Merge of JDK1.7 build 147 version of classes
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 07 Sep 2013 13:55:09 +0200
changeset 1259d257b7a37635
parent 1256 7b379a47e3a9
parent 1258 724f3e1ea53e
child 1260 fe3567c7b522
Merge of JDK1.7 build 147 version of classes
emul/compact/src/main/java/java/lang/System.java
rt/emul/compact/src/main/java/java/io/BufferedWriter.java
rt/emul/compact/src/main/java/java/io/File.java
rt/emul/compact/src/main/java/java/io/FileFilter.java
rt/emul/compact/src/main/java/java/io/FileNotFoundException.java
rt/emul/compact/src/main/java/java/io/FilenameFilter.java
rt/emul/compact/src/main/java/java/io/InterruptedIOException.java
rt/emul/compact/src/main/java/java/io/OutputStreamWriter.java
rt/emul/compact/src/main/java/java/io/PrintStream.java
rt/emul/compact/src/main/java/java/io/PrintWriter.java
rt/emul/compact/src/main/java/java/io/Writer.java
rt/emul/compact/src/main/java/java/lang/StackOverflowError.java
rt/emul/compact/src/main/java/java/lang/System.java
rt/emul/compact/src/main/java/java/lang/Thread.java
rt/emul/compact/src/main/java/java/math/BigDecimal.java
rt/emul/compact/src/main/java/java/math/BigInteger.java
rt/emul/compact/src/main/java/java/math/BitSieve.java
rt/emul/compact/src/main/java/java/math/MathContext.java
rt/emul/compact/src/main/java/java/math/MutableBigInteger.java
rt/emul/compact/src/main/java/java/math/RoundingMode.java
rt/emul/compact/src/main/java/java/math/SignedMutableBigInteger.java
rt/emul/compact/src/main/java/java/math/package-info.java
rt/emul/compact/src/main/java/java/net/URI.java
rt/emul/compact/src/main/java/java/net/URISyntaxException.java
rt/emul/compact/src/main/java/java/util/IdentityHashMap.java
rt/emul/compact/src/main/java/java/util/LinkedHashSet.java
rt/emul/compact/src/main/java/java/util/NavigableMap.java
rt/emul/compact/src/main/java/java/util/NavigableSet.java
rt/emul/compact/src/main/java/java/util/TreeMap.java
rt/emul/compact/src/main/java/java/util/TreeSet.java
rt/emul/compact/src/main/java/java/util/WeakHashMap.java
rt/emul/compact/src/main/java/java/util/concurrent/Executor.java
rt/emul/compact/src/main/java/java/util/logging/Level.java
rt/emul/compact/src/main/java/java/util/logging/LogRecord.java
rt/emul/compact/src/main/java/java/util/logging/Logger.java
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/rt/emul/compact/src/main/java/java/io/BufferedWriter.java	Sat Sep 07 13:55:09 2013 +0200
     1.3 @@ -0,0 +1,272 @@
     1.4 +/*
     1.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.  Oracle designates this
    1.11 + * particular file as subject to the "Classpath" exception as provided
    1.12 + * by Oracle in the LICENSE file that accompanied this code.
    1.13 + *
    1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.17 + * version 2 for more details (a copy is included in the LICENSE file that
    1.18 + * accompanied this code).
    1.19 + *
    1.20 + * You should have received a copy of the GNU General Public License version
    1.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.23 + *
    1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.25 + * or visit www.oracle.com if you need additional information or have any
    1.26 + * questions.
    1.27 + */
    1.28 +
    1.29 +package java.io;
    1.30 +
    1.31 +
    1.32 +/**
    1.33 + * Writes text to a character-output stream, buffering characters so as to
    1.34 + * provide for the efficient writing of single characters, arrays, and strings.
    1.35 + *
    1.36 + * <p> The buffer size may be specified, or the default size may be accepted.
    1.37 + * The default is large enough for most purposes.
    1.38 + *
    1.39 + * <p> A newLine() method is provided, which uses the platform's own notion of
    1.40 + * line separator as defined by the system property <tt>line.separator</tt>.
    1.41 + * Not all platforms use the newline character ('\n') to terminate lines.
    1.42 + * Calling this method to terminate each output line is therefore preferred to
    1.43 + * writing a newline character directly.
    1.44 + *
    1.45 + * <p> In general, a Writer sends its output immediately to the underlying
    1.46 + * character or byte stream.  Unless prompt output is required, it is advisable
    1.47 + * to wrap a BufferedWriter around any Writer whose write() operations may be
    1.48 + * costly, such as FileWriters and OutputStreamWriters.  For example,
    1.49 + *
    1.50 + * <pre>
    1.51 + * PrintWriter out
    1.52 + *   = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")));
    1.53 + * </pre>
    1.54 + *
    1.55 + * will buffer the PrintWriter's output to the file.  Without buffering, each
    1.56 + * invocation of a print() method would cause characters to be converted into
    1.57 + * bytes that would then be written immediately to the file, which can be very
    1.58 + * inefficient.
    1.59 + *
    1.60 + * @see PrintWriter
    1.61 + * @see FileWriter
    1.62 + * @see OutputStreamWriter
    1.63 + * @see java.nio.file.Files#newBufferedWriter
    1.64 + *
    1.65 + * @author      Mark Reinhold
    1.66 + * @since       JDK1.1
    1.67 + */
    1.68 +
    1.69 +public class BufferedWriter extends Writer {
    1.70 +
    1.71 +    private Writer out;
    1.72 +
    1.73 +    private char cb[];
    1.74 +    private int nChars, nextChar;
    1.75 +
    1.76 +    private static int defaultCharBufferSize = 8192;
    1.77 +
    1.78 +    /**
    1.79 +     * Line separator string.  This is the value of the line.separator
    1.80 +     * property at the moment that the stream was created.
    1.81 +     */
    1.82 +    private String lineSeparator;
    1.83 +
    1.84 +    /**
    1.85 +     * Creates a buffered character-output stream that uses a default-sized
    1.86 +     * output buffer.
    1.87 +     *
    1.88 +     * @param  out  A Writer
    1.89 +     */
    1.90 +    public BufferedWriter(Writer out) {
    1.91 +        this(out, defaultCharBufferSize);
    1.92 +    }
    1.93 +
    1.94 +    /**
    1.95 +     * Creates a new buffered character-output stream that uses an output
    1.96 +     * buffer of the given size.
    1.97 +     *
    1.98 +     * @param  out  A Writer
    1.99 +     * @param  sz   Output-buffer size, a positive integer
   1.100 +     *
   1.101 +     * @exception  IllegalArgumentException  If sz is <= 0
   1.102 +     */
   1.103 +    public BufferedWriter(Writer out, int sz) {
   1.104 +        super(out);
   1.105 +        if (sz <= 0)
   1.106 +            throw new IllegalArgumentException("Buffer size <= 0");
   1.107 +        this.out = out;
   1.108 +        cb = new char[sz];
   1.109 +        nChars = sz;
   1.110 +        nextChar = 0;
   1.111 +
   1.112 +        lineSeparator = java.security.AccessController.doPrivileged(
   1.113 +            new sun.security.action.GetPropertyAction("line.separator"));
   1.114 +    }
   1.115 +
   1.116 +    /** Checks to make sure that the stream has not been closed */
   1.117 +    private void ensureOpen() throws IOException {
   1.118 +        if (out == null)
   1.119 +            throw new IOException("Stream closed");
   1.120 +    }
   1.121 +
   1.122 +    /**
   1.123 +     * Flushes the output buffer to the underlying character stream, without
   1.124 +     * flushing the stream itself.  This method is non-private only so that it
   1.125 +     * may be invoked by PrintStream.
   1.126 +     */
   1.127 +    void flushBuffer() throws IOException {
   1.128 +        synchronized (lock) {
   1.129 +            ensureOpen();
   1.130 +            if (nextChar == 0)
   1.131 +                return;
   1.132 +            out.write(cb, 0, nextChar);
   1.133 +            nextChar = 0;
   1.134 +        }
   1.135 +    }
   1.136 +
   1.137 +    /**
   1.138 +     * Writes a single character.
   1.139 +     *
   1.140 +     * @exception  IOException  If an I/O error occurs
   1.141 +     */
   1.142 +    public void write(int c) throws IOException {
   1.143 +        synchronized (lock) {
   1.144 +            ensureOpen();
   1.145 +            if (nextChar >= nChars)
   1.146 +                flushBuffer();
   1.147 +            cb[nextChar++] = (char) c;
   1.148 +        }
   1.149 +    }
   1.150 +
   1.151 +    /**
   1.152 +     * Our own little min method, to avoid loading java.lang.Math if we've run
   1.153 +     * out of file descriptors and we're trying to print a stack trace.
   1.154 +     */
   1.155 +    private int min(int a, int b) {
   1.156 +        if (a < b) return a;
   1.157 +        return b;
   1.158 +    }
   1.159 +
   1.160 +    /**
   1.161 +     * Writes a portion of an array of characters.
   1.162 +     *
   1.163 +     * <p> Ordinarily this method stores characters from the given array into
   1.164 +     * this stream's buffer, flushing the buffer to the underlying stream as
   1.165 +     * needed.  If the requested length is at least as large as the buffer,
   1.166 +     * however, then this method will flush the buffer and write the characters
   1.167 +     * directly to the underlying stream.  Thus redundant
   1.168 +     * <code>BufferedWriter</code>s will not copy data unnecessarily.
   1.169 +     *
   1.170 +     * @param  cbuf  A character array
   1.171 +     * @param  off   Offset from which to start reading characters
   1.172 +     * @param  len   Number of characters to write
   1.173 +     *
   1.174 +     * @exception  IOException  If an I/O error occurs
   1.175 +     */
   1.176 +    public void write(char cbuf[], int off, int len) throws IOException {
   1.177 +        synchronized (lock) {
   1.178 +            ensureOpen();
   1.179 +            if ((off < 0) || (off > cbuf.length) || (len < 0) ||
   1.180 +                ((off + len) > cbuf.length) || ((off + len) < 0)) {
   1.181 +                throw new IndexOutOfBoundsException();
   1.182 +            } else if (len == 0) {
   1.183 +                return;
   1.184 +            }
   1.185 +
   1.186 +            if (len >= nChars) {
   1.187 +                /* If the request length exceeds the size of the output buffer,
   1.188 +                   flush the buffer and then write the data directly.  In this
   1.189 +                   way buffered streams will cascade harmlessly. */
   1.190 +                flushBuffer();
   1.191 +                out.write(cbuf, off, len);
   1.192 +                return;
   1.193 +            }
   1.194 +
   1.195 +            int b = off, t = off + len;
   1.196 +            while (b < t) {
   1.197 +                int d = min(nChars - nextChar, t - b);
   1.198 +                System.arraycopy(cbuf, b, cb, nextChar, d);
   1.199 +                b += d;
   1.200 +                nextChar += d;
   1.201 +                if (nextChar >= nChars)
   1.202 +                    flushBuffer();
   1.203 +            }
   1.204 +        }
   1.205 +    }
   1.206 +
   1.207 +    /**
   1.208 +     * Writes a portion of a String.
   1.209 +     *
   1.210 +     * <p> If the value of the <tt>len</tt> parameter is negative then no
   1.211 +     * characters are written.  This is contrary to the specification of this
   1.212 +     * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int)
   1.213 +     * superclass}, which requires that an {@link IndexOutOfBoundsException} be
   1.214 +     * thrown.
   1.215 +     *
   1.216 +     * @param  s     String to be written
   1.217 +     * @param  off   Offset from which to start reading characters
   1.218 +     * @param  len   Number of characters to be written
   1.219 +     *
   1.220 +     * @exception  IOException  If an I/O error occurs
   1.221 +     */
   1.222 +    public void write(String s, int off, int len) throws IOException {
   1.223 +        synchronized (lock) {
   1.224 +            ensureOpen();
   1.225 +
   1.226 +            int b = off, t = off + len;
   1.227 +            while (b < t) {
   1.228 +                int d = min(nChars - nextChar, t - b);
   1.229 +                s.getChars(b, b + d, cb, nextChar);
   1.230 +                b += d;
   1.231 +                nextChar += d;
   1.232 +                if (nextChar >= nChars)
   1.233 +                    flushBuffer();
   1.234 +            }
   1.235 +        }
   1.236 +    }
   1.237 +
   1.238 +    /**
   1.239 +     * Writes a line separator.  The line separator string is defined by the
   1.240 +     * system property <tt>line.separator</tt>, and is not necessarily a single
   1.241 +     * newline ('\n') character.
   1.242 +     *
   1.243 +     * @exception  IOException  If an I/O error occurs
   1.244 +     */
   1.245 +    public void newLine() throws IOException {
   1.246 +        write(lineSeparator);
   1.247 +    }
   1.248 +
   1.249 +    /**
   1.250 +     * Flushes the stream.
   1.251 +     *
   1.252 +     * @exception  IOException  If an I/O error occurs
   1.253 +     */
   1.254 +    public void flush() throws IOException {
   1.255 +        synchronized (lock) {
   1.256 +            flushBuffer();
   1.257 +            out.flush();
   1.258 +        }
   1.259 +    }
   1.260 +
   1.261 +    public void close() throws IOException {
   1.262 +        synchronized (lock) {
   1.263 +            if (out == null) {
   1.264 +                return;
   1.265 +            }
   1.266 +            try {
   1.267 +                flushBuffer();
   1.268 +            } finally {
   1.269 +                out.close();
   1.270 +                out = null;
   1.271 +                cb = null;
   1.272 +            }
   1.273 +        }
   1.274 +    }
   1.275 +}
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/rt/emul/compact/src/main/java/java/io/File.java	Sat Sep 07 13:55:09 2013 +0200
     2.3 @@ -0,0 +1,2076 @@
     2.4 +/*
     2.5 + * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
     2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2.7 + *
     2.8 + * This code is free software; you can redistribute it and/or modify it
     2.9 + * under the terms of the GNU General Public License version 2 only, as
    2.10 + * published by the Free Software Foundation.  Oracle designates this
    2.11 + * particular file as subject to the "Classpath" exception as provided
    2.12 + * by Oracle in the LICENSE file that accompanied this code.
    2.13 + *
    2.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
    2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    2.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 + * version 2 for more details (a copy is included in the LICENSE file that
    2.18 + * accompanied this code).
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License version
    2.21 + * 2 along with this work; if not, write to the Free Software Foundation,
    2.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    2.23 + *
    2.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    2.25 + * or visit www.oracle.com if you need additional information or have any
    2.26 + * questions.
    2.27 + */
    2.28 +
    2.29 +package java.io;
    2.30 +
    2.31 +import java.net.URI;
    2.32 +import java.net.URL;
    2.33 +import java.net.MalformedURLException;
    2.34 +import java.net.URISyntaxException;
    2.35 +import java.util.List;
    2.36 +import java.util.ArrayList;
    2.37 +import java.security.AccessController;
    2.38 +import java.security.SecureRandom;
    2.39 +import java.nio.file.Path;
    2.40 +import java.nio.file.FileSystems;
    2.41 +import sun.security.action.GetPropertyAction;
    2.42 +
    2.43 +/**
    2.44 + * An abstract representation of file and directory pathnames.
    2.45 + *
    2.46 + * <p> User interfaces and operating systems use system-dependent <em>pathname
    2.47 + * strings</em> to name files and directories.  This class presents an
    2.48 + * abstract, system-independent view of hierarchical pathnames.  An
    2.49 + * <em>abstract pathname</em> has two components:
    2.50 + *
    2.51 + * <ol>
    2.52 + * <li> An optional system-dependent <em>prefix</em> string,
    2.53 + *      such as a disk-drive specifier, <code>"/"</code>&nbsp;for the UNIX root
    2.54 + *      directory, or <code>"\\\\"</code>&nbsp;for a Microsoft Windows UNC pathname, and
    2.55 + * <li> A sequence of zero or more string <em>names</em>.
    2.56 + * </ol>
    2.57 + *
    2.58 + * The first name in an abstract pathname may be a directory name or, in the
    2.59 + * case of Microsoft Windows UNC pathnames, a hostname.  Each subsequent name
    2.60 + * in an abstract pathname denotes a directory; the last name may denote
    2.61 + * either a directory or a file.  The <em>empty</em> abstract pathname has no
    2.62 + * prefix and an empty name sequence.
    2.63 + *
    2.64 + * <p> The conversion of a pathname string to or from an abstract pathname is
    2.65 + * inherently system-dependent.  When an abstract pathname is converted into a
    2.66 + * pathname string, each name is separated from the next by a single copy of
    2.67 + * the default <em>separator character</em>.  The default name-separator
    2.68 + * character is defined by the system property <code>file.separator</code>, and
    2.69 + * is made available in the public static fields <code>{@link
    2.70 + * #separator}</code> and <code>{@link #separatorChar}</code> of this class.
    2.71 + * When a pathname string is converted into an abstract pathname, the names
    2.72 + * within it may be separated by the default name-separator character or by any
    2.73 + * other name-separator character that is supported by the underlying system.
    2.74 + *
    2.75 + * <p> A pathname, whether abstract or in string form, may be either
    2.76 + * <em>absolute</em> or <em>relative</em>.  An absolute pathname is complete in
    2.77 + * that no other information is required in order to locate the file that it
    2.78 + * denotes.  A relative pathname, in contrast, must be interpreted in terms of
    2.79 + * information taken from some other pathname.  By default the classes in the
    2.80 + * <code>java.io</code> package always resolve relative pathnames against the
    2.81 + * current user directory.  This directory is named by the system property
    2.82 + * <code>user.dir</code>, and is typically the directory in which the Java
    2.83 + * virtual machine was invoked.
    2.84 + *
    2.85 + * <p> The <em>parent</em> of an abstract pathname may be obtained by invoking
    2.86 + * the {@link #getParent} method of this class and consists of the pathname's
    2.87 + * prefix and each name in the pathname's name sequence except for the last.
    2.88 + * Each directory's absolute pathname is an ancestor of any <tt>File</tt>
    2.89 + * object with an absolute abstract pathname which begins with the directory's
    2.90 + * absolute pathname.  For example, the directory denoted by the abstract
    2.91 + * pathname <tt>"/usr"</tt> is an ancestor of the directory denoted by the
    2.92 + * pathname <tt>"/usr/local/bin"</tt>.
    2.93 + *
    2.94 + * <p> The prefix concept is used to handle root directories on UNIX platforms,
    2.95 + * and drive specifiers, root directories and UNC pathnames on Microsoft Windows platforms,
    2.96 + * as follows:
    2.97 + *
    2.98 + * <ul>
    2.99 + *
   2.100 + * <li> For UNIX platforms, the prefix of an absolute pathname is always
   2.101 + * <code>"/"</code>.  Relative pathnames have no prefix.  The abstract pathname
   2.102 + * denoting the root directory has the prefix <code>"/"</code> and an empty
   2.103 + * name sequence.
   2.104 + *
   2.105 + * <li> For Microsoft Windows platforms, the prefix of a pathname that contains a drive
   2.106 + * specifier consists of the drive letter followed by <code>":"</code> and
   2.107 + * possibly followed by <code>"\\"</code> if the pathname is absolute.  The
   2.108 + * prefix of a UNC pathname is <code>"\\\\"</code>; the hostname and the share
   2.109 + * name are the first two names in the name sequence.  A relative pathname that
   2.110 + * does not specify a drive has no prefix.
   2.111 + *
   2.112 + * </ul>
   2.113 + *
   2.114 + * <p> Instances of this class may or may not denote an actual file-system
   2.115 + * object such as a file or a directory.  If it does denote such an object
   2.116 + * then that object resides in a <i>partition</i>.  A partition is an
   2.117 + * operating system-specific portion of storage for a file system.  A single
   2.118 + * storage device (e.g. a physical disk-drive, flash memory, CD-ROM) may
   2.119 + * contain multiple partitions.  The object, if any, will reside on the
   2.120 + * partition <a name="partName">named</a> by some ancestor of the absolute
   2.121 + * form of this pathname.
   2.122 + *
   2.123 + * <p> A file system may implement restrictions to certain operations on the
   2.124 + * actual file-system object, such as reading, writing, and executing.  These
   2.125 + * restrictions are collectively known as <i>access permissions</i>.  The file
   2.126 + * system may have multiple sets of access permissions on a single object.
   2.127 + * For example, one set may apply to the object's <i>owner</i>, and another
   2.128 + * may apply to all other users.  The access permissions on an object may
   2.129 + * cause some methods in this class to fail.
   2.130 + *
   2.131 + * <p> Instances of the <code>File</code> class are immutable; that is, once
   2.132 + * created, the abstract pathname represented by a <code>File</code> object
   2.133 + * will never change.
   2.134 + *
   2.135 + * <h4>Interoperability with {@code java.nio.file} package</h4>
   2.136 + *
   2.137 + * <p> The <a href="../../java/nio/file/package-summary.html">{@code java.nio.file}</a>
   2.138 + * package defines interfaces and classes for the Java virtual machine to access
   2.139 + * files, file attributes, and file systems. This API may be used to overcome
   2.140 + * many of the limitations of the {@code java.io.File} class.
   2.141 + * The {@link #toPath toPath} method may be used to obtain a {@link
   2.142 + * Path} that uses the abstract path represented by a {@code File} object to
   2.143 + * locate a file. The resulting {@code Path} may be used with the {@link
   2.144 + * java.nio.file.Files} class to provide more efficient and extensive access to
   2.145 + * additional file operations, file attributes, and I/O exceptions to help
   2.146 + * diagnose errors when an operation on a file fails.
   2.147 + *
   2.148 + * @author  unascribed
   2.149 + * @since   JDK1.0
   2.150 + */
   2.151 +
   2.152 +public class File
   2.153 +    implements Serializable, Comparable<File>
   2.154 +{
   2.155 +
   2.156 +    /**
   2.157 +     * The FileSystem object representing the platform's local file system.
   2.158 +     */
   2.159 +    static private FileSystem fs = FileSystem.getFileSystem();
   2.160 +
   2.161 +    /**
   2.162 +     * This abstract pathname's normalized pathname string.  A normalized
   2.163 +     * pathname string uses the default name-separator character and does not
   2.164 +     * contain any duplicate or redundant separators.
   2.165 +     *
   2.166 +     * @serial
   2.167 +     */
   2.168 +    private String path;
   2.169 +
   2.170 +    /**
   2.171 +     * The length of this abstract pathname's prefix, or zero if it has no
   2.172 +     * prefix.
   2.173 +     */
   2.174 +    private transient int prefixLength;
   2.175 +
   2.176 +    /**
   2.177 +     * Returns the length of this abstract pathname's prefix.
   2.178 +     * For use by FileSystem classes.
   2.179 +     */
   2.180 +    int getPrefixLength() {
   2.181 +        return prefixLength;
   2.182 +    }
   2.183 +
   2.184 +    /**
   2.185 +     * The system-dependent default name-separator character.  This field is
   2.186 +     * initialized to contain the first character of the value of the system
   2.187 +     * property <code>file.separator</code>.  On UNIX systems the value of this
   2.188 +     * field is <code>'/'</code>; on Microsoft Windows systems it is <code>'\\'</code>.
   2.189 +     *
   2.190 +     * @see     java.lang.System#getProperty(java.lang.String)
   2.191 +     */
   2.192 +    public static final char separatorChar = fs.getSeparator();
   2.193 +
   2.194 +    /**
   2.195 +     * The system-dependent default name-separator character, represented as a
   2.196 +     * string for convenience.  This string contains a single character, namely
   2.197 +     * <code>{@link #separatorChar}</code>.
   2.198 +     */
   2.199 +    public static final String separator = "" + separatorChar;
   2.200 +
   2.201 +    /**
   2.202 +     * The system-dependent path-separator character.  This field is
   2.203 +     * initialized to contain the first character of the value of the system
   2.204 +     * property <code>path.separator</code>.  This character is used to
   2.205 +     * separate filenames in a sequence of files given as a <em>path list</em>.
   2.206 +     * On UNIX systems, this character is <code>':'</code>; on Microsoft Windows systems it
   2.207 +     * is <code>';'</code>.
   2.208 +     *
   2.209 +     * @see     java.lang.System#getProperty(java.lang.String)
   2.210 +     */
   2.211 +    public static final char pathSeparatorChar = fs.getPathSeparator();
   2.212 +
   2.213 +    /**
   2.214 +     * The system-dependent path-separator character, represented as a string
   2.215 +     * for convenience.  This string contains a single character, namely
   2.216 +     * <code>{@link #pathSeparatorChar}</code>.
   2.217 +     */
   2.218 +    public static final String pathSeparator = "" + pathSeparatorChar;
   2.219 +
   2.220 +
   2.221 +    /* -- Constructors -- */
   2.222 +
   2.223 +    /**
   2.224 +     * Internal constructor for already-normalized pathname strings.
   2.225 +     */
   2.226 +    private File(String pathname, int prefixLength) {
   2.227 +        this.path = pathname;
   2.228 +        this.prefixLength = prefixLength;
   2.229 +    }
   2.230 +
   2.231 +    /**
   2.232 +     * Internal constructor for already-normalized pathname strings.
   2.233 +     * The parameter order is used to disambiguate this method from the
   2.234 +     * public(File, String) constructor.
   2.235 +     */
   2.236 +    private File(String child, File parent) {
   2.237 +        assert parent.path != null;
   2.238 +        assert (!parent.path.equals(""));
   2.239 +        this.path = fs.resolve(parent.path, child);
   2.240 +        this.prefixLength = parent.prefixLength;
   2.241 +    }
   2.242 +
   2.243 +    /**
   2.244 +     * Creates a new <code>File</code> instance by converting the given
   2.245 +     * pathname string into an abstract pathname.  If the given string is
   2.246 +     * the empty string, then the result is the empty abstract pathname.
   2.247 +     *
   2.248 +     * @param   pathname  A pathname string
   2.249 +     * @throws  NullPointerException
   2.250 +     *          If the <code>pathname</code> argument is <code>null</code>
   2.251 +     */
   2.252 +    public File(String pathname) {
   2.253 +        if (pathname == null) {
   2.254 +            throw new NullPointerException();
   2.255 +        }
   2.256 +        this.path = fs.normalize(pathname);
   2.257 +        this.prefixLength = fs.prefixLength(this.path);
   2.258 +    }
   2.259 +
   2.260 +    /* Note: The two-argument File constructors do not interpret an empty
   2.261 +       parent abstract pathname as the current user directory.  An empty parent
   2.262 +       instead causes the child to be resolved against the system-dependent
   2.263 +       directory defined by the FileSystem.getDefaultParent method.  On Unix
   2.264 +       this default is "/", while on Microsoft Windows it is "\\".  This is required for
   2.265 +       compatibility with the original behavior of this class. */
   2.266 +
   2.267 +    /**
   2.268 +     * Creates a new <code>File</code> instance from a parent pathname string
   2.269 +     * and a child pathname string.
   2.270 +     *
   2.271 +     * <p> If <code>parent</code> is <code>null</code> then the new
   2.272 +     * <code>File</code> instance is created as if by invoking the
   2.273 +     * single-argument <code>File</code> constructor on the given
   2.274 +     * <code>child</code> pathname string.
   2.275 +     *
   2.276 +     * <p> Otherwise the <code>parent</code> pathname string is taken to denote
   2.277 +     * a directory, and the <code>child</code> pathname string is taken to
   2.278 +     * denote either a directory or a file.  If the <code>child</code> pathname
   2.279 +     * string is absolute then it is converted into a relative pathname in a
   2.280 +     * system-dependent way.  If <code>parent</code> is the empty string then
   2.281 +     * the new <code>File</code> instance is created by converting
   2.282 +     * <code>child</code> into an abstract pathname and resolving the result
   2.283 +     * against a system-dependent default directory.  Otherwise each pathname
   2.284 +     * string is converted into an abstract pathname and the child abstract
   2.285 +     * pathname is resolved against the parent.
   2.286 +     *
   2.287 +     * @param   parent  The parent pathname string
   2.288 +     * @param   child   The child pathname string
   2.289 +     * @throws  NullPointerException
   2.290 +     *          If <code>child</code> is <code>null</code>
   2.291 +     */
   2.292 +    public File(String parent, String child) {
   2.293 +        if (child == null) {
   2.294 +            throw new NullPointerException();
   2.295 +        }
   2.296 +        if (parent != null) {
   2.297 +            if (parent.equals("")) {
   2.298 +                this.path = fs.resolve(fs.getDefaultParent(),
   2.299 +                                       fs.normalize(child));
   2.300 +            } else {
   2.301 +                this.path = fs.resolve(fs.normalize(parent),
   2.302 +                                       fs.normalize(child));
   2.303 +            }
   2.304 +        } else {
   2.305 +            this.path = fs.normalize(child);
   2.306 +        }
   2.307 +        this.prefixLength = fs.prefixLength(this.path);
   2.308 +    }
   2.309 +
   2.310 +    /**
   2.311 +     * Creates a new <code>File</code> instance from a parent abstract
   2.312 +     * pathname and a child pathname string.
   2.313 +     *
   2.314 +     * <p> If <code>parent</code> is <code>null</code> then the new
   2.315 +     * <code>File</code> instance is created as if by invoking the
   2.316 +     * single-argument <code>File</code> constructor on the given
   2.317 +     * <code>child</code> pathname string.
   2.318 +     *
   2.319 +     * <p> Otherwise the <code>parent</code> abstract pathname is taken to
   2.320 +     * denote a directory, and the <code>child</code> pathname string is taken
   2.321 +     * to denote either a directory or a file.  If the <code>child</code>
   2.322 +     * pathname string is absolute then it is converted into a relative
   2.323 +     * pathname in a system-dependent way.  If <code>parent</code> is the empty
   2.324 +     * abstract pathname then the new <code>File</code> instance is created by
   2.325 +     * converting <code>child</code> into an abstract pathname and resolving
   2.326 +     * the result against a system-dependent default directory.  Otherwise each
   2.327 +     * pathname string is converted into an abstract pathname and the child
   2.328 +     * abstract pathname is resolved against the parent.
   2.329 +     *
   2.330 +     * @param   parent  The parent abstract pathname
   2.331 +     * @param   child   The child pathname string
   2.332 +     * @throws  NullPointerException
   2.333 +     *          If <code>child</code> is <code>null</code>
   2.334 +     */
   2.335 +    public File(File parent, String child) {
   2.336 +        if (child == null) {
   2.337 +            throw new NullPointerException();
   2.338 +        }
   2.339 +        if (parent != null) {
   2.340 +            if (parent.path.equals("")) {
   2.341 +                this.path = fs.resolve(fs.getDefaultParent(),
   2.342 +                                       fs.normalize(child));
   2.343 +            } else {
   2.344 +                this.path = fs.resolve(parent.path,
   2.345 +                                       fs.normalize(child));
   2.346 +            }
   2.347 +        } else {
   2.348 +            this.path = fs.normalize(child);
   2.349 +        }
   2.350 +        this.prefixLength = fs.prefixLength(this.path);
   2.351 +    }
   2.352 +
   2.353 +    /**
   2.354 +     * Creates a new <tt>File</tt> instance by converting the given
   2.355 +     * <tt>file:</tt> URI into an abstract pathname.
   2.356 +     *
   2.357 +     * <p> The exact form of a <tt>file:</tt> URI is system-dependent, hence
   2.358 +     * the transformation performed by this constructor is also
   2.359 +     * system-dependent.
   2.360 +     *
   2.361 +     * <p> For a given abstract pathname <i>f</i> it is guaranteed that
   2.362 +     *
   2.363 +     * <blockquote><tt>
   2.364 +     * new File(</tt><i>&nbsp;f</i><tt>.{@link #toURI() toURI}()).equals(</tt><i>&nbsp;f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
   2.365 +     * </tt></blockquote>
   2.366 +     *
   2.367 +     * so long as the original abstract pathname, the URI, and the new abstract
   2.368 +     * pathname are all created in (possibly different invocations of) the same
   2.369 +     * Java virtual machine.  This relationship typically does not hold,
   2.370 +     * however, when a <tt>file:</tt> URI that is created in a virtual machine
   2.371 +     * on one operating system is converted into an abstract pathname in a
   2.372 +     * virtual machine on a different operating system.
   2.373 +     *
   2.374 +     * @param  uri
   2.375 +     *         An absolute, hierarchical URI with a scheme equal to
   2.376 +     *         <tt>"file"</tt>, a non-empty path component, and undefined
   2.377 +     *         authority, query, and fragment components
   2.378 +     *
   2.379 +     * @throws  NullPointerException
   2.380 +     *          If <tt>uri</tt> is <tt>null</tt>
   2.381 +     *
   2.382 +     * @throws  IllegalArgumentException
   2.383 +     *          If the preconditions on the parameter do not hold
   2.384 +     *
   2.385 +     * @see #toURI()
   2.386 +     * @see java.net.URI
   2.387 +     * @since 1.4
   2.388 +     */
   2.389 +    public File(URI uri) {
   2.390 +
   2.391 +        // Check our many preconditions
   2.392 +        if (!uri.isAbsolute())
   2.393 +            throw new IllegalArgumentException("URI is not absolute");
   2.394 +        if (uri.isOpaque())
   2.395 +            throw new IllegalArgumentException("URI is not hierarchical");
   2.396 +        String scheme = uri.getScheme();
   2.397 +        if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
   2.398 +            throw new IllegalArgumentException("URI scheme is not \"file\"");
   2.399 +        if (uri.getAuthority() != null)
   2.400 +            throw new IllegalArgumentException("URI has an authority component");
   2.401 +        if (uri.getFragment() != null)
   2.402 +            throw new IllegalArgumentException("URI has a fragment component");
   2.403 +        if (uri.getQuery() != null)
   2.404 +            throw new IllegalArgumentException("URI has a query component");
   2.405 +        String p = uri.getPath();
   2.406 +        if (p.equals(""))
   2.407 +            throw new IllegalArgumentException("URI path component is empty");
   2.408 +
   2.409 +        // Okay, now initialize
   2.410 +        p = fs.fromURIPath(p);
   2.411 +        if (File.separatorChar != '/')
   2.412 +            p = p.replace('/', File.separatorChar);
   2.413 +        this.path = fs.normalize(p);
   2.414 +        this.prefixLength = fs.prefixLength(this.path);
   2.415 +    }
   2.416 +
   2.417 +
   2.418 +    /* -- Path-component accessors -- */
   2.419 +
   2.420 +    /**
   2.421 +     * Returns the name of the file or directory denoted by this abstract
   2.422 +     * pathname.  This is just the last name in the pathname's name
   2.423 +     * sequence.  If the pathname's name sequence is empty, then the empty
   2.424 +     * string is returned.
   2.425 +     *
   2.426 +     * @return  The name of the file or directory denoted by this abstract
   2.427 +     *          pathname, or the empty string if this pathname's name sequence
   2.428 +     *          is empty
   2.429 +     */
   2.430 +    public String getName() {
   2.431 +        int index = path.lastIndexOf(separatorChar);
   2.432 +        if (index < prefixLength) return path.substring(prefixLength);
   2.433 +        return path.substring(index + 1);
   2.434 +    }
   2.435 +
   2.436 +    /**
   2.437 +     * Returns the pathname string of this abstract pathname's parent, or
   2.438 +     * <code>null</code> if this pathname does not name a parent directory.
   2.439 +     *
   2.440 +     * <p> The <em>parent</em> of an abstract pathname consists of the
   2.441 +     * pathname's prefix, if any, and each name in the pathname's name
   2.442 +     * sequence except for the last.  If the name sequence is empty then
   2.443 +     * the pathname does not name a parent directory.
   2.444 +     *
   2.445 +     * @return  The pathname string of the parent directory named by this
   2.446 +     *          abstract pathname, or <code>null</code> if this pathname
   2.447 +     *          does not name a parent
   2.448 +     */
   2.449 +    public String getParent() {
   2.450 +        int index = path.lastIndexOf(separatorChar);
   2.451 +        if (index < prefixLength) {
   2.452 +            if ((prefixLength > 0) && (path.length() > prefixLength))
   2.453 +                return path.substring(0, prefixLength);
   2.454 +            return null;
   2.455 +        }
   2.456 +        return path.substring(0, index);
   2.457 +    }
   2.458 +
   2.459 +    /**
   2.460 +     * Returns the abstract pathname of this abstract pathname's parent,
   2.461 +     * or <code>null</code> if this pathname does not name a parent
   2.462 +     * directory.
   2.463 +     *
   2.464 +     * <p> The <em>parent</em> of an abstract pathname consists of the
   2.465 +     * pathname's prefix, if any, and each name in the pathname's name
   2.466 +     * sequence except for the last.  If the name sequence is empty then
   2.467 +     * the pathname does not name a parent directory.
   2.468 +     *
   2.469 +     * @return  The abstract pathname of the parent directory named by this
   2.470 +     *          abstract pathname, or <code>null</code> if this pathname
   2.471 +     *          does not name a parent
   2.472 +     *
   2.473 +     * @since 1.2
   2.474 +     */
   2.475 +    public File getParentFile() {
   2.476 +        String p = this.getParent();
   2.477 +        if (p == null) return null;
   2.478 +        return new File(p, this.prefixLength);
   2.479 +    }
   2.480 +
   2.481 +    /**
   2.482 +     * Converts this abstract pathname into a pathname string.  The resulting
   2.483 +     * string uses the {@link #separator default name-separator character} to
   2.484 +     * separate the names in the name sequence.
   2.485 +     *
   2.486 +     * @return  The string form of this abstract pathname
   2.487 +     */
   2.488 +    public String getPath() {
   2.489 +        return path;
   2.490 +    }
   2.491 +
   2.492 +
   2.493 +    /* -- Path operations -- */
   2.494 +
   2.495 +    /**
   2.496 +     * Tests whether this abstract pathname is absolute.  The definition of
   2.497 +     * absolute pathname is system dependent.  On UNIX systems, a pathname is
   2.498 +     * absolute if its prefix is <code>"/"</code>.  On Microsoft Windows systems, a
   2.499 +     * pathname is absolute if its prefix is a drive specifier followed by
   2.500 +     * <code>"\\"</code>, or if its prefix is <code>"\\\\"</code>.
   2.501 +     *
   2.502 +     * @return  <code>true</code> if this abstract pathname is absolute,
   2.503 +     *          <code>false</code> otherwise
   2.504 +     */
   2.505 +    public boolean isAbsolute() {
   2.506 +        return fs.isAbsolute(this);
   2.507 +    }
   2.508 +
   2.509 +    /**
   2.510 +     * Returns the absolute pathname string of this abstract pathname.
   2.511 +     *
   2.512 +     * <p> If this abstract pathname is already absolute, then the pathname
   2.513 +     * string is simply returned as if by the <code>{@link #getPath}</code>
   2.514 +     * method.  If this abstract pathname is the empty abstract pathname then
   2.515 +     * the pathname string of the current user directory, which is named by the
   2.516 +     * system property <code>user.dir</code>, is returned.  Otherwise this
   2.517 +     * pathname is resolved in a system-dependent way.  On UNIX systems, a
   2.518 +     * relative pathname is made absolute by resolving it against the current
   2.519 +     * user directory.  On Microsoft Windows systems, a relative pathname is made absolute
   2.520 +     * by resolving it against the current directory of the drive named by the
   2.521 +     * pathname, if any; if not, it is resolved against the current user
   2.522 +     * directory.
   2.523 +     *
   2.524 +     * @return  The absolute pathname string denoting the same file or
   2.525 +     *          directory as this abstract pathname
   2.526 +     *
   2.527 +     * @throws  SecurityException
   2.528 +     *          If a required system property value cannot be accessed.
   2.529 +     *
   2.530 +     * @see     java.io.File#isAbsolute()
   2.531 +     */
   2.532 +    public String getAbsolutePath() {
   2.533 +        return fs.resolve(this);
   2.534 +    }
   2.535 +
   2.536 +    /**
   2.537 +     * Returns the absolute form of this abstract pathname.  Equivalent to
   2.538 +     * <code>new&nbsp;File(this.{@link #getAbsolutePath})</code>.
   2.539 +     *
   2.540 +     * @return  The absolute abstract pathname denoting the same file or
   2.541 +     *          directory as this abstract pathname
   2.542 +     *
   2.543 +     * @throws  SecurityException
   2.544 +     *          If a required system property value cannot be accessed.
   2.545 +     *
   2.546 +     * @since 1.2
   2.547 +     */
   2.548 +    public File getAbsoluteFile() {
   2.549 +        String absPath = getAbsolutePath();
   2.550 +        return new File(absPath, fs.prefixLength(absPath));
   2.551 +    }
   2.552 +
   2.553 +    /**
   2.554 +     * Returns the canonical pathname string of this abstract pathname.
   2.555 +     *
   2.556 +     * <p> A canonical pathname is both absolute and unique.  The precise
   2.557 +     * definition of canonical form is system-dependent.  This method first
   2.558 +     * converts this pathname to absolute form if necessary, as if by invoking the
   2.559 +     * {@link #getAbsolutePath} method, and then maps it to its unique form in a
   2.560 +     * system-dependent way.  This typically involves removing redundant names
   2.561 +     * such as <tt>"."</tt> and <tt>".."</tt> from the pathname, resolving
   2.562 +     * symbolic links (on UNIX platforms), and converting drive letters to a
   2.563 +     * standard case (on Microsoft Windows platforms).
   2.564 +     *
   2.565 +     * <p> Every pathname that denotes an existing file or directory has a
   2.566 +     * unique canonical form.  Every pathname that denotes a nonexistent file
   2.567 +     * or directory also has a unique canonical form.  The canonical form of
   2.568 +     * the pathname of a nonexistent file or directory may be different from
   2.569 +     * the canonical form of the same pathname after the file or directory is
   2.570 +     * created.  Similarly, the canonical form of the pathname of an existing
   2.571 +     * file or directory may be different from the canonical form of the same
   2.572 +     * pathname after the file or directory is deleted.
   2.573 +     *
   2.574 +     * @return  The canonical pathname string denoting the same file or
   2.575 +     *          directory as this abstract pathname
   2.576 +     *
   2.577 +     * @throws  IOException
   2.578 +     *          If an I/O error occurs, which is possible because the
   2.579 +     *          construction of the canonical pathname may require
   2.580 +     *          filesystem queries
   2.581 +     *
   2.582 +     * @throws  SecurityException
   2.583 +     *          If a required system property value cannot be accessed, or
   2.584 +     *          if a security manager exists and its <code>{@link
   2.585 +     *          java.lang.SecurityManager#checkRead}</code> method denies
   2.586 +     *          read access to the file
   2.587 +     *
   2.588 +     * @since   JDK1.1
   2.589 +     * @see     Path#toRealPath
   2.590 +     */
   2.591 +    public String getCanonicalPath() throws IOException {
   2.592 +        return fs.canonicalize(fs.resolve(this));
   2.593 +    }
   2.594 +
   2.595 +    /**
   2.596 +     * Returns the canonical form of this abstract pathname.  Equivalent to
   2.597 +     * <code>new&nbsp;File(this.{@link #getCanonicalPath})</code>.
   2.598 +     *
   2.599 +     * @return  The canonical pathname string denoting the same file or
   2.600 +     *          directory as this abstract pathname
   2.601 +     *
   2.602 +     * @throws  IOException
   2.603 +     *          If an I/O error occurs, which is possible because the
   2.604 +     *          construction of the canonical pathname may require
   2.605 +     *          filesystem queries
   2.606 +     *
   2.607 +     * @throws  SecurityException
   2.608 +     *          If a required system property value cannot be accessed, or
   2.609 +     *          if a security manager exists and its <code>{@link
   2.610 +     *          java.lang.SecurityManager#checkRead}</code> method denies
   2.611 +     *          read access to the file
   2.612 +     *
   2.613 +     * @since 1.2
   2.614 +     * @see     Path#toRealPath
   2.615 +     */
   2.616 +    public File getCanonicalFile() throws IOException {
   2.617 +        String canonPath = getCanonicalPath();
   2.618 +        return new File(canonPath, fs.prefixLength(canonPath));
   2.619 +    }
   2.620 +
   2.621 +    private static String slashify(String path, boolean isDirectory) {
   2.622 +        String p = path;
   2.623 +        if (File.separatorChar != '/')
   2.624 +            p = p.replace(File.separatorChar, '/');
   2.625 +        if (!p.startsWith("/"))
   2.626 +            p = "/" + p;
   2.627 +        if (!p.endsWith("/") && isDirectory)
   2.628 +            p = p + "/";
   2.629 +        return p;
   2.630 +    }
   2.631 +
   2.632 +    /**
   2.633 +     * Converts this abstract pathname into a <code>file:</code> URL.  The
   2.634 +     * exact form of the URL is system-dependent.  If it can be determined that
   2.635 +     * the file denoted by this abstract pathname is a directory, then the
   2.636 +     * resulting URL will end with a slash.
   2.637 +     *
   2.638 +     * @return  A URL object representing the equivalent file URL
   2.639 +     *
   2.640 +     * @throws  MalformedURLException
   2.641 +     *          If the path cannot be parsed as a URL
   2.642 +     *
   2.643 +     * @see     #toURI()
   2.644 +     * @see     java.net.URI
   2.645 +     * @see     java.net.URI#toURL()
   2.646 +     * @see     java.net.URL
   2.647 +     * @since   1.2
   2.648 +     *
   2.649 +     * @deprecated This method does not automatically escape characters that
   2.650 +     * are illegal in URLs.  It is recommended that new code convert an
   2.651 +     * abstract pathname into a URL by first converting it into a URI, via the
   2.652 +     * {@link #toURI() toURI} method, and then converting the URI into a URL
   2.653 +     * via the {@link java.net.URI#toURL() URI.toURL} method.
   2.654 +     */
   2.655 +    @Deprecated
   2.656 +    public URL toURL() throws MalformedURLException {
   2.657 +        return new URL("file", "", slashify(getAbsolutePath(), isDirectory()));
   2.658 +    }
   2.659 +
   2.660 +    /**
   2.661 +     * Constructs a <tt>file:</tt> URI that represents this abstract pathname.
   2.662 +     *
   2.663 +     * <p> The exact form of the URI is system-dependent.  If it can be
   2.664 +     * determined that the file denoted by this abstract pathname is a
   2.665 +     * directory, then the resulting URI will end with a slash.
   2.666 +     *
   2.667 +     * <p> For a given abstract pathname <i>f</i>, it is guaranteed that
   2.668 +     *
   2.669 +     * <blockquote><tt>
   2.670 +     * new {@link #File(java.net.URI) File}(</tt><i>&nbsp;f</i><tt>.toURI()).equals(</tt><i>&nbsp;f</i><tt>.{@link #getAbsoluteFile() getAbsoluteFile}())
   2.671 +     * </tt></blockquote>
   2.672 +     *
   2.673 +     * so long as the original abstract pathname, the URI, and the new abstract
   2.674 +     * pathname are all created in (possibly different invocations of) the same
   2.675 +     * Java virtual machine.  Due to the system-dependent nature of abstract
   2.676 +     * pathnames, however, this relationship typically does not hold when a
   2.677 +     * <tt>file:</tt> URI that is created in a virtual machine on one operating
   2.678 +     * system is converted into an abstract pathname in a virtual machine on a
   2.679 +     * different operating system.
   2.680 +     *
   2.681 +     * <p> Note that when this abstract pathname represents a UNC pathname then
   2.682 +     * all components of the UNC (including the server name component) are encoded
   2.683 +     * in the {@code URI} path. The authority component is undefined, meaning
   2.684 +     * that it is represented as {@code null}. The {@link Path} class defines the
   2.685 +     * {@link Path#toUri toUri} method to encode the server name in the authority
   2.686 +     * component of the resulting {@code URI}. The {@link #toPath toPath} method
   2.687 +     * may be used to obtain a {@code Path} representing this abstract pathname.
   2.688 +     *
   2.689 +     * @return  An absolute, hierarchical URI with a scheme equal to
   2.690 +     *          <tt>"file"</tt>, a path representing this abstract pathname,
   2.691 +     *          and undefined authority, query, and fragment components
   2.692 +     * @throws SecurityException If a required system property value cannot
   2.693 +     * be accessed.
   2.694 +     *
   2.695 +     * @see #File(java.net.URI)
   2.696 +     * @see java.net.URI
   2.697 +     * @see java.net.URI#toURL()
   2.698 +     * @since 1.4
   2.699 +     */
   2.700 +    public URI toURI() {
   2.701 +        try {
   2.702 +            File f = getAbsoluteFile();
   2.703 +            String sp = slashify(f.getPath(), f.isDirectory());
   2.704 +            if (sp.startsWith("//"))
   2.705 +                sp = "//" + sp;
   2.706 +            return new URI("file", null, sp, null);
   2.707 +        } catch (URISyntaxException x) {
   2.708 +            throw new Error(x);         // Can't happen
   2.709 +        }
   2.710 +    }
   2.711 +
   2.712 +
   2.713 +    /* -- Attribute accessors -- */
   2.714 +
   2.715 +    /**
   2.716 +     * Tests whether the application can read the file denoted by this
   2.717 +     * abstract pathname.
   2.718 +     *
   2.719 +     * @return  <code>true</code> if and only if the file specified by this
   2.720 +     *          abstract pathname exists <em>and</em> can be read by the
   2.721 +     *          application; <code>false</code> otherwise
   2.722 +     *
   2.723 +     * @throws  SecurityException
   2.724 +     *          If a security manager exists and its <code>{@link
   2.725 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.726 +     *          method denies read access to the file
   2.727 +     */
   2.728 +    public boolean canRead() {
   2.729 +        SecurityManager security = System.getSecurityManager();
   2.730 +        if (security != null) {
   2.731 +            security.checkRead(path);
   2.732 +        }
   2.733 +        return fs.checkAccess(this, FileSystem.ACCESS_READ);
   2.734 +    }
   2.735 +
   2.736 +    /**
   2.737 +     * Tests whether the application can modify the file denoted by this
   2.738 +     * abstract pathname.
   2.739 +     *
   2.740 +     * @return  <code>true</code> if and only if the file system actually
   2.741 +     *          contains a file denoted by this abstract pathname <em>and</em>
   2.742 +     *          the application is allowed to write to the file;
   2.743 +     *          <code>false</code> otherwise.
   2.744 +     *
   2.745 +     * @throws  SecurityException
   2.746 +     *          If a security manager exists and its <code>{@link
   2.747 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
   2.748 +     *          method denies write access to the file
   2.749 +     */
   2.750 +    public boolean canWrite() {
   2.751 +        SecurityManager security = System.getSecurityManager();
   2.752 +        if (security != null) {
   2.753 +            security.checkWrite(path);
   2.754 +        }
   2.755 +        return fs.checkAccess(this, FileSystem.ACCESS_WRITE);
   2.756 +    }
   2.757 +
   2.758 +    /**
   2.759 +     * Tests whether the file or directory denoted by this abstract pathname
   2.760 +     * exists.
   2.761 +     *
   2.762 +     * @return  <code>true</code> if and only if the file or directory denoted
   2.763 +     *          by this abstract pathname exists; <code>false</code> otherwise
   2.764 +     *
   2.765 +     * @throws  SecurityException
   2.766 +     *          If a security manager exists and its <code>{@link
   2.767 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.768 +     *          method denies read access to the file or directory
   2.769 +     */
   2.770 +    public boolean exists() {
   2.771 +        SecurityManager security = System.getSecurityManager();
   2.772 +        if (security != null) {
   2.773 +            security.checkRead(path);
   2.774 +        }
   2.775 +        return ((fs.getBooleanAttributes(this) & FileSystem.BA_EXISTS) != 0);
   2.776 +    }
   2.777 +
   2.778 +    /**
   2.779 +     * Tests whether the file denoted by this abstract pathname is a
   2.780 +     * directory.
   2.781 +     *
   2.782 +     * <p> Where it is required to distinguish an I/O exception from the case
   2.783 +     * that the file is not a directory, or where several attributes of the
   2.784 +     * same file are required at the same time, then the {@link
   2.785 +     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
   2.786 +     * Files.readAttributes} method may be used.
   2.787 +     *
   2.788 +     * @return <code>true</code> if and only if the file denoted by this
   2.789 +     *          abstract pathname exists <em>and</em> is a directory;
   2.790 +     *          <code>false</code> otherwise
   2.791 +     *
   2.792 +     * @throws  SecurityException
   2.793 +     *          If a security manager exists and its <code>{@link
   2.794 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.795 +     *          method denies read access to the file
   2.796 +     */
   2.797 +    public boolean isDirectory() {
   2.798 +        SecurityManager security = System.getSecurityManager();
   2.799 +        if (security != null) {
   2.800 +            security.checkRead(path);
   2.801 +        }
   2.802 +        return ((fs.getBooleanAttributes(this) & FileSystem.BA_DIRECTORY)
   2.803 +                != 0);
   2.804 +    }
   2.805 +
   2.806 +    /**
   2.807 +     * Tests whether the file denoted by this abstract pathname is a normal
   2.808 +     * file.  A file is <em>normal</em> if it is not a directory and, in
   2.809 +     * addition, satisfies other system-dependent criteria.  Any non-directory
   2.810 +     * file created by a Java application is guaranteed to be a normal file.
   2.811 +     *
   2.812 +     * <p> Where it is required to distinguish an I/O exception from the case
   2.813 +     * that the file is not a normal file, or where several attributes of the
   2.814 +     * same file are required at the same time, then the {@link
   2.815 +     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
   2.816 +     * Files.readAttributes} method may be used.
   2.817 +     *
   2.818 +     * @return  <code>true</code> if and only if the file denoted by this
   2.819 +     *          abstract pathname exists <em>and</em> is a normal file;
   2.820 +     *          <code>false</code> otherwise
   2.821 +     *
   2.822 +     * @throws  SecurityException
   2.823 +     *          If a security manager exists and its <code>{@link
   2.824 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.825 +     *          method denies read access to the file
   2.826 +     */
   2.827 +    public boolean isFile() {
   2.828 +        SecurityManager security = System.getSecurityManager();
   2.829 +        if (security != null) {
   2.830 +            security.checkRead(path);
   2.831 +        }
   2.832 +        return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
   2.833 +    }
   2.834 +
   2.835 +    /**
   2.836 +     * Tests whether the file named by this abstract pathname is a hidden
   2.837 +     * file.  The exact definition of <em>hidden</em> is system-dependent.  On
   2.838 +     * UNIX systems, a file is considered to be hidden if its name begins with
   2.839 +     * a period character (<code>'.'</code>).  On Microsoft Windows systems, a file is
   2.840 +     * considered to be hidden if it has been marked as such in the filesystem.
   2.841 +     *
   2.842 +     * @return  <code>true</code> if and only if the file denoted by this
   2.843 +     *          abstract pathname is hidden according to the conventions of the
   2.844 +     *          underlying platform
   2.845 +     *
   2.846 +     * @throws  SecurityException
   2.847 +     *          If a security manager exists and its <code>{@link
   2.848 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.849 +     *          method denies read access to the file
   2.850 +     *
   2.851 +     * @since 1.2
   2.852 +     */
   2.853 +    public boolean isHidden() {
   2.854 +        SecurityManager security = System.getSecurityManager();
   2.855 +        if (security != null) {
   2.856 +            security.checkRead(path);
   2.857 +        }
   2.858 +        return ((fs.getBooleanAttributes(this) & FileSystem.BA_HIDDEN) != 0);
   2.859 +    }
   2.860 +
   2.861 +    /**
   2.862 +     * Returns the time that the file denoted by this abstract pathname was
   2.863 +     * last modified.
   2.864 +     *
   2.865 +     * <p> Where it is required to distinguish an I/O exception from the case
   2.866 +     * where {@code 0L} is returned, or where several attributes of the
   2.867 +     * same file are required at the same time, or where the time of last
   2.868 +     * access or the creation time are required, then the {@link
   2.869 +     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
   2.870 +     * Files.readAttributes} method may be used.
   2.871 +     *
   2.872 +     * @return  A <code>long</code> value representing the time the file was
   2.873 +     *          last modified, measured in milliseconds since the epoch
   2.874 +     *          (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
   2.875 +     *          file does not exist or if an I/O error occurs
   2.876 +     *
   2.877 +     * @throws  SecurityException
   2.878 +     *          If a security manager exists and its <code>{@link
   2.879 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.880 +     *          method denies read access to the file
   2.881 +     */
   2.882 +    public long lastModified() {
   2.883 +        SecurityManager security = System.getSecurityManager();
   2.884 +        if (security != null) {
   2.885 +            security.checkRead(path);
   2.886 +        }
   2.887 +        return fs.getLastModifiedTime(this);
   2.888 +    }
   2.889 +
   2.890 +    /**
   2.891 +     * Returns the length of the file denoted by this abstract pathname.
   2.892 +     * The return value is unspecified if this pathname denotes a directory.
   2.893 +     *
   2.894 +     * <p> Where it is required to distinguish an I/O exception from the case
   2.895 +     * that {@code 0L} is returned, or where several attributes of the same file
   2.896 +     * are required at the same time, then the {@link
   2.897 +     * java.nio.file.Files#readAttributes(Path,Class,LinkOption[])
   2.898 +     * Files.readAttributes} method may be used.
   2.899 +     *
   2.900 +     * @return  The length, in bytes, of the file denoted by this abstract
   2.901 +     *          pathname, or <code>0L</code> if the file does not exist.  Some
   2.902 +     *          operating systems may return <code>0L</code> for pathnames
   2.903 +     *          denoting system-dependent entities such as devices or pipes.
   2.904 +     *
   2.905 +     * @throws  SecurityException
   2.906 +     *          If a security manager exists and its <code>{@link
   2.907 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
   2.908 +     *          method denies read access to the file
   2.909 +     */
   2.910 +    public long length() {
   2.911 +        SecurityManager security = System.getSecurityManager();
   2.912 +        if (security != null) {
   2.913 +            security.checkRead(path);
   2.914 +        }
   2.915 +        return fs.getLength(this);
   2.916 +    }
   2.917 +
   2.918 +
   2.919 +    /* -- File operations -- */
   2.920 +
   2.921 +    /**
   2.922 +     * Atomically creates a new, empty file named by this abstract pathname if
   2.923 +     * and only if a file with this name does not yet exist.  The check for the
   2.924 +     * existence of the file and the creation of the file if it does not exist
   2.925 +     * are a single operation that is atomic with respect to all other
   2.926 +     * filesystem activities that might affect the file.
   2.927 +     * <P>
   2.928 +     * Note: this method should <i>not</i> be used for file-locking, as
   2.929 +     * the resulting protocol cannot be made to work reliably. The
   2.930 +     * {@link java.nio.channels.FileLock FileLock}
   2.931 +     * facility should be used instead.
   2.932 +     *
   2.933 +     * @return  <code>true</code> if the named file does not exist and was
   2.934 +     *          successfully created; <code>false</code> if the named file
   2.935 +     *          already exists
   2.936 +     *
   2.937 +     * @throws  IOException
   2.938 +     *          If an I/O error occurred
   2.939 +     *
   2.940 +     * @throws  SecurityException
   2.941 +     *          If a security manager exists and its <code>{@link
   2.942 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
   2.943 +     *          method denies write access to the file
   2.944 +     *
   2.945 +     * @since 1.2
   2.946 +     */
   2.947 +    public boolean createNewFile() throws IOException {
   2.948 +        SecurityManager security = System.getSecurityManager();
   2.949 +        if (security != null) security.checkWrite(path);
   2.950 +        return fs.createFileExclusively(path);
   2.951 +    }
   2.952 +
   2.953 +    /**
   2.954 +     * Deletes the file or directory denoted by this abstract pathname.  If
   2.955 +     * this pathname denotes a directory, then the directory must be empty in
   2.956 +     * order to be deleted.
   2.957 +     *
   2.958 +     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
   2.959 +     * java.nio.file.Files#delete(Path) delete} method to throw an {@link IOException}
   2.960 +     * when a file cannot be deleted. This is useful for error reporting and to
   2.961 +     * diagnose why a file cannot be deleted.
   2.962 +     *
   2.963 +     * @return  <code>true</code> if and only if the file or directory is
   2.964 +     *          successfully deleted; <code>false</code> otherwise
   2.965 +     *
   2.966 +     * @throws  SecurityException
   2.967 +     *          If a security manager exists and its <code>{@link
   2.968 +     *          java.lang.SecurityManager#checkDelete}</code> method denies
   2.969 +     *          delete access to the file
   2.970 +     */
   2.971 +    public boolean delete() {
   2.972 +        SecurityManager security = System.getSecurityManager();
   2.973 +        if (security != null) {
   2.974 +            security.checkDelete(path);
   2.975 +        }
   2.976 +        return fs.delete(this);
   2.977 +    }
   2.978 +
   2.979 +    /**
   2.980 +     * Requests that the file or directory denoted by this abstract
   2.981 +     * pathname be deleted when the virtual machine terminates.
   2.982 +     * Files (or directories) are deleted in the reverse order that
   2.983 +     * they are registered. Invoking this method to delete a file or
   2.984 +     * directory that is already registered for deletion has no effect.
   2.985 +     * Deletion will be attempted only for normal termination of the
   2.986 +     * virtual machine, as defined by the Java Language Specification.
   2.987 +     *
   2.988 +     * <p> Once deletion has been requested, it is not possible to cancel the
   2.989 +     * request.  This method should therefore be used with care.
   2.990 +     *
   2.991 +     * <P>
   2.992 +     * Note: this method should <i>not</i> be used for file-locking, as
   2.993 +     * the resulting protocol cannot be made to work reliably. The
   2.994 +     * {@link java.nio.channels.FileLock FileLock}
   2.995 +     * facility should be used instead.
   2.996 +     *
   2.997 +     * @throws  SecurityException
   2.998 +     *          If a security manager exists and its <code>{@link
   2.999 +     *          java.lang.SecurityManager#checkDelete}</code> method denies
  2.1000 +     *          delete access to the file
  2.1001 +     *
  2.1002 +     * @see #delete
  2.1003 +     *
  2.1004 +     * @since 1.2
  2.1005 +     */
  2.1006 +    public void deleteOnExit() {
  2.1007 +        SecurityManager security = System.getSecurityManager();
  2.1008 +        if (security != null) {
  2.1009 +            security.checkDelete(path);
  2.1010 +        }
  2.1011 +        DeleteOnExitHook.add(path);
  2.1012 +    }
  2.1013 +
  2.1014 +    /**
  2.1015 +     * Returns an array of strings naming the files and directories in the
  2.1016 +     * directory denoted by this abstract pathname.
  2.1017 +     *
  2.1018 +     * <p> If this abstract pathname does not denote a directory, then this
  2.1019 +     * method returns {@code null}.  Otherwise an array of strings is
  2.1020 +     * returned, one for each file or directory in the directory.  Names
  2.1021 +     * denoting the directory itself and the directory's parent directory are
  2.1022 +     * not included in the result.  Each string is a file name rather than a
  2.1023 +     * complete path.
  2.1024 +     *
  2.1025 +     * <p> There is no guarantee that the name strings in the resulting array
  2.1026 +     * will appear in any specific order; they are not, in particular,
  2.1027 +     * guaranteed to appear in alphabetical order.
  2.1028 +     *
  2.1029 +     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
  2.1030 +     * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method to
  2.1031 +     * open a directory and iterate over the names of the files in the directory.
  2.1032 +     * This may use less resources when working with very large directories, and
  2.1033 +     * may be more responsive when working with remote directories.
  2.1034 +     *
  2.1035 +     * @return  An array of strings naming the files and directories in the
  2.1036 +     *          directory denoted by this abstract pathname.  The array will be
  2.1037 +     *          empty if the directory is empty.  Returns {@code null} if
  2.1038 +     *          this abstract pathname does not denote a directory, or if an
  2.1039 +     *          I/O error occurs.
  2.1040 +     *
  2.1041 +     * @throws  SecurityException
  2.1042 +     *          If a security manager exists and its {@link
  2.1043 +     *          SecurityManager#checkRead(String)} method denies read access to
  2.1044 +     *          the directory
  2.1045 +     */
  2.1046 +    public String[] list() {
  2.1047 +        SecurityManager security = System.getSecurityManager();
  2.1048 +        if (security != null) {
  2.1049 +            security.checkRead(path);
  2.1050 +        }
  2.1051 +        return fs.list(this);
  2.1052 +    }
  2.1053 +
  2.1054 +    /**
  2.1055 +     * Returns an array of strings naming the files and directories in the
  2.1056 +     * directory denoted by this abstract pathname that satisfy the specified
  2.1057 +     * filter.  The behavior of this method is the same as that of the
  2.1058 +     * {@link #list()} method, except that the strings in the returned array
  2.1059 +     * must satisfy the filter.  If the given {@code filter} is {@code null}
  2.1060 +     * then all names are accepted.  Otherwise, a name satisfies the filter if
  2.1061 +     * and only if the value {@code true} results when the {@link
  2.1062 +     * FilenameFilter#accept FilenameFilter.accept(File,&nbsp;String)} method
  2.1063 +     * of the filter is invoked on this abstract pathname and the name of a
  2.1064 +     * file or directory in the directory that it denotes.
  2.1065 +     *
  2.1066 +     * @param  filter
  2.1067 +     *         A filename filter
  2.1068 +     *
  2.1069 +     * @return  An array of strings naming the files and directories in the
  2.1070 +     *          directory denoted by this abstract pathname that were accepted
  2.1071 +     *          by the given {@code filter}.  The array will be empty if the
  2.1072 +     *          directory is empty or if no names were accepted by the filter.
  2.1073 +     *          Returns {@code null} if this abstract pathname does not denote
  2.1074 +     *          a directory, or if an I/O error occurs.
  2.1075 +     *
  2.1076 +     * @throws  SecurityException
  2.1077 +     *          If a security manager exists and its {@link
  2.1078 +     *          SecurityManager#checkRead(String)} method denies read access to
  2.1079 +     *          the directory
  2.1080 +     *
  2.1081 +     * @see java.nio.file.Files#newDirectoryStream(Path,String)
  2.1082 +     */
  2.1083 +    public String[] list(FilenameFilter filter) {
  2.1084 +        String names[] = list();
  2.1085 +        if ((names == null) || (filter == null)) {
  2.1086 +            return names;
  2.1087 +        }
  2.1088 +        List<String> v = new ArrayList<>();
  2.1089 +        for (int i = 0 ; i < names.length ; i++) {
  2.1090 +            if (filter.accept(this, names[i])) {
  2.1091 +                v.add(names[i]);
  2.1092 +            }
  2.1093 +        }
  2.1094 +        return v.toArray(new String[v.size()]);
  2.1095 +    }
  2.1096 +
  2.1097 +    /**
  2.1098 +     * Returns an array of abstract pathnames denoting the files in the
  2.1099 +     * directory denoted by this abstract pathname.
  2.1100 +     *
  2.1101 +     * <p> If this abstract pathname does not denote a directory, then this
  2.1102 +     * method returns {@code null}.  Otherwise an array of {@code File} objects
  2.1103 +     * is returned, one for each file or directory in the directory.  Pathnames
  2.1104 +     * denoting the directory itself and the directory's parent directory are
  2.1105 +     * not included in the result.  Each resulting abstract pathname is
  2.1106 +     * constructed from this abstract pathname using the {@link #File(File,
  2.1107 +     * String) File(File,&nbsp;String)} constructor.  Therefore if this
  2.1108 +     * pathname is absolute then each resulting pathname is absolute; if this
  2.1109 +     * pathname is relative then each resulting pathname will be relative to
  2.1110 +     * the same directory.
  2.1111 +     *
  2.1112 +     * <p> There is no guarantee that the name strings in the resulting array
  2.1113 +     * will appear in any specific order; they are not, in particular,
  2.1114 +     * guaranteed to appear in alphabetical order.
  2.1115 +     *
  2.1116 +     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
  2.1117 +     * java.nio.file.Files#newDirectoryStream(Path) newDirectoryStream} method
  2.1118 +     * to open a directory and iterate over the names of the files in the
  2.1119 +     * directory. This may use less resources when working with very large
  2.1120 +     * directories.
  2.1121 +     *
  2.1122 +     * @return  An array of abstract pathnames denoting the files and
  2.1123 +     *          directories in the directory denoted by this abstract pathname.
  2.1124 +     *          The array will be empty if the directory is empty.  Returns
  2.1125 +     *          {@code null} if this abstract pathname does not denote a
  2.1126 +     *          directory, or if an I/O error occurs.
  2.1127 +     *
  2.1128 +     * @throws  SecurityException
  2.1129 +     *          If a security manager exists and its {@link
  2.1130 +     *          SecurityManager#checkRead(String)} method denies read access to
  2.1131 +     *          the directory
  2.1132 +     *
  2.1133 +     * @since  1.2
  2.1134 +     */
  2.1135 +    public File[] listFiles() {
  2.1136 +        String[] ss = list();
  2.1137 +        if (ss == null) return null;
  2.1138 +        int n = ss.length;
  2.1139 +        File[] fs = new File[n];
  2.1140 +        for (int i = 0; i < n; i++) {
  2.1141 +            fs[i] = new File(ss[i], this);
  2.1142 +        }
  2.1143 +        return fs;
  2.1144 +    }
  2.1145 +
  2.1146 +    /**
  2.1147 +     * Returns an array of abstract pathnames denoting the files and
  2.1148 +     * directories in the directory denoted by this abstract pathname that
  2.1149 +     * satisfy the specified filter.  The behavior of this method is the same
  2.1150 +     * as that of the {@link #listFiles()} method, except that the pathnames in
  2.1151 +     * the returned array must satisfy the filter.  If the given {@code filter}
  2.1152 +     * is {@code null} then all pathnames are accepted.  Otherwise, a pathname
  2.1153 +     * satisfies the filter if and only if the value {@code true} results when
  2.1154 +     * the {@link FilenameFilter#accept
  2.1155 +     * FilenameFilter.accept(File,&nbsp;String)} method of the filter is
  2.1156 +     * invoked on this abstract pathname and the name of a file or directory in
  2.1157 +     * the directory that it denotes.
  2.1158 +     *
  2.1159 +     * @param  filter
  2.1160 +     *         A filename filter
  2.1161 +     *
  2.1162 +     * @return  An array of abstract pathnames denoting the files and
  2.1163 +     *          directories in the directory denoted by this abstract pathname.
  2.1164 +     *          The array will be empty if the directory is empty.  Returns
  2.1165 +     *          {@code null} if this abstract pathname does not denote a
  2.1166 +     *          directory, or if an I/O error occurs.
  2.1167 +     *
  2.1168 +     * @throws  SecurityException
  2.1169 +     *          If a security manager exists and its {@link
  2.1170 +     *          SecurityManager#checkRead(String)} method denies read access to
  2.1171 +     *          the directory
  2.1172 +     *
  2.1173 +     * @since  1.2
  2.1174 +     * @see java.nio.file.Files#newDirectoryStream(Path,String)
  2.1175 +     */
  2.1176 +    public File[] listFiles(FilenameFilter filter) {
  2.1177 +        String ss[] = list();
  2.1178 +        if (ss == null) return null;
  2.1179 +        ArrayList<File> files = new ArrayList<>();
  2.1180 +        for (String s : ss)
  2.1181 +            if ((filter == null) || filter.accept(this, s))
  2.1182 +                files.add(new File(s, this));
  2.1183 +        return files.toArray(new File[files.size()]);
  2.1184 +    }
  2.1185 +
  2.1186 +    /**
  2.1187 +     * Returns an array of abstract pathnames denoting the files and
  2.1188 +     * directories in the directory denoted by this abstract pathname that
  2.1189 +     * satisfy the specified filter.  The behavior of this method is the same
  2.1190 +     * as that of the {@link #listFiles()} method, except that the pathnames in
  2.1191 +     * the returned array must satisfy the filter.  If the given {@code filter}
  2.1192 +     * is {@code null} then all pathnames are accepted.  Otherwise, a pathname
  2.1193 +     * satisfies the filter if and only if the value {@code true} results when
  2.1194 +     * the {@link FileFilter#accept FileFilter.accept(File)} method of the
  2.1195 +     * filter is invoked on the pathname.
  2.1196 +     *
  2.1197 +     * @param  filter
  2.1198 +     *         A file filter
  2.1199 +     *
  2.1200 +     * @return  An array of abstract pathnames denoting the files and
  2.1201 +     *          directories in the directory denoted by this abstract pathname.
  2.1202 +     *          The array will be empty if the directory is empty.  Returns
  2.1203 +     *          {@code null} if this abstract pathname does not denote a
  2.1204 +     *          directory, or if an I/O error occurs.
  2.1205 +     *
  2.1206 +     * @throws  SecurityException
  2.1207 +     *          If a security manager exists and its {@link
  2.1208 +     *          SecurityManager#checkRead(String)} method denies read access to
  2.1209 +     *          the directory
  2.1210 +     *
  2.1211 +     * @since  1.2
  2.1212 +     * @see java.nio.file.Files#newDirectoryStream(Path,java.nio.file.DirectoryStream.Filter)
  2.1213 +     */
  2.1214 +    public File[] listFiles(FileFilter filter) {
  2.1215 +        String ss[] = list();
  2.1216 +        if (ss == null) return null;
  2.1217 +        ArrayList<File> files = new ArrayList<>();
  2.1218 +        for (String s : ss) {
  2.1219 +            File f = new File(s, this);
  2.1220 +            if ((filter == null) || filter.accept(f))
  2.1221 +                files.add(f);
  2.1222 +        }
  2.1223 +        return files.toArray(new File[files.size()]);
  2.1224 +    }
  2.1225 +
  2.1226 +    /**
  2.1227 +     * Creates the directory named by this abstract pathname.
  2.1228 +     *
  2.1229 +     * @return  <code>true</code> if and only if the directory was
  2.1230 +     *          created; <code>false</code> otherwise
  2.1231 +     *
  2.1232 +     * @throws  SecurityException
  2.1233 +     *          If a security manager exists and its <code>{@link
  2.1234 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1235 +     *          method does not permit the named directory to be created
  2.1236 +     */
  2.1237 +    public boolean mkdir() {
  2.1238 +        SecurityManager security = System.getSecurityManager();
  2.1239 +        if (security != null) {
  2.1240 +            security.checkWrite(path);
  2.1241 +        }
  2.1242 +        return fs.createDirectory(this);
  2.1243 +    }
  2.1244 +
  2.1245 +    /**
  2.1246 +     * Creates the directory named by this abstract pathname, including any
  2.1247 +     * necessary but nonexistent parent directories.  Note that if this
  2.1248 +     * operation fails it may have succeeded in creating some of the necessary
  2.1249 +     * parent directories.
  2.1250 +     *
  2.1251 +     * @return  <code>true</code> if and only if the directory was created,
  2.1252 +     *          along with all necessary parent directories; <code>false</code>
  2.1253 +     *          otherwise
  2.1254 +     *
  2.1255 +     * @throws  SecurityException
  2.1256 +     *          If a security manager exists and its <code>{@link
  2.1257 +     *          java.lang.SecurityManager#checkRead(java.lang.String)}</code>
  2.1258 +     *          method does not permit verification of the existence of the
  2.1259 +     *          named directory and all necessary parent directories; or if
  2.1260 +     *          the <code>{@link
  2.1261 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1262 +     *          method does not permit the named directory and all necessary
  2.1263 +     *          parent directories to be created
  2.1264 +     */
  2.1265 +    public boolean mkdirs() {
  2.1266 +        if (exists()) {
  2.1267 +            return false;
  2.1268 +        }
  2.1269 +        if (mkdir()) {
  2.1270 +            return true;
  2.1271 +        }
  2.1272 +        File canonFile = null;
  2.1273 +        try {
  2.1274 +            canonFile = getCanonicalFile();
  2.1275 +        } catch (IOException e) {
  2.1276 +            return false;
  2.1277 +        }
  2.1278 +
  2.1279 +        File parent = canonFile.getParentFile();
  2.1280 +        return (parent != null && (parent.mkdirs() || parent.exists()) &&
  2.1281 +                canonFile.mkdir());
  2.1282 +    }
  2.1283 +
  2.1284 +    /**
  2.1285 +     * Renames the file denoted by this abstract pathname.
  2.1286 +     *
  2.1287 +     * <p> Many aspects of the behavior of this method are inherently
  2.1288 +     * platform-dependent: The rename operation might not be able to move a
  2.1289 +     * file from one filesystem to another, it might not be atomic, and it
  2.1290 +     * might not succeed if a file with the destination abstract pathname
  2.1291 +     * already exists.  The return value should always be checked to make sure
  2.1292 +     * that the rename operation was successful.
  2.1293 +     *
  2.1294 +     * <p> Note that the {@link java.nio.file.Files} class defines the {@link
  2.1295 +     * java.nio.file.Files#move move} method to move or rename a file in a
  2.1296 +     * platform independent manner.
  2.1297 +     *
  2.1298 +     * @param  dest  The new abstract pathname for the named file
  2.1299 +     *
  2.1300 +     * @return  <code>true</code> if and only if the renaming succeeded;
  2.1301 +     *          <code>false</code> otherwise
  2.1302 +     *
  2.1303 +     * @throws  SecurityException
  2.1304 +     *          If a security manager exists and its <code>{@link
  2.1305 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1306 +     *          method denies write access to either the old or new pathnames
  2.1307 +     *
  2.1308 +     * @throws  NullPointerException
  2.1309 +     *          If parameter <code>dest</code> is <code>null</code>
  2.1310 +     */
  2.1311 +    public boolean renameTo(File dest) {
  2.1312 +        SecurityManager security = System.getSecurityManager();
  2.1313 +        if (security != null) {
  2.1314 +            security.checkWrite(path);
  2.1315 +            security.checkWrite(dest.path);
  2.1316 +        }
  2.1317 +        return fs.rename(this, dest);
  2.1318 +    }
  2.1319 +
  2.1320 +    /**
  2.1321 +     * Sets the last-modified time of the file or directory named by this
  2.1322 +     * abstract pathname.
  2.1323 +     *
  2.1324 +     * <p> All platforms support file-modification times to the nearest second,
  2.1325 +     * but some provide more precision.  The argument will be truncated to fit
  2.1326 +     * the supported precision.  If the operation succeeds and no intervening
  2.1327 +     * operations on the file take place, then the next invocation of the
  2.1328 +     * <code>{@link #lastModified}</code> method will return the (possibly
  2.1329 +     * truncated) <code>time</code> argument that was passed to this method.
  2.1330 +     *
  2.1331 +     * @param  time  The new last-modified time, measured in milliseconds since
  2.1332 +     *               the epoch (00:00:00 GMT, January 1, 1970)
  2.1333 +     *
  2.1334 +     * @return <code>true</code> if and only if the operation succeeded;
  2.1335 +     *          <code>false</code> otherwise
  2.1336 +     *
  2.1337 +     * @throws  IllegalArgumentException  If the argument is negative
  2.1338 +     *
  2.1339 +     * @throws  SecurityException
  2.1340 +     *          If a security manager exists and its <code>{@link
  2.1341 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1342 +     *          method denies write access to the named file
  2.1343 +     *
  2.1344 +     * @since 1.2
  2.1345 +     */
  2.1346 +    public boolean setLastModified(long time) {
  2.1347 +        if (time < 0) throw new IllegalArgumentException("Negative time");
  2.1348 +        SecurityManager security = System.getSecurityManager();
  2.1349 +        if (security != null) {
  2.1350 +            security.checkWrite(path);
  2.1351 +        }
  2.1352 +        return fs.setLastModifiedTime(this, time);
  2.1353 +    }
  2.1354 +
  2.1355 +    /**
  2.1356 +     * Marks the file or directory named by this abstract pathname so that
  2.1357 +     * only read operations are allowed.  After invoking this method the file
  2.1358 +     * or directory is guaranteed not to change until it is either deleted or
  2.1359 +     * marked to allow write access.  Whether or not a read-only file or
  2.1360 +     * directory may be deleted depends upon the underlying system.
  2.1361 +     *
  2.1362 +     * @return <code>true</code> if and only if the operation succeeded;
  2.1363 +     *          <code>false</code> otherwise
  2.1364 +     *
  2.1365 +     * @throws  SecurityException
  2.1366 +     *          If a security manager exists and its <code>{@link
  2.1367 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1368 +     *          method denies write access to the named file
  2.1369 +     *
  2.1370 +     * @since 1.2
  2.1371 +     */
  2.1372 +    public boolean setReadOnly() {
  2.1373 +        SecurityManager security = System.getSecurityManager();
  2.1374 +        if (security != null) {
  2.1375 +            security.checkWrite(path);
  2.1376 +        }
  2.1377 +        return fs.setReadOnly(this);
  2.1378 +    }
  2.1379 +
  2.1380 +    /**
  2.1381 +     * Sets the owner's or everybody's write permission for this abstract
  2.1382 +     * pathname.
  2.1383 +     *
  2.1384 +     * <p> The {@link java.nio.file.Files} class defines methods that operate on
  2.1385 +     * file attributes including file permissions. This may be used when finer
  2.1386 +     * manipulation of file permissions is required.
  2.1387 +     *
  2.1388 +     * @param   writable
  2.1389 +     *          If <code>true</code>, sets the access permission to allow write
  2.1390 +     *          operations; if <code>false</code> to disallow write operations
  2.1391 +     *
  2.1392 +     * @param   ownerOnly
  2.1393 +     *          If <code>true</code>, the write permission applies only to the
  2.1394 +     *          owner's write permission; otherwise, it applies to everybody.  If
  2.1395 +     *          the underlying file system can not distinguish the owner's write
  2.1396 +     *          permission from that of others, then the permission will apply to
  2.1397 +     *          everybody, regardless of this value.
  2.1398 +     *
  2.1399 +     * @return  <code>true</code> if and only if the operation succeeded. The
  2.1400 +     *          operation will fail if the user does not have permission to change
  2.1401 +     *          the access permissions of this abstract pathname.
  2.1402 +     *
  2.1403 +     * @throws  SecurityException
  2.1404 +     *          If a security manager exists and its <code>{@link
  2.1405 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1406 +     *          method denies write access to the named file
  2.1407 +     *
  2.1408 +     * @since 1.6
  2.1409 +     */
  2.1410 +    public boolean setWritable(boolean writable, boolean ownerOnly) {
  2.1411 +        SecurityManager security = System.getSecurityManager();
  2.1412 +        if (security != null) {
  2.1413 +            security.checkWrite(path);
  2.1414 +        }
  2.1415 +        return fs.setPermission(this, FileSystem.ACCESS_WRITE, writable, ownerOnly);
  2.1416 +    }
  2.1417 +
  2.1418 +    /**
  2.1419 +     * A convenience method to set the owner's write permission for this abstract
  2.1420 +     * pathname.
  2.1421 +     *
  2.1422 +     * <p> An invocation of this method of the form <tt>file.setWritable(arg)</tt>
  2.1423 +     * behaves in exactly the same way as the invocation
  2.1424 +     *
  2.1425 +     * <pre>
  2.1426 +     *     file.setWritable(arg, true) </pre>
  2.1427 +     *
  2.1428 +     * @param   writable
  2.1429 +     *          If <code>true</code>, sets the access permission to allow write
  2.1430 +     *          operations; if <code>false</code> to disallow write operations
  2.1431 +     *
  2.1432 +     * @return  <code>true</code> if and only if the operation succeeded.  The
  2.1433 +     *          operation will fail if the user does not have permission to
  2.1434 +     *          change the access permissions of this abstract pathname.
  2.1435 +     *
  2.1436 +     * @throws  SecurityException
  2.1437 +     *          If a security manager exists and its <code>{@link
  2.1438 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1439 +     *          method denies write access to the file
  2.1440 +     *
  2.1441 +     * @since 1.6
  2.1442 +     */
  2.1443 +    public boolean setWritable(boolean writable) {
  2.1444 +        return setWritable(writable, true);
  2.1445 +    }
  2.1446 +
  2.1447 +    /**
  2.1448 +     * Sets the owner's or everybody's read permission for this abstract
  2.1449 +     * pathname.
  2.1450 +     *
  2.1451 +     * <p> The {@link java.nio.file.Files} class defines methods that operate on
  2.1452 +     * file attributes including file permissions. This may be used when finer
  2.1453 +     * manipulation of file permissions is required.
  2.1454 +     *
  2.1455 +     * @param   readable
  2.1456 +     *          If <code>true</code>, sets the access permission to allow read
  2.1457 +     *          operations; if <code>false</code> to disallow read operations
  2.1458 +     *
  2.1459 +     * @param   ownerOnly
  2.1460 +     *          If <code>true</code>, the read permission applies only to the
  2.1461 +     *          owner's read permission; otherwise, it applies to everybody.  If
  2.1462 +     *          the underlying file system can not distinguish the owner's read
  2.1463 +     *          permission from that of others, then the permission will apply to
  2.1464 +     *          everybody, regardless of this value.
  2.1465 +     *
  2.1466 +     * @return  <code>true</code> if and only if the operation succeeded.  The
  2.1467 +     *          operation will fail if the user does not have permission to
  2.1468 +     *          change the access permissions of this abstract pathname.  If
  2.1469 +     *          <code>readable</code> is <code>false</code> and the underlying
  2.1470 +     *          file system does not implement a read permission, then the
  2.1471 +     *          operation will fail.
  2.1472 +     *
  2.1473 +     * @throws  SecurityException
  2.1474 +     *          If a security manager exists and its <code>{@link
  2.1475 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1476 +     *          method denies write access to the file
  2.1477 +     *
  2.1478 +     * @since 1.6
  2.1479 +     */
  2.1480 +    public boolean setReadable(boolean readable, boolean ownerOnly) {
  2.1481 +        SecurityManager security = System.getSecurityManager();
  2.1482 +        if (security != null) {
  2.1483 +            security.checkWrite(path);
  2.1484 +        }
  2.1485 +        return fs.setPermission(this, FileSystem.ACCESS_READ, readable, ownerOnly);
  2.1486 +    }
  2.1487 +
  2.1488 +    /**
  2.1489 +     * A convenience method to set the owner's read permission for this abstract
  2.1490 +     * pathname.
  2.1491 +     *
  2.1492 +     * <p>An invocation of this method of the form <tt>file.setReadable(arg)</tt>
  2.1493 +     * behaves in exactly the same way as the invocation
  2.1494 +     *
  2.1495 +     * <pre>
  2.1496 +     *     file.setReadable(arg, true) </pre>
  2.1497 +     *
  2.1498 +     * @param  readable
  2.1499 +     *          If <code>true</code>, sets the access permission to allow read
  2.1500 +     *          operations; if <code>false</code> to disallow read operations
  2.1501 +     *
  2.1502 +     * @return  <code>true</code> if and only if the operation succeeded.  The
  2.1503 +     *          operation will fail if the user does not have permission to
  2.1504 +     *          change the access permissions of this abstract pathname.  If
  2.1505 +     *          <code>readable</code> is <code>false</code> and the underlying
  2.1506 +     *          file system does not implement a read permission, then the
  2.1507 +     *          operation will fail.
  2.1508 +     *
  2.1509 +     * @throws  SecurityException
  2.1510 +     *          If a security manager exists and its <code>{@link
  2.1511 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1512 +     *          method denies write access to the file
  2.1513 +     *
  2.1514 +     * @since 1.6
  2.1515 +     */
  2.1516 +    public boolean setReadable(boolean readable) {
  2.1517 +        return setReadable(readable, true);
  2.1518 +    }
  2.1519 +
  2.1520 +    /**
  2.1521 +     * Sets the owner's or everybody's execute permission for this abstract
  2.1522 +     * pathname.
  2.1523 +     *
  2.1524 +     * <p> The {@link java.nio.file.Files} class defines methods that operate on
  2.1525 +     * file attributes including file permissions. This may be used when finer
  2.1526 +     * manipulation of file permissions is required.
  2.1527 +     *
  2.1528 +     * @param   executable
  2.1529 +     *          If <code>true</code>, sets the access permission to allow execute
  2.1530 +     *          operations; if <code>false</code> to disallow execute operations
  2.1531 +     *
  2.1532 +     * @param   ownerOnly
  2.1533 +     *          If <code>true</code>, the execute permission applies only to the
  2.1534 +     *          owner's execute permission; otherwise, it applies to everybody.
  2.1535 +     *          If the underlying file system can not distinguish the owner's
  2.1536 +     *          execute permission from that of others, then the permission will
  2.1537 +     *          apply to everybody, regardless of this value.
  2.1538 +     *
  2.1539 +     * @return  <code>true</code> if and only if the operation succeeded.  The
  2.1540 +     *          operation will fail if the user does not have permission to
  2.1541 +     *          change the access permissions of this abstract pathname.  If
  2.1542 +     *          <code>executable</code> is <code>false</code> and the underlying
  2.1543 +     *          file system does not implement an execute permission, then the
  2.1544 +     *          operation will fail.
  2.1545 +     *
  2.1546 +     * @throws  SecurityException
  2.1547 +     *          If a security manager exists and its <code>{@link
  2.1548 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1549 +     *          method denies write access to the file
  2.1550 +     *
  2.1551 +     * @since 1.6
  2.1552 +     */
  2.1553 +    public boolean setExecutable(boolean executable, boolean ownerOnly) {
  2.1554 +        SecurityManager security = System.getSecurityManager();
  2.1555 +        if (security != null) {
  2.1556 +            security.checkWrite(path);
  2.1557 +        }
  2.1558 +        return fs.setPermission(this, FileSystem.ACCESS_EXECUTE, executable, ownerOnly);
  2.1559 +    }
  2.1560 +
  2.1561 +    /**
  2.1562 +     * A convenience method to set the owner's execute permission for this abstract
  2.1563 +     * pathname.
  2.1564 +     *
  2.1565 +     * <p>An invocation of this method of the form <tt>file.setExcutable(arg)</tt>
  2.1566 +     * behaves in exactly the same way as the invocation
  2.1567 +     *
  2.1568 +     * <pre>
  2.1569 +     *     file.setExecutable(arg, true) </pre>
  2.1570 +     *
  2.1571 +     * @param   executable
  2.1572 +     *          If <code>true</code>, sets the access permission to allow execute
  2.1573 +     *          operations; if <code>false</code> to disallow execute operations
  2.1574 +     *
  2.1575 +     * @return   <code>true</code> if and only if the operation succeeded.  The
  2.1576 +     *           operation will fail if the user does not have permission to
  2.1577 +     *           change the access permissions of this abstract pathname.  If
  2.1578 +     *           <code>executable</code> is <code>false</code> and the underlying
  2.1579 +     *           file system does not implement an excute permission, then the
  2.1580 +     *           operation will fail.
  2.1581 +     *
  2.1582 +     * @throws  SecurityException
  2.1583 +     *          If a security manager exists and its <code>{@link
  2.1584 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1585 +     *          method denies write access to the file
  2.1586 +     *
  2.1587 +     * @since 1.6
  2.1588 +     */
  2.1589 +    public boolean setExecutable(boolean executable) {
  2.1590 +        return setExecutable(executable, true);
  2.1591 +    }
  2.1592 +
  2.1593 +    /**
  2.1594 +     * Tests whether the application can execute the file denoted by this
  2.1595 +     * abstract pathname.
  2.1596 +     *
  2.1597 +     * @return  <code>true</code> if and only if the abstract pathname exists
  2.1598 +     *          <em>and</em> the application is allowed to execute the file
  2.1599 +     *
  2.1600 +     * @throws  SecurityException
  2.1601 +     *          If a security manager exists and its <code>{@link
  2.1602 +     *          java.lang.SecurityManager#checkExec(java.lang.String)}</code>
  2.1603 +     *          method denies execute access to the file
  2.1604 +     *
  2.1605 +     * @since 1.6
  2.1606 +     */
  2.1607 +    public boolean canExecute() {
  2.1608 +        SecurityManager security = System.getSecurityManager();
  2.1609 +        if (security != null) {
  2.1610 +            security.checkExec(path);
  2.1611 +        }
  2.1612 +        return fs.checkAccess(this, FileSystem.ACCESS_EXECUTE);
  2.1613 +    }
  2.1614 +
  2.1615 +
  2.1616 +    /* -- Filesystem interface -- */
  2.1617 +
  2.1618 +    /**
  2.1619 +     * List the available filesystem roots.
  2.1620 +     *
  2.1621 +     * <p> A particular Java platform may support zero or more
  2.1622 +     * hierarchically-organized file systems.  Each file system has a
  2.1623 +     * {@code root} directory from which all other files in that file system
  2.1624 +     * can be reached.  Windows platforms, for example, have a root directory
  2.1625 +     * for each active drive; UNIX platforms have a single root directory,
  2.1626 +     * namely {@code "/"}.  The set of available filesystem roots is affected
  2.1627 +     * by various system-level operations such as the insertion or ejection of
  2.1628 +     * removable media and the disconnecting or unmounting of physical or
  2.1629 +     * virtual disk drives.
  2.1630 +     *
  2.1631 +     * <p> This method returns an array of {@code File} objects that denote the
  2.1632 +     * root directories of the available filesystem roots.  It is guaranteed
  2.1633 +     * that the canonical pathname of any file physically present on the local
  2.1634 +     * machine will begin with one of the roots returned by this method.
  2.1635 +     *
  2.1636 +     * <p> The canonical pathname of a file that resides on some other machine
  2.1637 +     * and is accessed via a remote-filesystem protocol such as SMB or NFS may
  2.1638 +     * or may not begin with one of the roots returned by this method.  If the
  2.1639 +     * pathname of a remote file is syntactically indistinguishable from the
  2.1640 +     * pathname of a local file then it will begin with one of the roots
  2.1641 +     * returned by this method.  Thus, for example, {@code File} objects
  2.1642 +     * denoting the root directories of the mapped network drives of a Windows
  2.1643 +     * platform will be returned by this method, while {@code File} objects
  2.1644 +     * containing UNC pathnames will not be returned by this method.
  2.1645 +     *
  2.1646 +     * <p> Unlike most methods in this class, this method does not throw
  2.1647 +     * security exceptions.  If a security manager exists and its {@link
  2.1648 +     * SecurityManager#checkRead(String)} method denies read access to a
  2.1649 +     * particular root directory, then that directory will not appear in the
  2.1650 +     * result.
  2.1651 +     *
  2.1652 +     * @return  An array of {@code File} objects denoting the available
  2.1653 +     *          filesystem roots, or {@code null} if the set of roots could not
  2.1654 +     *          be determined.  The array will be empty if there are no
  2.1655 +     *          filesystem roots.
  2.1656 +     *
  2.1657 +     * @since  1.2
  2.1658 +     * @see java.nio.file.FileStore
  2.1659 +     */
  2.1660 +    public static File[] listRoots() {
  2.1661 +        return fs.listRoots();
  2.1662 +    }
  2.1663 +
  2.1664 +
  2.1665 +    /* -- Disk usage -- */
  2.1666 +
  2.1667 +    /**
  2.1668 +     * Returns the size of the partition <a href="#partName">named</a> by this
  2.1669 +     * abstract pathname.
  2.1670 +     *
  2.1671 +     * @return  The size, in bytes, of the partition or <tt>0L</tt> if this
  2.1672 +     *          abstract pathname does not name a partition
  2.1673 +     *
  2.1674 +     * @throws  SecurityException
  2.1675 +     *          If a security manager has been installed and it denies
  2.1676 +     *          {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
  2.1677 +     *          or its {@link SecurityManager#checkRead(String)} method denies
  2.1678 +     *          read access to the file named by this abstract pathname
  2.1679 +     *
  2.1680 +     * @since  1.6
  2.1681 +     */
  2.1682 +    public long getTotalSpace() {
  2.1683 +        SecurityManager sm = System.getSecurityManager();
  2.1684 +        if (sm != null) {
  2.1685 +            sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  2.1686 +            sm.checkRead(path);
  2.1687 +        }
  2.1688 +        return fs.getSpace(this, FileSystem.SPACE_TOTAL);
  2.1689 +    }
  2.1690 +
  2.1691 +    /**
  2.1692 +     * Returns the number of unallocated bytes in the partition <a
  2.1693 +     * href="#partName">named</a> by this abstract path name.
  2.1694 +     *
  2.1695 +     * <p> The returned number of unallocated bytes is a hint, but not
  2.1696 +     * a guarantee, that it is possible to use most or any of these
  2.1697 +     * bytes.  The number of unallocated bytes is most likely to be
  2.1698 +     * accurate immediately after this call.  It is likely to be made
  2.1699 +     * inaccurate by any external I/O operations including those made
  2.1700 +     * on the system outside of this virtual machine.  This method
  2.1701 +     * makes no guarantee that write operations to this file system
  2.1702 +     * will succeed.
  2.1703 +     *
  2.1704 +     * @return  The number of unallocated bytes on the partition <tt>0L</tt>
  2.1705 +     *          if the abstract pathname does not name a partition.  This
  2.1706 +     *          value will be less than or equal to the total file system size
  2.1707 +     *          returned by {@link #getTotalSpace}.
  2.1708 +     *
  2.1709 +     * @throws  SecurityException
  2.1710 +     *          If a security manager has been installed and it denies
  2.1711 +     *          {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
  2.1712 +     *          or its {@link SecurityManager#checkRead(String)} method denies
  2.1713 +     *          read access to the file named by this abstract pathname
  2.1714 +     *
  2.1715 +     * @since  1.6
  2.1716 +     */
  2.1717 +    public long getFreeSpace() {
  2.1718 +        SecurityManager sm = System.getSecurityManager();
  2.1719 +        if (sm != null) {
  2.1720 +            sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  2.1721 +            sm.checkRead(path);
  2.1722 +        }
  2.1723 +        return fs.getSpace(this, FileSystem.SPACE_FREE);
  2.1724 +    }
  2.1725 +
  2.1726 +    /**
  2.1727 +     * Returns the number of bytes available to this virtual machine on the
  2.1728 +     * partition <a href="#partName">named</a> by this abstract pathname.  When
  2.1729 +     * possible, this method checks for write permissions and other operating
  2.1730 +     * system restrictions and will therefore usually provide a more accurate
  2.1731 +     * estimate of how much new data can actually be written than {@link
  2.1732 +     * #getFreeSpace}.
  2.1733 +     *
  2.1734 +     * <p> The returned number of available bytes is a hint, but not a
  2.1735 +     * guarantee, that it is possible to use most or any of these bytes.  The
  2.1736 +     * number of unallocated bytes is most likely to be accurate immediately
  2.1737 +     * after this call.  It is likely to be made inaccurate by any external
  2.1738 +     * I/O operations including those made on the system outside of this
  2.1739 +     * virtual machine.  This method makes no guarantee that write operations
  2.1740 +     * to this file system will succeed.
  2.1741 +     *
  2.1742 +     * @return  The number of available bytes on the partition or <tt>0L</tt>
  2.1743 +     *          if the abstract pathname does not name a partition.  On
  2.1744 +     *          systems where this information is not available, this method
  2.1745 +     *          will be equivalent to a call to {@link #getFreeSpace}.
  2.1746 +     *
  2.1747 +     * @throws  SecurityException
  2.1748 +     *          If a security manager has been installed and it denies
  2.1749 +     *          {@link RuntimePermission}<tt>("getFileSystemAttributes")</tt>
  2.1750 +     *          or its {@link SecurityManager#checkRead(String)} method denies
  2.1751 +     *          read access to the file named by this abstract pathname
  2.1752 +     *
  2.1753 +     * @since  1.6
  2.1754 +     */
  2.1755 +    public long getUsableSpace() {
  2.1756 +        SecurityManager sm = System.getSecurityManager();
  2.1757 +        if (sm != null) {
  2.1758 +            sm.checkPermission(new RuntimePermission("getFileSystemAttributes"));
  2.1759 +            sm.checkRead(path);
  2.1760 +        }
  2.1761 +        return fs.getSpace(this, FileSystem.SPACE_USABLE);
  2.1762 +    }
  2.1763 +
  2.1764 +    /* -- Temporary files -- */
  2.1765 +
  2.1766 +    private static class TempDirectory {
  2.1767 +        private TempDirectory() { }
  2.1768 +
  2.1769 +        // temporary directory location
  2.1770 +        private static final File tmpdir = new File(fs.normalize(AccessController
  2.1771 +            .doPrivileged(new GetPropertyAction("java.io.tmpdir"))));
  2.1772 +        static File location() {
  2.1773 +            return tmpdir;
  2.1774 +        }
  2.1775 +
  2.1776 +        // file name generation
  2.1777 +        private static final SecureRandom random = new SecureRandom();
  2.1778 +        static File generateFile(String prefix, String suffix, File dir) {
  2.1779 +            long n = random.nextLong();
  2.1780 +            if (n == Long.MIN_VALUE) {
  2.1781 +                n = 0;      // corner case
  2.1782 +            } else {
  2.1783 +                n = Math.abs(n);
  2.1784 +            }
  2.1785 +            return new File(dir, prefix + Long.toString(n) + suffix);
  2.1786 +        }
  2.1787 +    }
  2.1788 +
  2.1789 +    /**
  2.1790 +     * <p> Creates a new empty file in the specified directory, using the
  2.1791 +     * given prefix and suffix strings to generate its name.  If this method
  2.1792 +     * returns successfully then it is guaranteed that:
  2.1793 +     *
  2.1794 +     * <ol>
  2.1795 +     * <li> The file denoted by the returned abstract pathname did not exist
  2.1796 +     *      before this method was invoked, and
  2.1797 +     * <li> Neither this method nor any of its variants will return the same
  2.1798 +     *      abstract pathname again in the current invocation of the virtual
  2.1799 +     *      machine.
  2.1800 +     * </ol>
  2.1801 +     *
  2.1802 +     * This method provides only part of a temporary-file facility.  To arrange
  2.1803 +     * for a file created by this method to be deleted automatically, use the
  2.1804 +     * <code>{@link #deleteOnExit}</code> method.
  2.1805 +     *
  2.1806 +     * <p> The <code>prefix</code> argument must be at least three characters
  2.1807 +     * long.  It is recommended that the prefix be a short, meaningful string
  2.1808 +     * such as <code>"hjb"</code> or <code>"mail"</code>.  The
  2.1809 +     * <code>suffix</code> argument may be <code>null</code>, in which case the
  2.1810 +     * suffix <code>".tmp"</code> will be used.
  2.1811 +     *
  2.1812 +     * <p> To create the new file, the prefix and the suffix may first be
  2.1813 +     * adjusted to fit the limitations of the underlying platform.  If the
  2.1814 +     * prefix is too long then it will be truncated, but its first three
  2.1815 +     * characters will always be preserved.  If the suffix is too long then it
  2.1816 +     * too will be truncated, but if it begins with a period character
  2.1817 +     * (<code>'.'</code>) then the period and the first three characters
  2.1818 +     * following it will always be preserved.  Once these adjustments have been
  2.1819 +     * made the name of the new file will be generated by concatenating the
  2.1820 +     * prefix, five or more internally-generated characters, and the suffix.
  2.1821 +     *
  2.1822 +     * <p> If the <code>directory</code> argument is <code>null</code> then the
  2.1823 +     * system-dependent default temporary-file directory will be used.  The
  2.1824 +     * default temporary-file directory is specified by the system property
  2.1825 +     * <code>java.io.tmpdir</code>.  On UNIX systems the default value of this
  2.1826 +     * property is typically <code>"/tmp"</code> or <code>"/var/tmp"</code>; on
  2.1827 +     * Microsoft Windows systems it is typically <code>"C:\\WINNT\\TEMP"</code>.  A different
  2.1828 +     * value may be given to this system property when the Java virtual machine
  2.1829 +     * is invoked, but programmatic changes to this property are not guaranteed
  2.1830 +     * to have any effect upon the temporary directory used by this method.
  2.1831 +     *
  2.1832 +     * @param  prefix     The prefix string to be used in generating the file's
  2.1833 +     *                    name; must be at least three characters long
  2.1834 +     *
  2.1835 +     * @param  suffix     The suffix string to be used in generating the file's
  2.1836 +     *                    name; may be <code>null</code>, in which case the
  2.1837 +     *                    suffix <code>".tmp"</code> will be used
  2.1838 +     *
  2.1839 +     * @param  directory  The directory in which the file is to be created, or
  2.1840 +     *                    <code>null</code> if the default temporary-file
  2.1841 +     *                    directory is to be used
  2.1842 +     *
  2.1843 +     * @return  An abstract pathname denoting a newly-created empty file
  2.1844 +     *
  2.1845 +     * @throws  IllegalArgumentException
  2.1846 +     *          If the <code>prefix</code> argument contains fewer than three
  2.1847 +     *          characters
  2.1848 +     *
  2.1849 +     * @throws  IOException  If a file could not be created
  2.1850 +     *
  2.1851 +     * @throws  SecurityException
  2.1852 +     *          If a security manager exists and its <code>{@link
  2.1853 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1854 +     *          method does not allow a file to be created
  2.1855 +     *
  2.1856 +     * @since 1.2
  2.1857 +     */
  2.1858 +    public static File createTempFile(String prefix, String suffix,
  2.1859 +                                      File directory)
  2.1860 +        throws IOException
  2.1861 +    {
  2.1862 +        if (prefix.length() < 3)
  2.1863 +            throw new IllegalArgumentException("Prefix string too short");
  2.1864 +        if (suffix == null)
  2.1865 +            suffix = ".tmp";
  2.1866 +
  2.1867 +        File tmpdir = (directory != null) ? directory : TempDirectory.location();
  2.1868 +        SecurityManager sm = System.getSecurityManager();
  2.1869 +        File f;
  2.1870 +        do {
  2.1871 +            f = TempDirectory.generateFile(prefix, suffix, tmpdir);
  2.1872 +            if (sm != null) {
  2.1873 +                try {
  2.1874 +                    sm.checkWrite(f.getPath());
  2.1875 +                } catch (SecurityException se) {
  2.1876 +                    // don't reveal temporary directory location
  2.1877 +                    if (directory == null)
  2.1878 +                        throw new SecurityException("Unable to create temporary file");
  2.1879 +                    throw se;
  2.1880 +                }
  2.1881 +            }
  2.1882 +        } while (!fs.createFileExclusively(f.getPath()));
  2.1883 +        return f;
  2.1884 +    }
  2.1885 +
  2.1886 +    /**
  2.1887 +     * Creates an empty file in the default temporary-file directory, using
  2.1888 +     * the given prefix and suffix to generate its name. Invoking this method
  2.1889 +     * is equivalent to invoking <code>{@link #createTempFile(java.lang.String,
  2.1890 +     * java.lang.String, java.io.File)
  2.1891 +     * createTempFile(prefix,&nbsp;suffix,&nbsp;null)}</code>.
  2.1892 +     *
  2.1893 +     * <p> The {@link
  2.1894 +     * java.nio.file.Files#createTempFile(String,String,java.nio.file.attribute.FileAttribute[])
  2.1895 +     * Files.createTempFile} method provides an alternative method to create an
  2.1896 +     * empty file in the temporary-file directory. Files created by that method
  2.1897 +     * may have more restrictive access permissions to files created by this
  2.1898 +     * method and so may be more suited to security-sensitive applications.
  2.1899 +     *
  2.1900 +     * @param  prefix     The prefix string to be used in generating the file's
  2.1901 +     *                    name; must be at least three characters long
  2.1902 +     *
  2.1903 +     * @param  suffix     The suffix string to be used in generating the file's
  2.1904 +     *                    name; may be <code>null</code>, in which case the
  2.1905 +     *                    suffix <code>".tmp"</code> will be used
  2.1906 +     *
  2.1907 +     * @return  An abstract pathname denoting a newly-created empty file
  2.1908 +     *
  2.1909 +     * @throws  IllegalArgumentException
  2.1910 +     *          If the <code>prefix</code> argument contains fewer than three
  2.1911 +     *          characters
  2.1912 +     *
  2.1913 +     * @throws  IOException  If a file could not be created
  2.1914 +     *
  2.1915 +     * @throws  SecurityException
  2.1916 +     *          If a security manager exists and its <code>{@link
  2.1917 +     *          java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
  2.1918 +     *          method does not allow a file to be created
  2.1919 +     *
  2.1920 +     * @since 1.2
  2.1921 +     * @see java.nio.file.Files#createTempDirectory(String,FileAttribute[])
  2.1922 +     */
  2.1923 +    public static File createTempFile(String prefix, String suffix)
  2.1924 +        throws IOException
  2.1925 +    {
  2.1926 +        return createTempFile(prefix, suffix, null);
  2.1927 +    }
  2.1928 +
  2.1929 +    /* -- Basic infrastructure -- */
  2.1930 +
  2.1931 +    /**
  2.1932 +     * Compares two abstract pathnames lexicographically.  The ordering
  2.1933 +     * defined by this method depends upon the underlying system.  On UNIX
  2.1934 +     * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
  2.1935 +     * systems it is not.
  2.1936 +     *
  2.1937 +     * @param   pathname  The abstract pathname to be compared to this abstract
  2.1938 +     *                    pathname
  2.1939 +     *
  2.1940 +     * @return  Zero if the argument is equal to this abstract pathname, a
  2.1941 +     *          value less than zero if this abstract pathname is
  2.1942 +     *          lexicographically less than the argument, or a value greater
  2.1943 +     *          than zero if this abstract pathname is lexicographically
  2.1944 +     *          greater than the argument
  2.1945 +     *
  2.1946 +     * @since   1.2
  2.1947 +     */
  2.1948 +    public int compareTo(File pathname) {
  2.1949 +        return fs.compare(this, pathname);
  2.1950 +    }
  2.1951 +
  2.1952 +    /**
  2.1953 +     * Tests this abstract pathname for equality with the given object.
  2.1954 +     * Returns <code>true</code> if and only if the argument is not
  2.1955 +     * <code>null</code> and is an abstract pathname that denotes the same file
  2.1956 +     * or directory as this abstract pathname.  Whether or not two abstract
  2.1957 +     * pathnames are equal depends upon the underlying system.  On UNIX
  2.1958 +     * systems, alphabetic case is significant in comparing pathnames; on Microsoft Windows
  2.1959 +     * systems it is not.
  2.1960 +     *
  2.1961 +     * @param   obj   The object to be compared with this abstract pathname
  2.1962 +     *
  2.1963 +     * @return  <code>true</code> if and only if the objects are the same;
  2.1964 +     *          <code>false</code> otherwise
  2.1965 +     */
  2.1966 +    public boolean equals(Object obj) {
  2.1967 +        if ((obj != null) && (obj instanceof File)) {
  2.1968 +            return compareTo((File)obj) == 0;
  2.1969 +        }
  2.1970 +        return false;
  2.1971 +    }
  2.1972 +
  2.1973 +    /**
  2.1974 +     * Computes a hash code for this abstract pathname.  Because equality of
  2.1975 +     * abstract pathnames is inherently system-dependent, so is the computation
  2.1976 +     * of their hash codes.  On UNIX systems, the hash code of an abstract
  2.1977 +     * pathname is equal to the exclusive <em>or</em> of the hash code
  2.1978 +     * of its pathname string and the decimal value
  2.1979 +     * <code>1234321</code>.  On Microsoft Windows systems, the hash
  2.1980 +     * code is equal to the exclusive <em>or</em> of the hash code of
  2.1981 +     * its pathname string converted to lower case and the decimal
  2.1982 +     * value <code>1234321</code>.  Locale is not taken into account on
  2.1983 +     * lowercasing the pathname string.
  2.1984 +     *
  2.1985 +     * @return  A hash code for this abstract pathname
  2.1986 +     */
  2.1987 +    public int hashCode() {
  2.1988 +        return fs.hashCode(this);
  2.1989 +    }
  2.1990 +
  2.1991 +    /**
  2.1992 +     * Returns the pathname string of this abstract pathname.  This is just the
  2.1993 +     * string returned by the <code>{@link #getPath}</code> method.
  2.1994 +     *
  2.1995 +     * @return  The string form of this abstract pathname
  2.1996 +     */
  2.1997 +    public String toString() {
  2.1998 +        return getPath();
  2.1999 +    }
  2.2000 +
  2.2001 +    /**
  2.2002 +     * WriteObject is called to save this filename.
  2.2003 +     * The separator character is saved also so it can be replaced
  2.2004 +     * in case the path is reconstituted on a different host type.
  2.2005 +     * <p>
  2.2006 +     * @serialData  Default fields followed by separator character.
  2.2007 +     */
  2.2008 +    private synchronized void writeObject(java.io.ObjectOutputStream s)
  2.2009 +        throws IOException
  2.2010 +    {
  2.2011 +        s.defaultWriteObject();
  2.2012 +        s.writeChar(this.separatorChar); // Add the separator character
  2.2013 +    }
  2.2014 +
  2.2015 +    /**
  2.2016 +     * readObject is called to restore this filename.
  2.2017 +     * The original separator character is read.  If it is different
  2.2018 +     * than the separator character on this system, then the old separator
  2.2019 +     * is replaced by the local separator.
  2.2020 +     */
  2.2021 +    private synchronized void readObject(java.io.ObjectInputStream s)
  2.2022 +         throws IOException, ClassNotFoundException
  2.2023 +    {
  2.2024 +        ObjectInputStream.GetField fields = s.readFields();
  2.2025 +        String pathField = (String)fields.get("path", null);
  2.2026 +        char sep = s.readChar(); // read the previous separator char
  2.2027 +        if (sep != separatorChar)
  2.2028 +            pathField = pathField.replace(sep, separatorChar);
  2.2029 +        this.path = fs.normalize(pathField);
  2.2030 +        this.prefixLength = fs.prefixLength(this.path);
  2.2031 +    }
  2.2032 +
  2.2033 +    /** use serialVersionUID from JDK 1.0.2 for interoperability */
  2.2034 +    private static final long serialVersionUID = 301077366599181567L;
  2.2035 +
  2.2036 +    // -- Integration with java.nio.file --
  2.2037 +
  2.2038 +    private volatile transient Path filePath;
  2.2039 +
  2.2040 +    /**
  2.2041 +     * Returns a {@link Path java.nio.file.Path} object constructed from the
  2.2042 +     * this abstract path. The resulting {@code Path} is associated with the
  2.2043 +     * {@link java.nio.file.FileSystems#getDefault default-filesystem}.
  2.2044 +     *
  2.2045 +     * <p> The first invocation of this method works as if invoking it were
  2.2046 +     * equivalent to evaluating the expression:
  2.2047 +     * <blockquote><pre>
  2.2048 +     * {@link java.nio.file.FileSystems#getDefault FileSystems.getDefault}().{@link
  2.2049 +     * java.nio.file.FileSystem#getPath getPath}(this.{@link #getPath getPath}());
  2.2050 +     * </pre></blockquote>
  2.2051 +     * Subsequent invocations of this method return the same {@code Path}.
  2.2052 +     *
  2.2053 +     * <p> If this abstract pathname is the empty abstract pathname then this
  2.2054 +     * method returns a {@code Path} that may be used to access the current
  2.2055 +     * user directory.
  2.2056 +     *
  2.2057 +     * @return  a {@code Path} constructed from this abstract path
  2.2058 +     *
  2.2059 +     * @throws  java.nio.file.InvalidPathException
  2.2060 +     *          if a {@code Path} object cannot be constructed from the abstract
  2.2061 +     *          path (see {@link java.nio.file.FileSystem#getPath FileSystem.getPath})
  2.2062 +     *
  2.2063 +     * @since   1.7
  2.2064 +     * @see Path#toFile
  2.2065 +     */
  2.2066 +    public Path toPath() {
  2.2067 +        Path result = filePath;
  2.2068 +        if (result == null) {
  2.2069 +            synchronized (this) {
  2.2070 +                result = filePath;
  2.2071 +                if (result == null) {
  2.2072 +                    result = FileSystems.getDefault().getPath(path);
  2.2073 +                    filePath = result;
  2.2074 +                }
  2.2075 +            }
  2.2076 +        }
  2.2077 +        return result;
  2.2078 +    }
  2.2079 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/rt/emul/compact/src/main/java/java/io/FileFilter.java	Sat Sep 07 13:55:09 2013 +0200
     3.3 @@ -0,0 +1,50 @@
     3.4 +/*
     3.5 + * Copyright (c) 1998, 2002, 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 +
    3.29 +package java.io;
    3.30 +
    3.31 +
    3.32 +/**
    3.33 + * A filter for abstract pathnames.
    3.34 + *
    3.35 + * <p> Instances of this interface may be passed to the <code>{@link
    3.36 + * File#listFiles(java.io.FileFilter) listFiles(FileFilter)}</code> method
    3.37 + * of the <code>{@link java.io.File}</code> class.
    3.38 + *
    3.39 + * @since 1.2
    3.40 + */
    3.41 +public interface FileFilter {
    3.42 +
    3.43 +    /**
    3.44 +     * Tests whether or not the specified abstract pathname should be
    3.45 +     * included in a pathname list.
    3.46 +     *
    3.47 +     * @param  pathname  The abstract pathname to be tested
    3.48 +     * @return  <code>true</code> if and only if <code>pathname</code>
    3.49 +     *          should be included
    3.50 +     */
    3.51 +    boolean accept(File pathname);
    3.52 +
    3.53 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/rt/emul/compact/src/main/java/java/io/FileNotFoundException.java	Sat Sep 07 13:55:09 2013 +0200
     4.3 @@ -0,0 +1,82 @@
     4.4 +/*
     4.5 + * Copyright (c) 1994, 2008, 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 +
    4.29 +package java.io;
    4.30 +
    4.31 +
    4.32 +/**
    4.33 + * Signals that an attempt to open the file denoted by a specified pathname
    4.34 + * has failed.
    4.35 + *
    4.36 + * <p> This exception will be thrown by the {@link FileInputStream}, {@link
    4.37 + * FileOutputStream}, and {@link RandomAccessFile} constructors when a file
    4.38 + * with the specified pathname does not exist.  It will also be thrown by these
    4.39 + * constructors if the file does exist but for some reason is inaccessible, for
    4.40 + * example when an attempt is made to open a read-only file for writing.
    4.41 + *
    4.42 + * @author  unascribed
    4.43 + * @since   JDK1.0
    4.44 + */
    4.45 +
    4.46 +public class FileNotFoundException extends IOException {
    4.47 +    private static final long serialVersionUID = -897856973823710492L;
    4.48 +
    4.49 +    /**
    4.50 +     * Constructs a <code>FileNotFoundException</code> with
    4.51 +     * <code>null</code> as its error detail message.
    4.52 +     */
    4.53 +    public FileNotFoundException() {
    4.54 +        super();
    4.55 +    }
    4.56 +
    4.57 +    /**
    4.58 +     * Constructs a <code>FileNotFoundException</code> with the
    4.59 +     * specified detail message. The string <code>s</code> can be
    4.60 +     * retrieved later by the
    4.61 +     * <code>{@link java.lang.Throwable#getMessage}</code>
    4.62 +     * method of class <code>java.lang.Throwable</code>.
    4.63 +     *
    4.64 +     * @param   s   the detail message.
    4.65 +     */
    4.66 +    public FileNotFoundException(String s) {
    4.67 +        super(s);
    4.68 +    }
    4.69 +
    4.70 +    /**
    4.71 +     * Constructs a <code>FileNotFoundException</code> with a detail message
    4.72 +     * consisting of the given pathname string followed by the given reason
    4.73 +     * string.  If the <code>reason</code> argument is <code>null</code> then
    4.74 +     * it will be omitted.  This private constructor is invoked only by native
    4.75 +     * I/O methods.
    4.76 +     *
    4.77 +     * @since 1.2
    4.78 +     */
    4.79 +    private FileNotFoundException(String path, String reason) {
    4.80 +        super(path + ((reason == null)
    4.81 +                      ? ""
    4.82 +                      : " (" + reason + ")"));
    4.83 +    }
    4.84 +
    4.85 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/rt/emul/compact/src/main/java/java/io/FilenameFilter.java	Sat Sep 07 13:55:09 2013 +0200
     5.3 @@ -0,0 +1,53 @@
     5.4 +/*
     5.5 + * Copyright (c) 1994, 1998, 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.io;
    5.30 +
    5.31 +/**
    5.32 + * Instances of classes that implement this interface are used to
    5.33 + * filter filenames. These instances are used to filter directory
    5.34 + * listings in the <code>list</code> method of class
    5.35 + * <code>File</code>, and by the Abstract Window Toolkit's file
    5.36 + * dialog component.
    5.37 + *
    5.38 + * @author  Arthur van Hoff
    5.39 + * @author  Jonathan Payne
    5.40 + * @see     java.awt.FileDialog#setFilenameFilter(java.io.FilenameFilter)
    5.41 + * @see     java.io.File
    5.42 + * @see     java.io.File#list(java.io.FilenameFilter)
    5.43 + * @since   JDK1.0
    5.44 + */
    5.45 +public
    5.46 +interface FilenameFilter {
    5.47 +    /**
    5.48 +     * Tests if a specified file should be included in a file list.
    5.49 +     *
    5.50 +     * @param   dir    the directory in which the file was found.
    5.51 +     * @param   name   the name of the file.
    5.52 +     * @return  <code>true</code> if and only if the name should be
    5.53 +     * included in the file list; <code>false</code> otherwise.
    5.54 +     */
    5.55 +    boolean accept(File dir, String name);
    5.56 +}
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/rt/emul/compact/src/main/java/java/io/InterruptedIOException.java	Sat Sep 07 13:55:09 2013 +0200
     6.3 @@ -0,0 +1,74 @@
     6.4 +/*
     6.5 + * Copyright (c) 1995, 2008, 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.io;
    6.30 +
    6.31 +/**
    6.32 + * Signals that an I/O operation has been interrupted. An
    6.33 + * <code>InterruptedIOException</code> is thrown to indicate that an
    6.34 + * input or output transfer has been terminated because the thread
    6.35 + * performing it was interrupted. The field {@link #bytesTransferred}
    6.36 + * indicates how many bytes were successfully transferred before
    6.37 + * the interruption occurred.
    6.38 + *
    6.39 + * @author  unascribed
    6.40 + * @see     java.io.InputStream
    6.41 + * @see     java.io.OutputStream
    6.42 + * @see     java.lang.Thread#interrupt()
    6.43 + * @since   JDK1.0
    6.44 + */
    6.45 +public
    6.46 +class InterruptedIOException extends IOException {
    6.47 +    private static final long serialVersionUID = 4020568460727500567L;
    6.48 +
    6.49 +    /**
    6.50 +     * Constructs an <code>InterruptedIOException</code> with
    6.51 +     * <code>null</code> as its error detail message.
    6.52 +     */
    6.53 +    public InterruptedIOException() {
    6.54 +        super();
    6.55 +    }
    6.56 +
    6.57 +    /**
    6.58 +     * Constructs an <code>InterruptedIOException</code> with the
    6.59 +     * specified detail message. The string <code>s</code> can be
    6.60 +     * retrieved later by the
    6.61 +     * <code>{@link java.lang.Throwable#getMessage}</code>
    6.62 +     * method of class <code>java.lang.Throwable</code>.
    6.63 +     *
    6.64 +     * @param   s   the detail message.
    6.65 +     */
    6.66 +    public InterruptedIOException(String s) {
    6.67 +        super(s);
    6.68 +    }
    6.69 +
    6.70 +    /**
    6.71 +     * Reports how many bytes had been transferred as part of the I/O
    6.72 +     * operation before it was interrupted.
    6.73 +     *
    6.74 +     * @serial
    6.75 +     */
    6.76 +    public int bytesTransferred = 0;
    6.77 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/rt/emul/compact/src/main/java/java/io/OutputStreamWriter.java	Sat Sep 07 13:55:09 2013 +0200
     7.3 @@ -0,0 +1,235 @@
     7.4 +/*
     7.5 + * Copyright (c) 1996, 2006, 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.io;
    7.30 +
    7.31 +import java.nio.charset.Charset;
    7.32 +import java.nio.charset.CharsetEncoder;
    7.33 +import sun.nio.cs.StreamEncoder;
    7.34 +
    7.35 +
    7.36 +/**
    7.37 + * An OutputStreamWriter is a bridge from character streams to byte streams:
    7.38 + * Characters written to it are encoded into bytes using a specified {@link
    7.39 + * java.nio.charset.Charset <code>charset</code>}.  The charset that it uses
    7.40 + * may be specified by name or may be given explicitly, or the platform's
    7.41 + * default charset may be accepted.
    7.42 + *
    7.43 + * <p> Each invocation of a write() method causes the encoding converter to be
    7.44 + * invoked on the given character(s).  The resulting bytes are accumulated in a
    7.45 + * buffer before being written to the underlying output stream.  The size of
    7.46 + * this buffer may be specified, but by default it is large enough for most
    7.47 + * purposes.  Note that the characters passed to the write() methods are not
    7.48 + * buffered.
    7.49 + *
    7.50 + * <p> For top efficiency, consider wrapping an OutputStreamWriter within a
    7.51 + * BufferedWriter so as to avoid frequent converter invocations.  For example:
    7.52 + *
    7.53 + * <pre>
    7.54 + * Writer out
    7.55 + *   = new BufferedWriter(new OutputStreamWriter(System.out));
    7.56 + * </pre>
    7.57 + *
    7.58 + * <p> A <i>surrogate pair</i> is a character represented by a sequence of two
    7.59 + * <tt>char</tt> values: A <i>high</i> surrogate in the range '&#92;uD800' to
    7.60 + * '&#92;uDBFF' followed by a <i>low</i> surrogate in the range '&#92;uDC00' to
    7.61 + * '&#92;uDFFF'.
    7.62 + *
    7.63 + * <p> A <i>malformed surrogate element</i> is a high surrogate that is not
    7.64 + * followed by a low surrogate or a low surrogate that is not preceded by a
    7.65 + * high surrogate.
    7.66 + *
    7.67 + * <p> This class always replaces malformed surrogate elements and unmappable
    7.68 + * character sequences with the charset's default <i>substitution sequence</i>.
    7.69 + * The {@linkplain java.nio.charset.CharsetEncoder} class should be used when more
    7.70 + * control over the encoding process is required.
    7.71 + *
    7.72 + * @see BufferedWriter
    7.73 + * @see OutputStream
    7.74 + * @see java.nio.charset.Charset
    7.75 + *
    7.76 + * @author      Mark Reinhold
    7.77 + * @since       JDK1.1
    7.78 + */
    7.79 +
    7.80 +public class OutputStreamWriter extends Writer {
    7.81 +
    7.82 +    private final StreamEncoder se;
    7.83 +
    7.84 +    /**
    7.85 +     * Creates an OutputStreamWriter that uses the named charset.
    7.86 +     *
    7.87 +     * @param  out
    7.88 +     *         An OutputStream
    7.89 +     *
    7.90 +     * @param  charsetName
    7.91 +     *         The name of a supported
    7.92 +     *         {@link java.nio.charset.Charset </code>charset<code>}
    7.93 +     *
    7.94 +     * @exception  UnsupportedEncodingException
    7.95 +     *             If the named encoding is not supported
    7.96 +     */
    7.97 +    public OutputStreamWriter(OutputStream out, String charsetName)
    7.98 +        throws UnsupportedEncodingException
    7.99 +    {
   7.100 +        super(out);
   7.101 +        if (charsetName == null)
   7.102 +            throw new NullPointerException("charsetName");
   7.103 +        se = StreamEncoder.forOutputStreamWriter(out, this, charsetName);
   7.104 +    }
   7.105 +
   7.106 +    /**
   7.107 +     * Creates an OutputStreamWriter that uses the default character encoding.
   7.108 +     *
   7.109 +     * @param  out  An OutputStream
   7.110 +     */
   7.111 +    public OutputStreamWriter(OutputStream out) {
   7.112 +        super(out);
   7.113 +        try {
   7.114 +            se = StreamEncoder.forOutputStreamWriter(out, this, (String)null);
   7.115 +        } catch (UnsupportedEncodingException e) {
   7.116 +            throw new Error(e);
   7.117 +        }
   7.118 +    }
   7.119 +
   7.120 +    /**
   7.121 +     * Creates an OutputStreamWriter that uses the given charset. </p>
   7.122 +     *
   7.123 +     * @param  out
   7.124 +     *         An OutputStream
   7.125 +     *
   7.126 +     * @param  cs
   7.127 +     *         A charset
   7.128 +     *
   7.129 +     * @since 1.4
   7.130 +     * @spec JSR-51
   7.131 +     */
   7.132 +    public OutputStreamWriter(OutputStream out, Charset cs) {
   7.133 +        super(out);
   7.134 +        if (cs == null)
   7.135 +            throw new NullPointerException("charset");
   7.136 +        se = StreamEncoder.forOutputStreamWriter(out, this, cs);
   7.137 +    }
   7.138 +
   7.139 +    /**
   7.140 +     * Creates an OutputStreamWriter that uses the given charset encoder.  </p>
   7.141 +     *
   7.142 +     * @param  out
   7.143 +     *         An OutputStream
   7.144 +     *
   7.145 +     * @param  enc
   7.146 +     *         A charset encoder
   7.147 +     *
   7.148 +     * @since 1.4
   7.149 +     * @spec JSR-51
   7.150 +     */
   7.151 +    public OutputStreamWriter(OutputStream out, CharsetEncoder enc) {
   7.152 +        super(out);
   7.153 +        if (enc == null)
   7.154 +            throw new NullPointerException("charset encoder");
   7.155 +        se = StreamEncoder.forOutputStreamWriter(out, this, enc);
   7.156 +    }
   7.157 +
   7.158 +    /**
   7.159 +     * Returns the name of the character encoding being used by this stream.
   7.160 +     *
   7.161 +     * <p> If the encoding has an historical name then that name is returned;
   7.162 +     * otherwise the encoding's canonical name is returned.
   7.163 +     *
   7.164 +     * <p> If this instance was created with the {@link
   7.165 +     * #OutputStreamWriter(OutputStream, String)} constructor then the returned
   7.166 +     * name, being unique for the encoding, may differ from the name passed to
   7.167 +     * the constructor.  This method may return <tt>null</tt> if the stream has
   7.168 +     * been closed. </p>
   7.169 +     *
   7.170 +     * @return The historical name of this encoding, or possibly
   7.171 +     *         <code>null</code> if the stream has been closed
   7.172 +     *
   7.173 +     * @see java.nio.charset.Charset
   7.174 +     *
   7.175 +     * @revised 1.4
   7.176 +     * @spec JSR-51
   7.177 +     */
   7.178 +    public String getEncoding() {
   7.179 +        return se.getEncoding();
   7.180 +    }
   7.181 +
   7.182 +    /**
   7.183 +     * Flushes the output buffer to the underlying byte stream, without flushing
   7.184 +     * the byte stream itself.  This method is non-private only so that it may
   7.185 +     * be invoked by PrintStream.
   7.186 +     */
   7.187 +    void flushBuffer() throws IOException {
   7.188 +        se.flushBuffer();
   7.189 +    }
   7.190 +
   7.191 +    /**
   7.192 +     * Writes a single character.
   7.193 +     *
   7.194 +     * @exception  IOException  If an I/O error occurs
   7.195 +     */
   7.196 +    public void write(int c) throws IOException {
   7.197 +        se.write(c);
   7.198 +    }
   7.199 +
   7.200 +    /**
   7.201 +     * Writes a portion of an array of characters.
   7.202 +     *
   7.203 +     * @param  cbuf  Buffer of characters
   7.204 +     * @param  off   Offset from which to start writing characters
   7.205 +     * @param  len   Number of characters to write
   7.206 +     *
   7.207 +     * @exception  IOException  If an I/O error occurs
   7.208 +     */
   7.209 +    public void write(char cbuf[], int off, int len) throws IOException {
   7.210 +        se.write(cbuf, off, len);
   7.211 +    }
   7.212 +
   7.213 +    /**
   7.214 +     * Writes a portion of a string.
   7.215 +     *
   7.216 +     * @param  str  A String
   7.217 +     * @param  off  Offset from which to start writing characters
   7.218 +     * @param  len  Number of characters to write
   7.219 +     *
   7.220 +     * @exception  IOException  If an I/O error occurs
   7.221 +     */
   7.222 +    public void write(String str, int off, int len) throws IOException {
   7.223 +        se.write(str, off, len);
   7.224 +    }
   7.225 +
   7.226 +    /**
   7.227 +     * Flushes the stream.
   7.228 +     *
   7.229 +     * @exception  IOException  If an I/O error occurs
   7.230 +     */
   7.231 +    public void flush() throws IOException {
   7.232 +        se.flush();
   7.233 +    }
   7.234 +
   7.235 +    public void close() throws IOException {
   7.236 +        se.close();
   7.237 +    }
   7.238 +}
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/rt/emul/compact/src/main/java/java/io/PrintStream.java	Sat Sep 07 13:55:09 2013 +0200
     8.3 @@ -0,0 +1,1129 @@
     8.4 +/*
     8.5 + * Copyright (c) 1996, 2011, 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 +
    8.29 +package java.io;
    8.30 +
    8.31 +import java.util.Formatter;
    8.32 +import java.util.Locale;
    8.33 +import java.nio.charset.Charset;
    8.34 +import java.nio.charset.IllegalCharsetNameException;
    8.35 +import java.nio.charset.UnsupportedCharsetException;
    8.36 +
    8.37 +/**
    8.38 + * A <code>PrintStream</code> adds functionality to another output stream,
    8.39 + * namely the ability to print representations of various data values
    8.40 + * conveniently.  Two other features are provided as well.  Unlike other output
    8.41 + * streams, a <code>PrintStream</code> never throws an
    8.42 + * <code>IOException</code>; instead, exceptional situations merely set an
    8.43 + * internal flag that can be tested via the <code>checkError</code> method.
    8.44 + * Optionally, a <code>PrintStream</code> can be created so as to flush
    8.45 + * automatically; this means that the <code>flush</code> method is
    8.46 + * automatically invoked after a byte array is written, one of the
    8.47 + * <code>println</code> methods is invoked, or a newline character or byte
    8.48 + * (<code>'\n'</code>) is written.
    8.49 + *
    8.50 + * <p> All characters printed by a <code>PrintStream</code> are converted into
    8.51 + * bytes using the platform's default character encoding.  The <code>{@link
    8.52 + * PrintWriter}</code> class should be used in situations that require writing
    8.53 + * characters rather than bytes.
    8.54 + *
    8.55 + * @author     Frank Yellin
    8.56 + * @author     Mark Reinhold
    8.57 + * @since      JDK1.0
    8.58 + */
    8.59 +
    8.60 +public class PrintStream extends FilterOutputStream
    8.61 +    implements Appendable, Closeable
    8.62 +{
    8.63 +
    8.64 +    private final boolean autoFlush;
    8.65 +    private boolean trouble = false;
    8.66 +    private Formatter formatter;
    8.67 +
    8.68 +    /**
    8.69 +     * Track both the text- and character-output streams, so that their buffers
    8.70 +     * can be flushed without flushing the entire stream.
    8.71 +     */
    8.72 +    private BufferedWriter textOut;
    8.73 +    private OutputStreamWriter charOut;
    8.74 +
    8.75 +    /**
    8.76 +     * requireNonNull is explicitly declared here so as not to create an extra
    8.77 +     * dependency on java.util.Objects.requireNonNull. PrintStream is loaded
    8.78 +     * early during system initialization.
    8.79 +     */
    8.80 +    private static <T> T requireNonNull(T obj, String message) {
    8.81 +        if (obj == null)
    8.82 +            throw new NullPointerException(message);
    8.83 +        return obj;
    8.84 +    }
    8.85 +
    8.86 +    /**
    8.87 +     * Returns a charset object for the given charset name.
    8.88 +     * @throws NullPointerException          is csn is null
    8.89 +     * @throws UnsupportedEncodingException  if the charset is not supported
    8.90 +     */
    8.91 +    private static Charset toCharset(String csn)
    8.92 +        throws UnsupportedEncodingException
    8.93 +    {
    8.94 +        requireNonNull(csn, "charsetName");
    8.95 +        try {
    8.96 +            return Charset.forName(csn);
    8.97 +        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
    8.98 +            // UnsupportedEncodingException should be thrown
    8.99 +            throw new UnsupportedEncodingException(csn);
   8.100 +        }
   8.101 +    }
   8.102 +
   8.103 +    /* Private constructors */
   8.104 +    private PrintStream(boolean autoFlush, OutputStream out) {
   8.105 +        super(out);
   8.106 +        this.autoFlush = autoFlush;
   8.107 +        this.charOut = new OutputStreamWriter(this);
   8.108 +        this.textOut = new BufferedWriter(charOut);
   8.109 +    }
   8.110 +
   8.111 +    private PrintStream(boolean autoFlush, OutputStream out, Charset charset) {
   8.112 +        super(out);
   8.113 +        this.autoFlush = autoFlush;
   8.114 +        this.charOut = new OutputStreamWriter(this, charset);
   8.115 +        this.textOut = new BufferedWriter(charOut);
   8.116 +    }
   8.117 +
   8.118 +    /* Variant of the private constructor so that the given charset name
   8.119 +     * can be verified before evaluating the OutputStream argument. Used
   8.120 +     * by constructors creating a FileOutputStream that also take a
   8.121 +     * charset name.
   8.122 +     */
   8.123 +    private PrintStream(boolean autoFlush, Charset charset, OutputStream out)
   8.124 +        throws UnsupportedEncodingException
   8.125 +    {
   8.126 +        this(autoFlush, out, charset);
   8.127 +    }
   8.128 +
   8.129 +    /**
   8.130 +     * Creates a new print stream.  This stream will not flush automatically.
   8.131 +     *
   8.132 +     * @param  out        The output stream to which values and objects will be
   8.133 +     *                    printed
   8.134 +     *
   8.135 +     * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream)
   8.136 +     */
   8.137 +    public PrintStream(OutputStream out) {
   8.138 +        this(out, false);
   8.139 +    }
   8.140 +
   8.141 +    /**
   8.142 +     * Creates a new print stream.
   8.143 +     *
   8.144 +     * @param  out        The output stream to which values and objects will be
   8.145 +     *                    printed
   8.146 +     * @param  autoFlush  A boolean; if true, the output buffer will be flushed
   8.147 +     *                    whenever a byte array is written, one of the
   8.148 +     *                    <code>println</code> methods is invoked, or a newline
   8.149 +     *                    character or byte (<code>'\n'</code>) is written
   8.150 +     *
   8.151 +     * @see java.io.PrintWriter#PrintWriter(java.io.OutputStream, boolean)
   8.152 +     */
   8.153 +    public PrintStream(OutputStream out, boolean autoFlush) {
   8.154 +        this(autoFlush, requireNonNull(out, "Null output stream"));
   8.155 +    }
   8.156 +
   8.157 +    /**
   8.158 +     * Creates a new print stream.
   8.159 +     *
   8.160 +     * @param  out        The output stream to which values and objects will be
   8.161 +     *                    printed
   8.162 +     * @param  autoFlush  A boolean; if true, the output buffer will be flushed
   8.163 +     *                    whenever a byte array is written, one of the
   8.164 +     *                    <code>println</code> methods is invoked, or a newline
   8.165 +     *                    character or byte (<code>'\n'</code>) is written
   8.166 +     * @param  encoding   The name of a supported
   8.167 +     *                    <a href="../lang/package-summary.html#charenc">
   8.168 +     *                    character encoding</a>
   8.169 +     *
   8.170 +     * @throws  UnsupportedEncodingException
   8.171 +     *          If the named encoding is not supported
   8.172 +     *
   8.173 +     * @since  1.4
   8.174 +     */
   8.175 +    public PrintStream(OutputStream out, boolean autoFlush, String encoding)
   8.176 +        throws UnsupportedEncodingException
   8.177 +    {
   8.178 +        this(autoFlush,
   8.179 +             requireNonNull(out, "Null output stream"),
   8.180 +             toCharset(encoding));
   8.181 +    }
   8.182 +
   8.183 +    /**
   8.184 +     * Creates a new print stream, without automatic line flushing, with the
   8.185 +     * specified file name.  This convenience constructor creates
   8.186 +     * the necessary intermediate {@link java.io.OutputStreamWriter
   8.187 +     * OutputStreamWriter}, which will encode characters using the
   8.188 +     * {@linkplain java.nio.charset.Charset#defaultCharset() default charset}
   8.189 +     * for this instance of the Java virtual machine.
   8.190 +     *
   8.191 +     * @param  fileName
   8.192 +     *         The name of the file to use as the destination of this print
   8.193 +     *         stream.  If the file exists, then it will be truncated to
   8.194 +     *         zero size; otherwise, a new file will be created.  The output
   8.195 +     *         will be written to the file and is buffered.
   8.196 +     *
   8.197 +     * @throws  FileNotFoundException
   8.198 +     *          If the given file object does not denote an existing, writable
   8.199 +     *          regular file and a new regular file of that name cannot be
   8.200 +     *          created, or if some other error occurs while opening or
   8.201 +     *          creating the file
   8.202 +     *
   8.203 +     * @throws  SecurityException
   8.204 +     *          If a security manager is present and {@link
   8.205 +     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   8.206 +     *          access to the file
   8.207 +     *
   8.208 +     * @since  1.5
   8.209 +     */
   8.210 +    public PrintStream(String fileName) throws FileNotFoundException {
   8.211 +        this(false, new FileOutputStream(fileName));
   8.212 +    }
   8.213 +
   8.214 +    /**
   8.215 +     * Creates a new print stream, without automatic line flushing, with the
   8.216 +     * specified file name and charset.  This convenience constructor creates
   8.217 +     * the necessary intermediate {@link java.io.OutputStreamWriter
   8.218 +     * OutputStreamWriter}, which will encode characters using the provided
   8.219 +     * charset.
   8.220 +     *
   8.221 +     * @param  fileName
   8.222 +     *         The name of the file to use as the destination of this print
   8.223 +     *         stream.  If the file exists, then it will be truncated to
   8.224 +     *         zero size; otherwise, a new file will be created.  The output
   8.225 +     *         will be written to the file and is buffered.
   8.226 +     *
   8.227 +     * @param  csn
   8.228 +     *         The name of a supported {@linkplain java.nio.charset.Charset
   8.229 +     *         charset}
   8.230 +     *
   8.231 +     * @throws  FileNotFoundException
   8.232 +     *          If the given file object does not denote an existing, writable
   8.233 +     *          regular file and a new regular file of that name cannot be
   8.234 +     *          created, or if some other error occurs while opening or
   8.235 +     *          creating the file
   8.236 +     *
   8.237 +     * @throws  SecurityException
   8.238 +     *          If a security manager is present and {@link
   8.239 +     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   8.240 +     *          access to the file
   8.241 +     *
   8.242 +     * @throws  UnsupportedEncodingException
   8.243 +     *          If the named charset is not supported
   8.244 +     *
   8.245 +     * @since  1.5
   8.246 +     */
   8.247 +    public PrintStream(String fileName, String csn)
   8.248 +        throws FileNotFoundException, UnsupportedEncodingException
   8.249 +    {
   8.250 +        // ensure charset is checked before the file is opened
   8.251 +        this(false, toCharset(csn), new FileOutputStream(fileName));
   8.252 +    }
   8.253 +
   8.254 +    /**
   8.255 +     * Creates a new print stream, without automatic line flushing, with the
   8.256 +     * specified file.  This convenience constructor creates the necessary
   8.257 +     * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
   8.258 +     * which will encode characters using the {@linkplain
   8.259 +     * java.nio.charset.Charset#defaultCharset() default charset} for this
   8.260 +     * instance of the Java virtual machine.
   8.261 +     *
   8.262 +     * @param  file
   8.263 +     *         The file to use as the destination of this print stream.  If the
   8.264 +     *         file exists, then it will be truncated to zero size; otherwise,
   8.265 +     *         a new file will be created.  The output will be written to the
   8.266 +     *         file and is buffered.
   8.267 +     *
   8.268 +     * @throws  FileNotFoundException
   8.269 +     *          If the given file object does not denote an existing, writable
   8.270 +     *          regular file and a new regular file of that name cannot be
   8.271 +     *          created, or if some other error occurs while opening or
   8.272 +     *          creating the file
   8.273 +     *
   8.274 +     * @throws  SecurityException
   8.275 +     *          If a security manager is present and {@link
   8.276 +     *          SecurityManager#checkWrite checkWrite(file.getPath())}
   8.277 +     *          denies write access to the file
   8.278 +     *
   8.279 +     * @since  1.5
   8.280 +     */
   8.281 +    public PrintStream(File file) throws FileNotFoundException {
   8.282 +        this(false, new FileOutputStream(file));
   8.283 +    }
   8.284 +
   8.285 +    /**
   8.286 +     * Creates a new print stream, without automatic line flushing, with the
   8.287 +     * specified file and charset.  This convenience constructor creates
   8.288 +     * the necessary intermediate {@link java.io.OutputStreamWriter
   8.289 +     * OutputStreamWriter}, which will encode characters using the provided
   8.290 +     * charset.
   8.291 +     *
   8.292 +     * @param  file
   8.293 +     *         The file to use as the destination of this print stream.  If the
   8.294 +     *         file exists, then it will be truncated to zero size; otherwise,
   8.295 +     *         a new file will be created.  The output will be written to the
   8.296 +     *         file and is buffered.
   8.297 +     *
   8.298 +     * @param  csn
   8.299 +     *         The name of a supported {@linkplain java.nio.charset.Charset
   8.300 +     *         charset}
   8.301 +     *
   8.302 +     * @throws  FileNotFoundException
   8.303 +     *          If the given file object does not denote an existing, writable
   8.304 +     *          regular file and a new regular file of that name cannot be
   8.305 +     *          created, or if some other error occurs while opening or
   8.306 +     *          creating the file
   8.307 +     *
   8.308 +     * @throws  SecurityException
   8.309 +     *          If a security manager is presentand {@link
   8.310 +     *          SecurityManager#checkWrite checkWrite(file.getPath())}
   8.311 +     *          denies write access to the file
   8.312 +     *
   8.313 +     * @throws  UnsupportedEncodingException
   8.314 +     *          If the named charset is not supported
   8.315 +     *
   8.316 +     * @since  1.5
   8.317 +     */
   8.318 +    public PrintStream(File file, String csn)
   8.319 +        throws FileNotFoundException, UnsupportedEncodingException
   8.320 +    {
   8.321 +        // ensure charset is checked before the file is opened
   8.322 +        this(false, toCharset(csn), new FileOutputStream(file));
   8.323 +    }
   8.324 +
   8.325 +    /** Check to make sure that the stream has not been closed */
   8.326 +    private void ensureOpen() throws IOException {
   8.327 +        if (out == null)
   8.328 +            throw new IOException("Stream closed");
   8.329 +    }
   8.330 +
   8.331 +    /**
   8.332 +     * Flushes the stream.  This is done by writing any buffered output bytes to
   8.333 +     * the underlying output stream and then flushing that stream.
   8.334 +     *
   8.335 +     * @see        java.io.OutputStream#flush()
   8.336 +     */
   8.337 +    public void flush() {
   8.338 +        synchronized (this) {
   8.339 +            try {
   8.340 +                ensureOpen();
   8.341 +                out.flush();
   8.342 +            }
   8.343 +            catch (IOException x) {
   8.344 +                trouble = true;
   8.345 +            }
   8.346 +        }
   8.347 +    }
   8.348 +
   8.349 +    private boolean closing = false; /* To avoid recursive closing */
   8.350 +
   8.351 +    /**
   8.352 +     * Closes the stream.  This is done by flushing the stream and then closing
   8.353 +     * the underlying output stream.
   8.354 +     *
   8.355 +     * @see        java.io.OutputStream#close()
   8.356 +     */
   8.357 +    public void close() {
   8.358 +        synchronized (this) {
   8.359 +            if (! closing) {
   8.360 +                closing = true;
   8.361 +                try {
   8.362 +                    textOut.close();
   8.363 +                    out.close();
   8.364 +                }
   8.365 +                catch (IOException x) {
   8.366 +                    trouble = true;
   8.367 +                }
   8.368 +                textOut = null;
   8.369 +                charOut = null;
   8.370 +                out = null;
   8.371 +            }
   8.372 +        }
   8.373 +    }
   8.374 +
   8.375 +    /**
   8.376 +     * Flushes the stream and checks its error state. The internal error state
   8.377 +     * is set to <code>true</code> when the underlying output stream throws an
   8.378 +     * <code>IOException</code> other than <code>InterruptedIOException</code>,
   8.379 +     * and when the <code>setError</code> method is invoked.  If an operation
   8.380 +     * on the underlying output stream throws an
   8.381 +     * <code>InterruptedIOException</code>, then the <code>PrintStream</code>
   8.382 +     * converts the exception back into an interrupt by doing:
   8.383 +     * <pre>
   8.384 +     *     Thread.currentThread().interrupt();
   8.385 +     * </pre>
   8.386 +     * or the equivalent.
   8.387 +     *
   8.388 +     * @return <code>true</code> if and only if this stream has encountered an
   8.389 +     *         <code>IOException</code> other than
   8.390 +     *         <code>InterruptedIOException</code>, or the
   8.391 +     *         <code>setError</code> method has been invoked
   8.392 +     */
   8.393 +    public boolean checkError() {
   8.394 +        if (out != null)
   8.395 +            flush();
   8.396 +        if (out instanceof java.io.PrintStream) {
   8.397 +            PrintStream ps = (PrintStream) out;
   8.398 +            return ps.checkError();
   8.399 +        }
   8.400 +        return trouble;
   8.401 +    }
   8.402 +
   8.403 +    /**
   8.404 +     * Sets the error state of the stream to <code>true</code>.
   8.405 +     *
   8.406 +     * <p> This method will cause subsequent invocations of {@link
   8.407 +     * #checkError()} to return <tt>true</tt> until {@link
   8.408 +     * #clearError()} is invoked.
   8.409 +     *
   8.410 +     * @since JDK1.1
   8.411 +     */
   8.412 +    protected void setError() {
   8.413 +        trouble = true;
   8.414 +    }
   8.415 +
   8.416 +    /**
   8.417 +     * Clears the internal error state of this stream.
   8.418 +     *
   8.419 +     * <p> This method will cause subsequent invocations of {@link
   8.420 +     * #checkError()} to return <tt>false</tt> until another write
   8.421 +     * operation fails and invokes {@link #setError()}.
   8.422 +     *
   8.423 +     * @since 1.6
   8.424 +     */
   8.425 +    protected void clearError() {
   8.426 +        trouble = false;
   8.427 +    }
   8.428 +
   8.429 +    /*
   8.430 +     * Exception-catching, synchronized output operations,
   8.431 +     * which also implement the write() methods of OutputStream
   8.432 +     */
   8.433 +
   8.434 +    /**
   8.435 +     * Writes the specified byte to this stream.  If the byte is a newline and
   8.436 +     * automatic flushing is enabled then the <code>flush</code> method will be
   8.437 +     * invoked.
   8.438 +     *
   8.439 +     * <p> Note that the byte is written as given; to write a character that
   8.440 +     * will be translated according to the platform's default character
   8.441 +     * encoding, use the <code>print(char)</code> or <code>println(char)</code>
   8.442 +     * methods.
   8.443 +     *
   8.444 +     * @param  b  The byte to be written
   8.445 +     * @see #print(char)
   8.446 +     * @see #println(char)
   8.447 +     */
   8.448 +    public void write(int b) {
   8.449 +        try {
   8.450 +            synchronized (this) {
   8.451 +                ensureOpen();
   8.452 +                out.write(b);
   8.453 +                if ((b == '\n') && autoFlush)
   8.454 +                    out.flush();
   8.455 +            }
   8.456 +        }
   8.457 +        catch (InterruptedIOException x) {
   8.458 +            Thread.currentThread().interrupt();
   8.459 +        }
   8.460 +        catch (IOException x) {
   8.461 +            trouble = true;
   8.462 +        }
   8.463 +    }
   8.464 +
   8.465 +    /**
   8.466 +     * Writes <code>len</code> bytes from the specified byte array starting at
   8.467 +     * offset <code>off</code> to this stream.  If automatic flushing is
   8.468 +     * enabled then the <code>flush</code> method will be invoked.
   8.469 +     *
   8.470 +     * <p> Note that the bytes will be written as given; to write characters
   8.471 +     * that will be translated according to the platform's default character
   8.472 +     * encoding, use the <code>print(char)</code> or <code>println(char)</code>
   8.473 +     * methods.
   8.474 +     *
   8.475 +     * @param  buf   A byte array
   8.476 +     * @param  off   Offset from which to start taking bytes
   8.477 +     * @param  len   Number of bytes to write
   8.478 +     */
   8.479 +    public void write(byte buf[], int off, int len) {
   8.480 +        try {
   8.481 +            synchronized (this) {
   8.482 +                ensureOpen();
   8.483 +                out.write(buf, off, len);
   8.484 +                if (autoFlush)
   8.485 +                    out.flush();
   8.486 +            }
   8.487 +        }
   8.488 +        catch (InterruptedIOException x) {
   8.489 +            Thread.currentThread().interrupt();
   8.490 +        }
   8.491 +        catch (IOException x) {
   8.492 +            trouble = true;
   8.493 +        }
   8.494 +    }
   8.495 +
   8.496 +    /*
   8.497 +     * The following private methods on the text- and character-output streams
   8.498 +     * always flush the stream buffers, so that writes to the underlying byte
   8.499 +     * stream occur as promptly as with the original PrintStream.
   8.500 +     */
   8.501 +
   8.502 +    private void write(char buf[]) {
   8.503 +        try {
   8.504 +            synchronized (this) {
   8.505 +                ensureOpen();
   8.506 +                textOut.write(buf);
   8.507 +                textOut.flushBuffer();
   8.508 +                charOut.flushBuffer();
   8.509 +                if (autoFlush) {
   8.510 +                    for (int i = 0; i < buf.length; i++)
   8.511 +                        if (buf[i] == '\n')
   8.512 +                            out.flush();
   8.513 +                }
   8.514 +            }
   8.515 +        }
   8.516 +        catch (InterruptedIOException x) {
   8.517 +            Thread.currentThread().interrupt();
   8.518 +        }
   8.519 +        catch (IOException x) {
   8.520 +            trouble = true;
   8.521 +        }
   8.522 +    }
   8.523 +
   8.524 +    private void write(String s) {
   8.525 +        try {
   8.526 +            synchronized (this) {
   8.527 +                ensureOpen();
   8.528 +                textOut.write(s);
   8.529 +                textOut.flushBuffer();
   8.530 +                charOut.flushBuffer();
   8.531 +                if (autoFlush && (s.indexOf('\n') >= 0))
   8.532 +                    out.flush();
   8.533 +            }
   8.534 +        }
   8.535 +        catch (InterruptedIOException x) {
   8.536 +            Thread.currentThread().interrupt();
   8.537 +        }
   8.538 +        catch (IOException x) {
   8.539 +            trouble = true;
   8.540 +        }
   8.541 +    }
   8.542 +
   8.543 +    private void newLine() {
   8.544 +        try {
   8.545 +            synchronized (this) {
   8.546 +                ensureOpen();
   8.547 +                textOut.newLine();
   8.548 +                textOut.flushBuffer();
   8.549 +                charOut.flushBuffer();
   8.550 +                if (autoFlush)
   8.551 +                    out.flush();
   8.552 +            }
   8.553 +        }
   8.554 +        catch (InterruptedIOException x) {
   8.555 +            Thread.currentThread().interrupt();
   8.556 +        }
   8.557 +        catch (IOException x) {
   8.558 +            trouble = true;
   8.559 +        }
   8.560 +    }
   8.561 +
   8.562 +    /* Methods that do not terminate lines */
   8.563 +
   8.564 +    /**
   8.565 +     * Prints a boolean value.  The string produced by <code>{@link
   8.566 +     * java.lang.String#valueOf(boolean)}</code> is translated into bytes
   8.567 +     * according to the platform's default character encoding, and these bytes
   8.568 +     * are written in exactly the manner of the
   8.569 +     * <code>{@link #write(int)}</code> method.
   8.570 +     *
   8.571 +     * @param      b   The <code>boolean</code> to be printed
   8.572 +     */
   8.573 +    public void print(boolean b) {
   8.574 +        write(b ? "true" : "false");
   8.575 +    }
   8.576 +
   8.577 +    /**
   8.578 +     * Prints a character.  The character is translated into one or more bytes
   8.579 +     * according to the platform's default character encoding, and these bytes
   8.580 +     * are written in exactly the manner of the
   8.581 +     * <code>{@link #write(int)}</code> method.
   8.582 +     *
   8.583 +     * @param      c   The <code>char</code> to be printed
   8.584 +     */
   8.585 +    public void print(char c) {
   8.586 +        write(String.valueOf(c));
   8.587 +    }
   8.588 +
   8.589 +    /**
   8.590 +     * Prints an integer.  The string produced by <code>{@link
   8.591 +     * java.lang.String#valueOf(int)}</code> is translated into bytes
   8.592 +     * according to the platform's default character encoding, and these bytes
   8.593 +     * are written in exactly the manner of the
   8.594 +     * <code>{@link #write(int)}</code> method.
   8.595 +     *
   8.596 +     * @param      i   The <code>int</code> to be printed
   8.597 +     * @see        java.lang.Integer#toString(int)
   8.598 +     */
   8.599 +    public void print(int i) {
   8.600 +        write(String.valueOf(i));
   8.601 +    }
   8.602 +
   8.603 +    /**
   8.604 +     * Prints a long integer.  The string produced by <code>{@link
   8.605 +     * java.lang.String#valueOf(long)}</code> is translated into bytes
   8.606 +     * according to the platform's default character encoding, and these bytes
   8.607 +     * are written in exactly the manner of the
   8.608 +     * <code>{@link #write(int)}</code> method.
   8.609 +     *
   8.610 +     * @param      l   The <code>long</code> to be printed
   8.611 +     * @see        java.lang.Long#toString(long)
   8.612 +     */
   8.613 +    public void print(long l) {
   8.614 +        write(String.valueOf(l));
   8.615 +    }
   8.616 +
   8.617 +    /**
   8.618 +     * Prints a floating-point number.  The string produced by <code>{@link
   8.619 +     * java.lang.String#valueOf(float)}</code> is translated into bytes
   8.620 +     * according to the platform's default character encoding, and these bytes
   8.621 +     * are written in exactly the manner of the
   8.622 +     * <code>{@link #write(int)}</code> method.
   8.623 +     *
   8.624 +     * @param      f   The <code>float</code> to be printed
   8.625 +     * @see        java.lang.Float#toString(float)
   8.626 +     */
   8.627 +    public void print(float f) {
   8.628 +        write(String.valueOf(f));
   8.629 +    }
   8.630 +
   8.631 +    /**
   8.632 +     * Prints a double-precision floating-point number.  The string produced by
   8.633 +     * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
   8.634 +     * bytes according to the platform's default character encoding, and these
   8.635 +     * bytes are written in exactly the manner of the <code>{@link
   8.636 +     * #write(int)}</code> method.
   8.637 +     *
   8.638 +     * @param      d   The <code>double</code> to be printed
   8.639 +     * @see        java.lang.Double#toString(double)
   8.640 +     */
   8.641 +    public void print(double d) {
   8.642 +        write(String.valueOf(d));
   8.643 +    }
   8.644 +
   8.645 +    /**
   8.646 +     * Prints an array of characters.  The characters are converted into bytes
   8.647 +     * according to the platform's default character encoding, and these bytes
   8.648 +     * are written in exactly the manner of the
   8.649 +     * <code>{@link #write(int)}</code> method.
   8.650 +     *
   8.651 +     * @param      s   The array of chars to be printed
   8.652 +     *
   8.653 +     * @throws  NullPointerException  If <code>s</code> is <code>null</code>
   8.654 +     */
   8.655 +    public void print(char s[]) {
   8.656 +        write(s);
   8.657 +    }
   8.658 +
   8.659 +    /**
   8.660 +     * Prints a string.  If the argument is <code>null</code> then the string
   8.661 +     * <code>"null"</code> is printed.  Otherwise, the string's characters are
   8.662 +     * converted into bytes according to the platform's default character
   8.663 +     * encoding, and these bytes are written in exactly the manner of the
   8.664 +     * <code>{@link #write(int)}</code> method.
   8.665 +     *
   8.666 +     * @param      s   The <code>String</code> to be printed
   8.667 +     */
   8.668 +    public void print(String s) {
   8.669 +        if (s == null) {
   8.670 +            s = "null";
   8.671 +        }
   8.672 +        write(s);
   8.673 +    }
   8.674 +
   8.675 +    /**
   8.676 +     * Prints an object.  The string produced by the <code>{@link
   8.677 +     * java.lang.String#valueOf(Object)}</code> method is translated into bytes
   8.678 +     * according to the platform's default character encoding, and these bytes
   8.679 +     * are written in exactly the manner of the
   8.680 +     * <code>{@link #write(int)}</code> method.
   8.681 +     *
   8.682 +     * @param      obj   The <code>Object</code> to be printed
   8.683 +     * @see        java.lang.Object#toString()
   8.684 +     */
   8.685 +    public void print(Object obj) {
   8.686 +        write(String.valueOf(obj));
   8.687 +    }
   8.688 +
   8.689 +
   8.690 +    /* Methods that do terminate lines */
   8.691 +
   8.692 +    /**
   8.693 +     * Terminates the current line by writing the line separator string.  The
   8.694 +     * line separator string is defined by the system property
   8.695 +     * <code>line.separator</code>, and is not necessarily a single newline
   8.696 +     * character (<code>'\n'</code>).
   8.697 +     */
   8.698 +    public void println() {
   8.699 +        newLine();
   8.700 +    }
   8.701 +
   8.702 +    /**
   8.703 +     * Prints a boolean and then terminate the line.  This method behaves as
   8.704 +     * though it invokes <code>{@link #print(boolean)}</code> and then
   8.705 +     * <code>{@link #println()}</code>.
   8.706 +     *
   8.707 +     * @param x  The <code>boolean</code> to be printed
   8.708 +     */
   8.709 +    public void println(boolean x) {
   8.710 +        synchronized (this) {
   8.711 +            print(x);
   8.712 +            newLine();
   8.713 +        }
   8.714 +    }
   8.715 +
   8.716 +    /**
   8.717 +     * Prints a character and then terminate the line.  This method behaves as
   8.718 +     * though it invokes <code>{@link #print(char)}</code> and then
   8.719 +     * <code>{@link #println()}</code>.
   8.720 +     *
   8.721 +     * @param x  The <code>char</code> to be printed.
   8.722 +     */
   8.723 +    public void println(char x) {
   8.724 +        synchronized (this) {
   8.725 +            print(x);
   8.726 +            newLine();
   8.727 +        }
   8.728 +    }
   8.729 +
   8.730 +    /**
   8.731 +     * Prints an integer and then terminate the line.  This method behaves as
   8.732 +     * though it invokes <code>{@link #print(int)}</code> and then
   8.733 +     * <code>{@link #println()}</code>.
   8.734 +     *
   8.735 +     * @param x  The <code>int</code> to be printed.
   8.736 +     */
   8.737 +    public void println(int x) {
   8.738 +        synchronized (this) {
   8.739 +            print(x);
   8.740 +            newLine();
   8.741 +        }
   8.742 +    }
   8.743 +
   8.744 +    /**
   8.745 +     * Prints a long and then terminate the line.  This method behaves as
   8.746 +     * though it invokes <code>{@link #print(long)}</code> and then
   8.747 +     * <code>{@link #println()}</code>.
   8.748 +     *
   8.749 +     * @param x  a The <code>long</code> to be printed.
   8.750 +     */
   8.751 +    public void println(long x) {
   8.752 +        synchronized (this) {
   8.753 +            print(x);
   8.754 +            newLine();
   8.755 +        }
   8.756 +    }
   8.757 +
   8.758 +    /**
   8.759 +     * Prints a float and then terminate the line.  This method behaves as
   8.760 +     * though it invokes <code>{@link #print(float)}</code> and then
   8.761 +     * <code>{@link #println()}</code>.
   8.762 +     *
   8.763 +     * @param x  The <code>float</code> to be printed.
   8.764 +     */
   8.765 +    public void println(float x) {
   8.766 +        synchronized (this) {
   8.767 +            print(x);
   8.768 +            newLine();
   8.769 +        }
   8.770 +    }
   8.771 +
   8.772 +    /**
   8.773 +     * Prints a double and then terminate the line.  This method behaves as
   8.774 +     * though it invokes <code>{@link #print(double)}</code> and then
   8.775 +     * <code>{@link #println()}</code>.
   8.776 +     *
   8.777 +     * @param x  The <code>double</code> to be printed.
   8.778 +     */
   8.779 +    public void println(double x) {
   8.780 +        synchronized (this) {
   8.781 +            print(x);
   8.782 +            newLine();
   8.783 +        }
   8.784 +    }
   8.785 +
   8.786 +    /**
   8.787 +     * Prints an array of characters and then terminate the line.  This method
   8.788 +     * behaves as though it invokes <code>{@link #print(char[])}</code> and
   8.789 +     * then <code>{@link #println()}</code>.
   8.790 +     *
   8.791 +     * @param x  an array of chars to print.
   8.792 +     */
   8.793 +    public void println(char x[]) {
   8.794 +        synchronized (this) {
   8.795 +            print(x);
   8.796 +            newLine();
   8.797 +        }
   8.798 +    }
   8.799 +
   8.800 +    /**
   8.801 +     * Prints a String and then terminate the line.  This method behaves as
   8.802 +     * though it invokes <code>{@link #print(String)}</code> and then
   8.803 +     * <code>{@link #println()}</code>.
   8.804 +     *
   8.805 +     * @param x  The <code>String</code> to be printed.
   8.806 +     */
   8.807 +    public void println(String x) {
   8.808 +        synchronized (this) {
   8.809 +            print(x);
   8.810 +            newLine();
   8.811 +        }
   8.812 +    }
   8.813 +
   8.814 +    /**
   8.815 +     * Prints an Object and then terminate the line.  This method calls
   8.816 +     * at first String.valueOf(x) to get the printed object's string value,
   8.817 +     * then behaves as
   8.818 +     * though it invokes <code>{@link #print(String)}</code> and then
   8.819 +     * <code>{@link #println()}</code>.
   8.820 +     *
   8.821 +     * @param x  The <code>Object</code> to be printed.
   8.822 +     */
   8.823 +    public void println(Object x) {
   8.824 +        String s = String.valueOf(x);
   8.825 +        synchronized (this) {
   8.826 +            print(s);
   8.827 +            newLine();
   8.828 +        }
   8.829 +    }
   8.830 +
   8.831 +
   8.832 +    /**
   8.833 +     * A convenience method to write a formatted string to this output stream
   8.834 +     * using the specified format string and arguments.
   8.835 +     *
   8.836 +     * <p> An invocation of this method of the form <tt>out.printf(format,
   8.837 +     * args)</tt> behaves in exactly the same way as the invocation
   8.838 +     *
   8.839 +     * <pre>
   8.840 +     *     out.format(format, args) </pre>
   8.841 +     *
   8.842 +     * @param  format
   8.843 +     *         A format string as described in <a
   8.844 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>
   8.845 +     *
   8.846 +     * @param  args
   8.847 +     *         Arguments referenced by the format specifiers in the format
   8.848 +     *         string.  If there are more arguments than format specifiers, the
   8.849 +     *         extra arguments are ignored.  The number of arguments is
   8.850 +     *         variable and may be zero.  The maximum number of arguments is
   8.851 +     *         limited by the maximum dimension of a Java array as defined by
   8.852 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   8.853 +     *         The behaviour on a
   8.854 +     *         <tt>null</tt> argument depends on the <a
   8.855 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   8.856 +     *
   8.857 +     * @throws  IllegalFormatException
   8.858 +     *          If a format string contains an illegal syntax, a format
   8.859 +     *          specifier that is incompatible with the given arguments,
   8.860 +     *          insufficient arguments given the format string, or other
   8.861 +     *          illegal conditions.  For specification of all possible
   8.862 +     *          formatting errors, see the <a
   8.863 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   8.864 +     *          formatter class specification.
   8.865 +     *
   8.866 +     * @throws  NullPointerException
   8.867 +     *          If the <tt>format</tt> is <tt>null</tt>
   8.868 +     *
   8.869 +     * @return  This output stream
   8.870 +     *
   8.871 +     * @since  1.5
   8.872 +     */
   8.873 +    public PrintStream printf(String format, Object ... args) {
   8.874 +        return format(format, args);
   8.875 +    }
   8.876 +
   8.877 +    /**
   8.878 +     * A convenience method to write a formatted string to this output stream
   8.879 +     * using the specified format string and arguments.
   8.880 +     *
   8.881 +     * <p> An invocation of this method of the form <tt>out.printf(l, format,
   8.882 +     * args)</tt> behaves in exactly the same way as the invocation
   8.883 +     *
   8.884 +     * <pre>
   8.885 +     *     out.format(l, format, args) </pre>
   8.886 +     *
   8.887 +     * @param  l
   8.888 +     *         The {@linkplain java.util.Locale locale} to apply during
   8.889 +     *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
   8.890 +     *         is applied.
   8.891 +     *
   8.892 +     * @param  format
   8.893 +     *         A format string as described in <a
   8.894 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>
   8.895 +     *
   8.896 +     * @param  args
   8.897 +     *         Arguments referenced by the format specifiers in the format
   8.898 +     *         string.  If there are more arguments than format specifiers, the
   8.899 +     *         extra arguments are ignored.  The number of arguments is
   8.900 +     *         variable and may be zero.  The maximum number of arguments is
   8.901 +     *         limited by the maximum dimension of a Java array as defined by
   8.902 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   8.903 +     *         The behaviour on a
   8.904 +     *         <tt>null</tt> argument depends on the <a
   8.905 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   8.906 +     *
   8.907 +     * @throws  IllegalFormatException
   8.908 +     *          If a format string contains an illegal syntax, a format
   8.909 +     *          specifier that is incompatible with the given arguments,
   8.910 +     *          insufficient arguments given the format string, or other
   8.911 +     *          illegal conditions.  For specification of all possible
   8.912 +     *          formatting errors, see the <a
   8.913 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   8.914 +     *          formatter class specification.
   8.915 +     *
   8.916 +     * @throws  NullPointerException
   8.917 +     *          If the <tt>format</tt> is <tt>null</tt>
   8.918 +     *
   8.919 +     * @return  This output stream
   8.920 +     *
   8.921 +     * @since  1.5
   8.922 +     */
   8.923 +    public PrintStream printf(Locale l, String format, Object ... args) {
   8.924 +        return format(l, format, args);
   8.925 +    }
   8.926 +
   8.927 +    /**
   8.928 +     * Writes a formatted string to this output stream using the specified
   8.929 +     * format string and arguments.
   8.930 +     *
   8.931 +     * <p> The locale always used is the one returned by {@link
   8.932 +     * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
   8.933 +     * previous invocations of other formatting methods on this object.
   8.934 +     *
   8.935 +     * @param  format
   8.936 +     *         A format string as described in <a
   8.937 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>
   8.938 +     *
   8.939 +     * @param  args
   8.940 +     *         Arguments referenced by the format specifiers in the format
   8.941 +     *         string.  If there are more arguments than format specifiers, the
   8.942 +     *         extra arguments are ignored.  The number of arguments is
   8.943 +     *         variable and may be zero.  The maximum number of arguments is
   8.944 +     *         limited by the maximum dimension of a Java array as defined by
   8.945 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   8.946 +     *         The behaviour on a
   8.947 +     *         <tt>null</tt> argument depends on the <a
   8.948 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   8.949 +     *
   8.950 +     * @throws  IllegalFormatException
   8.951 +     *          If a format string contains an illegal syntax, a format
   8.952 +     *          specifier that is incompatible with the given arguments,
   8.953 +     *          insufficient arguments given the format string, or other
   8.954 +     *          illegal conditions.  For specification of all possible
   8.955 +     *          formatting errors, see the <a
   8.956 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   8.957 +     *          formatter class specification.
   8.958 +     *
   8.959 +     * @throws  NullPointerException
   8.960 +     *          If the <tt>format</tt> is <tt>null</tt>
   8.961 +     *
   8.962 +     * @return  This output stream
   8.963 +     *
   8.964 +     * @since  1.5
   8.965 +     */
   8.966 +    public PrintStream format(String format, Object ... args) {
   8.967 +        try {
   8.968 +            synchronized (this) {
   8.969 +                ensureOpen();
   8.970 +                if ((formatter == null)
   8.971 +                    || (formatter.locale() != Locale.getDefault()))
   8.972 +                    formatter = new Formatter((Appendable) this);
   8.973 +                formatter.format(Locale.getDefault(), format, args);
   8.974 +            }
   8.975 +        } catch (InterruptedIOException x) {
   8.976 +            Thread.currentThread().interrupt();
   8.977 +        } catch (IOException x) {
   8.978 +            trouble = true;
   8.979 +        }
   8.980 +        return this;
   8.981 +    }
   8.982 +
   8.983 +    /**
   8.984 +     * Writes a formatted string to this output stream using the specified
   8.985 +     * format string and arguments.
   8.986 +     *
   8.987 +     * @param  l
   8.988 +     *         The {@linkplain java.util.Locale locale} to apply during
   8.989 +     *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
   8.990 +     *         is applied.
   8.991 +     *
   8.992 +     * @param  format
   8.993 +     *         A format string as described in <a
   8.994 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>
   8.995 +     *
   8.996 +     * @param  args
   8.997 +     *         Arguments referenced by the format specifiers in the format
   8.998 +     *         string.  If there are more arguments than format specifiers, the
   8.999 +     *         extra arguments are ignored.  The number of arguments is
  8.1000 +     *         variable and may be zero.  The maximum number of arguments is
  8.1001 +     *         limited by the maximum dimension of a Java array as defined by
  8.1002 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
  8.1003 +     *         The behaviour on a
  8.1004 +     *         <tt>null</tt> argument depends on the <a
  8.1005 +     *         href="../util/Formatter.html#syntax">conversion</a>.
  8.1006 +     *
  8.1007 +     * @throws  IllegalFormatException
  8.1008 +     *          If a format string contains an illegal syntax, a format
  8.1009 +     *          specifier that is incompatible with the given arguments,
  8.1010 +     *          insufficient arguments given the format string, or other
  8.1011 +     *          illegal conditions.  For specification of all possible
  8.1012 +     *          formatting errors, see the <a
  8.1013 +     *          href="../util/Formatter.html#detail">Details</a> section of the
  8.1014 +     *          formatter class specification.
  8.1015 +     *
  8.1016 +     * @throws  NullPointerException
  8.1017 +     *          If the <tt>format</tt> is <tt>null</tt>
  8.1018 +     *
  8.1019 +     * @return  This output stream
  8.1020 +     *
  8.1021 +     * @since  1.5
  8.1022 +     */
  8.1023 +    public PrintStream format(Locale l, String format, Object ... args) {
  8.1024 +        try {
  8.1025 +            synchronized (this) {
  8.1026 +                ensureOpen();
  8.1027 +                if ((formatter == null)
  8.1028 +                    || (formatter.locale() != l))
  8.1029 +                    formatter = new Formatter(this, l);
  8.1030 +                formatter.format(l, format, args);
  8.1031 +            }
  8.1032 +        } catch (InterruptedIOException x) {
  8.1033 +            Thread.currentThread().interrupt();
  8.1034 +        } catch (IOException x) {
  8.1035 +            trouble = true;
  8.1036 +        }
  8.1037 +        return this;
  8.1038 +    }
  8.1039 +
  8.1040 +    /**
  8.1041 +     * Appends the specified character sequence to this output stream.
  8.1042 +     *
  8.1043 +     * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
  8.1044 +     * behaves in exactly the same way as the invocation
  8.1045 +     *
  8.1046 +     * <pre>
  8.1047 +     *     out.print(csq.toString()) </pre>
  8.1048 +     *
  8.1049 +     * <p> Depending on the specification of <tt>toString</tt> for the
  8.1050 +     * character sequence <tt>csq</tt>, the entire sequence may not be
  8.1051 +     * appended.  For instance, invoking then <tt>toString</tt> method of a
  8.1052 +     * character buffer will return a subsequence whose content depends upon
  8.1053 +     * the buffer's position and limit.
  8.1054 +     *
  8.1055 +     * @param  csq
  8.1056 +     *         The character sequence to append.  If <tt>csq</tt> is
  8.1057 +     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
  8.1058 +     *         appended to this output stream.
  8.1059 +     *
  8.1060 +     * @return  This output stream
  8.1061 +     *
  8.1062 +     * @since  1.5
  8.1063 +     */
  8.1064 +    public PrintStream append(CharSequence csq) {
  8.1065 +        if (csq == null)
  8.1066 +            print("null");
  8.1067 +        else
  8.1068 +            print(csq.toString());
  8.1069 +        return this;
  8.1070 +    }
  8.1071 +
  8.1072 +    /**
  8.1073 +     * Appends a subsequence of the specified character sequence to this output
  8.1074 +     * stream.
  8.1075 +     *
  8.1076 +     * <p> An invocation of this method of the form <tt>out.append(csq, start,
  8.1077 +     * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
  8.1078 +     * exactly the same way as the invocation
  8.1079 +     *
  8.1080 +     * <pre>
  8.1081 +     *     out.print(csq.subSequence(start, end).toString()) </pre>
  8.1082 +     *
  8.1083 +     * @param  csq
  8.1084 +     *         The character sequence from which a subsequence will be
  8.1085 +     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
  8.1086 +     *         will be appended as if <tt>csq</tt> contained the four
  8.1087 +     *         characters <tt>"null"</tt>.
  8.1088 +     *
  8.1089 +     * @param  start
  8.1090 +     *         The index of the first character in the subsequence
  8.1091 +     *
  8.1092 +     * @param  end
  8.1093 +     *         The index of the character following the last character in the
  8.1094 +     *         subsequence
  8.1095 +     *
  8.1096 +     * @return  This output stream
  8.1097 +     *
  8.1098 +     * @throws  IndexOutOfBoundsException
  8.1099 +     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
  8.1100 +     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
  8.1101 +     *          <tt>csq.length()</tt>
  8.1102 +     *
  8.1103 +     * @since  1.5
  8.1104 +     */
  8.1105 +    public PrintStream append(CharSequence csq, int start, int end) {
  8.1106 +        CharSequence cs = (csq == null ? "null" : csq);
  8.1107 +        write(cs.subSequence(start, end).toString());
  8.1108 +        return this;
  8.1109 +    }
  8.1110 +
  8.1111 +    /**
  8.1112 +     * Appends the specified character to this output stream.
  8.1113 +     *
  8.1114 +     * <p> An invocation of this method of the form <tt>out.append(c)</tt>
  8.1115 +     * behaves in exactly the same way as the invocation
  8.1116 +     *
  8.1117 +     * <pre>
  8.1118 +     *     out.print(c) </pre>
  8.1119 +     *
  8.1120 +     * @param  c
  8.1121 +     *         The 16-bit character to append
  8.1122 +     *
  8.1123 +     * @return  This output stream
  8.1124 +     *
  8.1125 +     * @since  1.5
  8.1126 +     */
  8.1127 +    public PrintStream append(char c) {
  8.1128 +        print(c);
  8.1129 +        return this;
  8.1130 +    }
  8.1131 +
  8.1132 +}
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/rt/emul/compact/src/main/java/java/io/PrintWriter.java	Sat Sep 07 13:55:09 2013 +0200
     9.3 @@ -0,0 +1,1066 @@
     9.4 +/*
     9.5 + * Copyright (c) 1996, 2011, 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.io;
    9.30 +
    9.31 +import java.util.Objects;
    9.32 +import java.util.Formatter;
    9.33 +import java.util.Locale;
    9.34 +import java.nio.charset.Charset;
    9.35 +import java.nio.charset.IllegalCharsetNameException;
    9.36 +import java.nio.charset.UnsupportedCharsetException;
    9.37 +
    9.38 +/**
    9.39 + * Prints formatted representations of objects to a text-output stream.  This
    9.40 + * class implements all of the <tt>print</tt> methods found in {@link
    9.41 + * PrintStream}.  It does not contain methods for writing raw bytes, for which
    9.42 + * a program should use unencoded byte streams.
    9.43 + *
    9.44 + * <p> Unlike the {@link PrintStream} class, if automatic flushing is enabled
    9.45 + * it will be done only when one of the <tt>println</tt>, <tt>printf</tt>, or
    9.46 + * <tt>format</tt> methods is invoked, rather than whenever a newline character
    9.47 + * happens to be output.  These methods use the platform's own notion of line
    9.48 + * separator rather than the newline character.
    9.49 + *
    9.50 + * <p> Methods in this class never throw I/O exceptions, although some of its
    9.51 + * constructors may.  The client may inquire as to whether any errors have
    9.52 + * occurred by invoking {@link #checkError checkError()}.
    9.53 + *
    9.54 + * @author      Frank Yellin
    9.55 + * @author      Mark Reinhold
    9.56 + * @since       JDK1.1
    9.57 + */
    9.58 +
    9.59 +public class PrintWriter extends Writer {
    9.60 +
    9.61 +    /**
    9.62 +     * The underlying character-output stream of this
    9.63 +     * <code>PrintWriter</code>.
    9.64 +     *
    9.65 +     * @since 1.2
    9.66 +     */
    9.67 +    protected Writer out;
    9.68 +
    9.69 +    private final boolean autoFlush;
    9.70 +    private boolean trouble = false;
    9.71 +    private Formatter formatter;
    9.72 +    private PrintStream psOut = null;
    9.73 +
    9.74 +    /**
    9.75 +     * Line separator string.  This is the value of the line.separator
    9.76 +     * property at the moment that the stream was created.
    9.77 +     */
    9.78 +    private final String lineSeparator;
    9.79 +
    9.80 +    /**
    9.81 +     * Returns a charset object for the given charset name.
    9.82 +     * @throws NullPointerException          is csn is null
    9.83 +     * @throws UnsupportedEncodingException  if the charset is not supported
    9.84 +     */
    9.85 +    private static Charset toCharset(String csn)
    9.86 +        throws UnsupportedEncodingException
    9.87 +    {
    9.88 +        Objects.requireNonNull(csn, "charsetName");
    9.89 +        try {
    9.90 +            return Charset.forName(csn);
    9.91 +        } catch (IllegalCharsetNameException|UnsupportedCharsetException unused) {
    9.92 +            // UnsupportedEncodingException should be thrown
    9.93 +            throw new UnsupportedEncodingException(csn);
    9.94 +        }
    9.95 +    }
    9.96 +
    9.97 +    /**
    9.98 +     * Creates a new PrintWriter, without automatic line flushing.
    9.99 +     *
   9.100 +     * @param  out        A character-output stream
   9.101 +     */
   9.102 +    public PrintWriter (Writer out) {
   9.103 +        this(out, false);
   9.104 +    }
   9.105 +
   9.106 +    /**
   9.107 +     * Creates a new PrintWriter.
   9.108 +     *
   9.109 +     * @param  out        A character-output stream
   9.110 +     * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
   9.111 +     *                    <tt>printf</tt>, or <tt>format</tt> methods will
   9.112 +     *                    flush the output buffer
   9.113 +     */
   9.114 +    public PrintWriter(Writer out,
   9.115 +                       boolean autoFlush) {
   9.116 +        super(out);
   9.117 +        this.out = out;
   9.118 +        this.autoFlush = autoFlush;
   9.119 +        lineSeparator = java.security.AccessController.doPrivileged(
   9.120 +            new sun.security.action.GetPropertyAction("line.separator"));
   9.121 +    }
   9.122 +
   9.123 +    /**
   9.124 +     * Creates a new PrintWriter, without automatic line flushing, from an
   9.125 +     * existing OutputStream.  This convenience constructor creates the
   9.126 +     * necessary intermediate OutputStreamWriter, which will convert characters
   9.127 +     * into bytes using the default character encoding.
   9.128 +     *
   9.129 +     * @param  out        An output stream
   9.130 +     *
   9.131 +     * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
   9.132 +     */
   9.133 +    public PrintWriter(OutputStream out) {
   9.134 +        this(out, false);
   9.135 +    }
   9.136 +
   9.137 +    /**
   9.138 +     * Creates a new PrintWriter from an existing OutputStream.  This
   9.139 +     * convenience constructor creates the necessary intermediate
   9.140 +     * OutputStreamWriter, which will convert characters into bytes using the
   9.141 +     * default character encoding.
   9.142 +     *
   9.143 +     * @param  out        An output stream
   9.144 +     * @param  autoFlush  A boolean; if true, the <tt>println</tt>,
   9.145 +     *                    <tt>printf</tt>, or <tt>format</tt> methods will
   9.146 +     *                    flush the output buffer
   9.147 +     *
   9.148 +     * @see java.io.OutputStreamWriter#OutputStreamWriter(java.io.OutputStream)
   9.149 +     */
   9.150 +    public PrintWriter(OutputStream out, boolean autoFlush) {
   9.151 +        this(new BufferedWriter(new OutputStreamWriter(out)), autoFlush);
   9.152 +
   9.153 +        // save print stream for error propagation
   9.154 +        if (out instanceof java.io.PrintStream) {
   9.155 +            psOut = (PrintStream) out;
   9.156 +        }
   9.157 +    }
   9.158 +
   9.159 +    /**
   9.160 +     * Creates a new PrintWriter, without automatic line flushing, with the
   9.161 +     * specified file name.  This convenience constructor creates the necessary
   9.162 +     * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
   9.163 +     * which will encode characters using the {@linkplain
   9.164 +     * java.nio.charset.Charset#defaultCharset() default charset} for this
   9.165 +     * instance of the Java virtual machine.
   9.166 +     *
   9.167 +     * @param  fileName
   9.168 +     *         The name of the file to use as the destination of this writer.
   9.169 +     *         If the file exists then it will be truncated to zero size;
   9.170 +     *         otherwise, a new file will be created.  The output will be
   9.171 +     *         written to the file and is buffered.
   9.172 +     *
   9.173 +     * @throws  FileNotFoundException
   9.174 +     *          If the given string does not denote an existing, writable
   9.175 +     *          regular file and a new regular file of that name cannot be
   9.176 +     *          created, or if some other error occurs while opening or
   9.177 +     *          creating the file
   9.178 +     *
   9.179 +     * @throws  SecurityException
   9.180 +     *          If a security manager is present and {@link
   9.181 +     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   9.182 +     *          access to the file
   9.183 +     *
   9.184 +     * @since  1.5
   9.185 +     */
   9.186 +    public PrintWriter(String fileName) throws FileNotFoundException {
   9.187 +        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
   9.188 +             false);
   9.189 +    }
   9.190 +
   9.191 +    /* Private constructor */
   9.192 +    private PrintWriter(Charset charset, File file)
   9.193 +        throws FileNotFoundException
   9.194 +    {
   9.195 +        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset)),
   9.196 +             false);
   9.197 +    }
   9.198 +
   9.199 +    /**
   9.200 +     * Creates a new PrintWriter, without automatic line flushing, with the
   9.201 +     * specified file name and charset.  This convenience constructor creates
   9.202 +     * the necessary intermediate {@link java.io.OutputStreamWriter
   9.203 +     * OutputStreamWriter}, which will encode characters using the provided
   9.204 +     * charset.
   9.205 +     *
   9.206 +     * @param  fileName
   9.207 +     *         The name of the file to use as the destination of this writer.
   9.208 +     *         If the file exists then it will be truncated to zero size;
   9.209 +     *         otherwise, a new file will be created.  The output will be
   9.210 +     *         written to the file and is buffered.
   9.211 +     *
   9.212 +     * @param  csn
   9.213 +     *         The name of a supported {@linkplain java.nio.charset.Charset
   9.214 +     *         charset}
   9.215 +     *
   9.216 +     * @throws  FileNotFoundException
   9.217 +     *          If the given string does not denote an existing, writable
   9.218 +     *          regular file and a new regular file of that name cannot be
   9.219 +     *          created, or if some other error occurs while opening or
   9.220 +     *          creating the file
   9.221 +     *
   9.222 +     * @throws  SecurityException
   9.223 +     *          If a security manager is present and {@link
   9.224 +     *          SecurityManager#checkWrite checkWrite(fileName)} denies write
   9.225 +     *          access to the file
   9.226 +     *
   9.227 +     * @throws  UnsupportedEncodingException
   9.228 +     *          If the named charset is not supported
   9.229 +     *
   9.230 +     * @since  1.5
   9.231 +     */
   9.232 +    public PrintWriter(String fileName, String csn)
   9.233 +        throws FileNotFoundException, UnsupportedEncodingException
   9.234 +    {
   9.235 +        this(toCharset(csn), new File(fileName));
   9.236 +    }
   9.237 +
   9.238 +    /**
   9.239 +     * Creates a new PrintWriter, without automatic line flushing, with the
   9.240 +     * specified file.  This convenience constructor creates the necessary
   9.241 +     * intermediate {@link java.io.OutputStreamWriter OutputStreamWriter},
   9.242 +     * which will encode characters using the {@linkplain
   9.243 +     * java.nio.charset.Charset#defaultCharset() default charset} for this
   9.244 +     * instance of the Java virtual machine.
   9.245 +     *
   9.246 +     * @param  file
   9.247 +     *         The file to use as the destination of this writer.  If the file
   9.248 +     *         exists then it will be truncated to zero size; otherwise, a new
   9.249 +     *         file will be created.  The output will be written to the file
   9.250 +     *         and is buffered.
   9.251 +     *
   9.252 +     * @throws  FileNotFoundException
   9.253 +     *          If the given file object does not denote an existing, writable
   9.254 +     *          regular file and a new regular file of that name cannot be
   9.255 +     *          created, or if some other error occurs while opening or
   9.256 +     *          creating the file
   9.257 +     *
   9.258 +     * @throws  SecurityException
   9.259 +     *          If a security manager is present and {@link
   9.260 +     *          SecurityManager#checkWrite checkWrite(file.getPath())}
   9.261 +     *          denies write access to the file
   9.262 +     *
   9.263 +     * @since  1.5
   9.264 +     */
   9.265 +    public PrintWriter(File file) throws FileNotFoundException {
   9.266 +        this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file))),
   9.267 +             false);
   9.268 +    }
   9.269 +
   9.270 +    /**
   9.271 +     * Creates a new PrintWriter, without automatic line flushing, with the
   9.272 +     * specified file and charset.  This convenience constructor creates the
   9.273 +     * necessary intermediate {@link java.io.OutputStreamWriter
   9.274 +     * OutputStreamWriter}, which will encode characters using the provided
   9.275 +     * charset.
   9.276 +     *
   9.277 +     * @param  file
   9.278 +     *         The file to use as the destination of this writer.  If the file
   9.279 +     *         exists then it will be truncated to zero size; otherwise, a new
   9.280 +     *         file will be created.  The output will be written to the file
   9.281 +     *         and is buffered.
   9.282 +     *
   9.283 +     * @param  csn
   9.284 +     *         The name of a supported {@linkplain java.nio.charset.Charset
   9.285 +     *         charset}
   9.286 +     *
   9.287 +     * @throws  FileNotFoundException
   9.288 +     *          If the given file object does not denote an existing, writable
   9.289 +     *          regular file and a new regular file of that name cannot be
   9.290 +     *          created, or if some other error occurs while opening or
   9.291 +     *          creating the file
   9.292 +     *
   9.293 +     * @throws  SecurityException
   9.294 +     *          If a security manager is present and {@link
   9.295 +     *          SecurityManager#checkWrite checkWrite(file.getPath())}
   9.296 +     *          denies write access to the file
   9.297 +     *
   9.298 +     * @throws  UnsupportedEncodingException
   9.299 +     *          If the named charset is not supported
   9.300 +     *
   9.301 +     * @since  1.5
   9.302 +     */
   9.303 +    public PrintWriter(File file, String csn)
   9.304 +        throws FileNotFoundException, UnsupportedEncodingException
   9.305 +    {
   9.306 +        this(toCharset(csn), file);
   9.307 +    }
   9.308 +
   9.309 +    /** Checks to make sure that the stream has not been closed */
   9.310 +    private void ensureOpen() throws IOException {
   9.311 +        if (out == null)
   9.312 +            throw new IOException("Stream closed");
   9.313 +    }
   9.314 +
   9.315 +    /**
   9.316 +     * Flushes the stream.
   9.317 +     * @see #checkError()
   9.318 +     */
   9.319 +    public void flush() {
   9.320 +        try {
   9.321 +            synchronized (lock) {
   9.322 +                ensureOpen();
   9.323 +                out.flush();
   9.324 +            }
   9.325 +        }
   9.326 +        catch (IOException x) {
   9.327 +            trouble = true;
   9.328 +        }
   9.329 +    }
   9.330 +
   9.331 +    /**
   9.332 +     * Closes the stream and releases any system resources associated
   9.333 +     * with it. Closing a previously closed stream has no effect.
   9.334 +     *
   9.335 +     * @see #checkError()
   9.336 +     */
   9.337 +    public void close() {
   9.338 +        try {
   9.339 +            synchronized (lock) {
   9.340 +                if (out == null)
   9.341 +                    return;
   9.342 +                out.close();
   9.343 +                out = null;
   9.344 +            }
   9.345 +        }
   9.346 +        catch (IOException x) {
   9.347 +            trouble = true;
   9.348 +        }
   9.349 +    }
   9.350 +
   9.351 +    /**
   9.352 +     * Flushes the stream if it's not closed and checks its error state.
   9.353 +     *
   9.354 +     * @return <code>true</code> if the print stream has encountered an error,
   9.355 +     *          either on the underlying output stream or during a format
   9.356 +     *          conversion.
   9.357 +     */
   9.358 +    public boolean checkError() {
   9.359 +        if (out != null) {
   9.360 +            flush();
   9.361 +        }
   9.362 +        if (out instanceof java.io.PrintWriter) {
   9.363 +            PrintWriter pw = (PrintWriter) out;
   9.364 +            return pw.checkError();
   9.365 +        } else if (psOut != null) {
   9.366 +            return psOut.checkError();
   9.367 +        }
   9.368 +        return trouble;
   9.369 +    }
   9.370 +
   9.371 +    /**
   9.372 +     * Indicates that an error has occurred.
   9.373 +     *
   9.374 +     * <p> This method will cause subsequent invocations of {@link
   9.375 +     * #checkError()} to return <tt>true</tt> until {@link
   9.376 +     * #clearError()} is invoked.
   9.377 +     */
   9.378 +    protected void setError() {
   9.379 +        trouble = true;
   9.380 +    }
   9.381 +
   9.382 +    /**
   9.383 +     * Clears the error state of this stream.
   9.384 +     *
   9.385 +     * <p> This method will cause subsequent invocations of {@link
   9.386 +     * #checkError()} to return <tt>false</tt> until another write
   9.387 +     * operation fails and invokes {@link #setError()}.
   9.388 +     *
   9.389 +     * @since 1.6
   9.390 +     */
   9.391 +    protected void clearError() {
   9.392 +        trouble = false;
   9.393 +    }
   9.394 +
   9.395 +    /*
   9.396 +     * Exception-catching, synchronized output operations,
   9.397 +     * which also implement the write() methods of Writer
   9.398 +     */
   9.399 +
   9.400 +    /**
   9.401 +     * Writes a single character.
   9.402 +     * @param c int specifying a character to be written.
   9.403 +     */
   9.404 +    public void write(int c) {
   9.405 +        try {
   9.406 +            synchronized (lock) {
   9.407 +                ensureOpen();
   9.408 +                out.write(c);
   9.409 +            }
   9.410 +        }
   9.411 +        catch (InterruptedIOException x) {
   9.412 +            Thread.currentThread().interrupt();
   9.413 +        }
   9.414 +        catch (IOException x) {
   9.415 +            trouble = true;
   9.416 +        }
   9.417 +    }
   9.418 +
   9.419 +    /**
   9.420 +     * Writes A Portion of an array of characters.
   9.421 +     * @param buf Array of characters
   9.422 +     * @param off Offset from which to start writing characters
   9.423 +     * @param len Number of characters to write
   9.424 +     */
   9.425 +    public void write(char buf[], int off, int len) {
   9.426 +        try {
   9.427 +            synchronized (lock) {
   9.428 +                ensureOpen();
   9.429 +                out.write(buf, off, len);
   9.430 +            }
   9.431 +        }
   9.432 +        catch (InterruptedIOException x) {
   9.433 +            Thread.currentThread().interrupt();
   9.434 +        }
   9.435 +        catch (IOException x) {
   9.436 +            trouble = true;
   9.437 +        }
   9.438 +    }
   9.439 +
   9.440 +    /**
   9.441 +     * Writes an array of characters.  This method cannot be inherited from the
   9.442 +     * Writer class because it must suppress I/O exceptions.
   9.443 +     * @param buf Array of characters to be written
   9.444 +     */
   9.445 +    public void write(char buf[]) {
   9.446 +        write(buf, 0, buf.length);
   9.447 +    }
   9.448 +
   9.449 +    /**
   9.450 +     * Writes a portion of a string.
   9.451 +     * @param s A String
   9.452 +     * @param off Offset from which to start writing characters
   9.453 +     * @param len Number of characters to write
   9.454 +     */
   9.455 +    public void write(String s, int off, int len) {
   9.456 +        try {
   9.457 +            synchronized (lock) {
   9.458 +                ensureOpen();
   9.459 +                out.write(s, off, len);
   9.460 +            }
   9.461 +        }
   9.462 +        catch (InterruptedIOException x) {
   9.463 +            Thread.currentThread().interrupt();
   9.464 +        }
   9.465 +        catch (IOException x) {
   9.466 +            trouble = true;
   9.467 +        }
   9.468 +    }
   9.469 +
   9.470 +    /**
   9.471 +     * Writes a string.  This method cannot be inherited from the Writer class
   9.472 +     * because it must suppress I/O exceptions.
   9.473 +     * @param s String to be written
   9.474 +     */
   9.475 +    public void write(String s) {
   9.476 +        write(s, 0, s.length());
   9.477 +    }
   9.478 +
   9.479 +    private void newLine() {
   9.480 +        try {
   9.481 +            synchronized (lock) {
   9.482 +                ensureOpen();
   9.483 +                out.write(lineSeparator);
   9.484 +                if (autoFlush)
   9.485 +                    out.flush();
   9.486 +            }
   9.487 +        }
   9.488 +        catch (InterruptedIOException x) {
   9.489 +            Thread.currentThread().interrupt();
   9.490 +        }
   9.491 +        catch (IOException x) {
   9.492 +            trouble = true;
   9.493 +        }
   9.494 +    }
   9.495 +
   9.496 +    /* Methods that do not terminate lines */
   9.497 +
   9.498 +    /**
   9.499 +     * Prints a boolean value.  The string produced by <code>{@link
   9.500 +     * java.lang.String#valueOf(boolean)}</code> is translated into bytes
   9.501 +     * according to the platform's default character encoding, and these bytes
   9.502 +     * are written in exactly the manner of the <code>{@link
   9.503 +     * #write(int)}</code> method.
   9.504 +     *
   9.505 +     * @param      b   The <code>boolean</code> to be printed
   9.506 +     */
   9.507 +    public void print(boolean b) {
   9.508 +        write(b ? "true" : "false");
   9.509 +    }
   9.510 +
   9.511 +    /**
   9.512 +     * Prints a character.  The character is translated into one or more bytes
   9.513 +     * according to the platform's default character encoding, and these bytes
   9.514 +     * are written in exactly the manner of the <code>{@link
   9.515 +     * #write(int)}</code> method.
   9.516 +     *
   9.517 +     * @param      c   The <code>char</code> to be printed
   9.518 +     */
   9.519 +    public void print(char c) {
   9.520 +        write(c);
   9.521 +    }
   9.522 +
   9.523 +    /**
   9.524 +     * Prints an integer.  The string produced by <code>{@link
   9.525 +     * java.lang.String#valueOf(int)}</code> is translated into bytes according
   9.526 +     * to the platform's default character encoding, and these bytes are
   9.527 +     * written in exactly the manner of the <code>{@link #write(int)}</code>
   9.528 +     * method.
   9.529 +     *
   9.530 +     * @param      i   The <code>int</code> to be printed
   9.531 +     * @see        java.lang.Integer#toString(int)
   9.532 +     */
   9.533 +    public void print(int i) {
   9.534 +        write(String.valueOf(i));
   9.535 +    }
   9.536 +
   9.537 +    /**
   9.538 +     * Prints a long integer.  The string produced by <code>{@link
   9.539 +     * java.lang.String#valueOf(long)}</code> is translated into bytes
   9.540 +     * according to the platform's default character encoding, and these bytes
   9.541 +     * are written in exactly the manner of the <code>{@link #write(int)}</code>
   9.542 +     * method.
   9.543 +     *
   9.544 +     * @param      l   The <code>long</code> to be printed
   9.545 +     * @see        java.lang.Long#toString(long)
   9.546 +     */
   9.547 +    public void print(long l) {
   9.548 +        write(String.valueOf(l));
   9.549 +    }
   9.550 +
   9.551 +    /**
   9.552 +     * Prints a floating-point number.  The string produced by <code>{@link
   9.553 +     * java.lang.String#valueOf(float)}</code> is translated into bytes
   9.554 +     * according to the platform's default character encoding, and these bytes
   9.555 +     * are written in exactly the manner of the <code>{@link #write(int)}</code>
   9.556 +     * method.
   9.557 +     *
   9.558 +     * @param      f   The <code>float</code> to be printed
   9.559 +     * @see        java.lang.Float#toString(float)
   9.560 +     */
   9.561 +    public void print(float f) {
   9.562 +        write(String.valueOf(f));
   9.563 +    }
   9.564 +
   9.565 +    /**
   9.566 +     * Prints a double-precision floating-point number.  The string produced by
   9.567 +     * <code>{@link java.lang.String#valueOf(double)}</code> is translated into
   9.568 +     * bytes according to the platform's default character encoding, and these
   9.569 +     * bytes are written in exactly the manner of the <code>{@link
   9.570 +     * #write(int)}</code> method.
   9.571 +     *
   9.572 +     * @param      d   The <code>double</code> to be printed
   9.573 +     * @see        java.lang.Double#toString(double)
   9.574 +     */
   9.575 +    public void print(double d) {
   9.576 +        write(String.valueOf(d));
   9.577 +    }
   9.578 +
   9.579 +    /**
   9.580 +     * Prints an array of characters.  The characters are converted into bytes
   9.581 +     * according to the platform's default character encoding, and these bytes
   9.582 +     * are written in exactly the manner of the <code>{@link #write(int)}</code>
   9.583 +     * method.
   9.584 +     *
   9.585 +     * @param      s   The array of chars to be printed
   9.586 +     *
   9.587 +     * @throws  NullPointerException  If <code>s</code> is <code>null</code>
   9.588 +     */
   9.589 +    public void print(char s[]) {
   9.590 +        write(s);
   9.591 +    }
   9.592 +
   9.593 +    /**
   9.594 +     * Prints a string.  If the argument is <code>null</code> then the string
   9.595 +     * <code>"null"</code> is printed.  Otherwise, the string's characters are
   9.596 +     * converted into bytes according to the platform's default character
   9.597 +     * encoding, and these bytes are written in exactly the manner of the
   9.598 +     * <code>{@link #write(int)}</code> method.
   9.599 +     *
   9.600 +     * @param      s   The <code>String</code> to be printed
   9.601 +     */
   9.602 +    public void print(String s) {
   9.603 +        if (s == null) {
   9.604 +            s = "null";
   9.605 +        }
   9.606 +        write(s);
   9.607 +    }
   9.608 +
   9.609 +    /**
   9.610 +     * Prints an object.  The string produced by the <code>{@link
   9.611 +     * java.lang.String#valueOf(Object)}</code> method is translated into bytes
   9.612 +     * according to the platform's default character encoding, and these bytes
   9.613 +     * are written in exactly the manner of the <code>{@link #write(int)}</code>
   9.614 +     * method.
   9.615 +     *
   9.616 +     * @param      obj   The <code>Object</code> to be printed
   9.617 +     * @see        java.lang.Object#toString()
   9.618 +     */
   9.619 +    public void print(Object obj) {
   9.620 +        write(String.valueOf(obj));
   9.621 +    }
   9.622 +
   9.623 +    /* Methods that do terminate lines */
   9.624 +
   9.625 +    /**
   9.626 +     * Terminates the current line by writing the line separator string.  The
   9.627 +     * line separator string is defined by the system property
   9.628 +     * <code>line.separator</code>, and is not necessarily a single newline
   9.629 +     * character (<code>'\n'</code>).
   9.630 +     */
   9.631 +    public void println() {
   9.632 +        newLine();
   9.633 +    }
   9.634 +
   9.635 +    /**
   9.636 +     * Prints a boolean value and then terminates the line.  This method behaves
   9.637 +     * as though it invokes <code>{@link #print(boolean)}</code> and then
   9.638 +     * <code>{@link #println()}</code>.
   9.639 +     *
   9.640 +     * @param x the <code>boolean</code> value to be printed
   9.641 +     */
   9.642 +    public void println(boolean x) {
   9.643 +        synchronized (lock) {
   9.644 +            print(x);
   9.645 +            println();
   9.646 +        }
   9.647 +    }
   9.648 +
   9.649 +    /**
   9.650 +     * Prints a character and then terminates the line.  This method behaves as
   9.651 +     * though it invokes <code>{@link #print(char)}</code> and then <code>{@link
   9.652 +     * #println()}</code>.
   9.653 +     *
   9.654 +     * @param x the <code>char</code> value to be printed
   9.655 +     */
   9.656 +    public void println(char x) {
   9.657 +        synchronized (lock) {
   9.658 +            print(x);
   9.659 +            println();
   9.660 +        }
   9.661 +    }
   9.662 +
   9.663 +    /**
   9.664 +     * Prints an integer and then terminates the line.  This method behaves as
   9.665 +     * though it invokes <code>{@link #print(int)}</code> and then <code>{@link
   9.666 +     * #println()}</code>.
   9.667 +     *
   9.668 +     * @param x the <code>int</code> value to be printed
   9.669 +     */
   9.670 +    public void println(int x) {
   9.671 +        synchronized (lock) {
   9.672 +            print(x);
   9.673 +            println();
   9.674 +        }
   9.675 +    }
   9.676 +
   9.677 +    /**
   9.678 +     * Prints a long integer and then terminates the line.  This method behaves
   9.679 +     * as though it invokes <code>{@link #print(long)}</code> and then
   9.680 +     * <code>{@link #println()}</code>.
   9.681 +     *
   9.682 +     * @param x the <code>long</code> value to be printed
   9.683 +     */
   9.684 +    public void println(long x) {
   9.685 +        synchronized (lock) {
   9.686 +            print(x);
   9.687 +            println();
   9.688 +        }
   9.689 +    }
   9.690 +
   9.691 +    /**
   9.692 +     * Prints a floating-point number and then terminates the line.  This method
   9.693 +     * behaves as though it invokes <code>{@link #print(float)}</code> and then
   9.694 +     * <code>{@link #println()}</code>.
   9.695 +     *
   9.696 +     * @param x the <code>float</code> value to be printed
   9.697 +     */
   9.698 +    public void println(float x) {
   9.699 +        synchronized (lock) {
   9.700 +            print(x);
   9.701 +            println();
   9.702 +        }
   9.703 +    }
   9.704 +
   9.705 +    /**
   9.706 +     * Prints a double-precision floating-point number and then terminates the
   9.707 +     * line.  This method behaves as though it invokes <code>{@link
   9.708 +     * #print(double)}</code> and then <code>{@link #println()}</code>.
   9.709 +     *
   9.710 +     * @param x the <code>double</code> value to be printed
   9.711 +     */
   9.712 +    public void println(double x) {
   9.713 +        synchronized (lock) {
   9.714 +            print(x);
   9.715 +            println();
   9.716 +        }
   9.717 +    }
   9.718 +
   9.719 +    /**
   9.720 +     * Prints an array of characters and then terminates the line.  This method
   9.721 +     * behaves as though it invokes <code>{@link #print(char[])}</code> and then
   9.722 +     * <code>{@link #println()}</code>.
   9.723 +     *
   9.724 +     * @param x the array of <code>char</code> values to be printed
   9.725 +     */
   9.726 +    public void println(char x[]) {
   9.727 +        synchronized (lock) {
   9.728 +            print(x);
   9.729 +            println();
   9.730 +        }
   9.731 +    }
   9.732 +
   9.733 +    /**
   9.734 +     * Prints a String and then terminates the line.  This method behaves as
   9.735 +     * though it invokes <code>{@link #print(String)}</code> and then
   9.736 +     * <code>{@link #println()}</code>.
   9.737 +     *
   9.738 +     * @param x the <code>String</code> value to be printed
   9.739 +     */
   9.740 +    public void println(String x) {
   9.741 +        synchronized (lock) {
   9.742 +            print(x);
   9.743 +            println();
   9.744 +        }
   9.745 +    }
   9.746 +
   9.747 +    /**
   9.748 +     * Prints an Object and then terminates the line.  This method calls
   9.749 +     * at first String.valueOf(x) to get the printed object's string value,
   9.750 +     * then behaves as
   9.751 +     * though it invokes <code>{@link #print(String)}</code> and then
   9.752 +     * <code>{@link #println()}</code>.
   9.753 +     *
   9.754 +     * @param x  The <code>Object</code> to be printed.
   9.755 +     */
   9.756 +    public void println(Object x) {
   9.757 +        String s = String.valueOf(x);
   9.758 +        synchronized (lock) {
   9.759 +            print(s);
   9.760 +            println();
   9.761 +        }
   9.762 +    }
   9.763 +
   9.764 +    /**
   9.765 +     * A convenience method to write a formatted string to this writer using
   9.766 +     * the specified format string and arguments.  If automatic flushing is
   9.767 +     * enabled, calls to this method will flush the output buffer.
   9.768 +     *
   9.769 +     * <p> An invocation of this method of the form <tt>out.printf(format,
   9.770 +     * args)</tt> behaves in exactly the same way as the invocation
   9.771 +     *
   9.772 +     * <pre>
   9.773 +     *     out.format(format, args) </pre>
   9.774 +     *
   9.775 +     * @param  format
   9.776 +     *         A format string as described in <a
   9.777 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>.
   9.778 +     *
   9.779 +     * @param  args
   9.780 +     *         Arguments referenced by the format specifiers in the format
   9.781 +     *         string.  If there are more arguments than format specifiers, the
   9.782 +     *         extra arguments are ignored.  The number of arguments is
   9.783 +     *         variable and may be zero.  The maximum number of arguments is
   9.784 +     *         limited by the maximum dimension of a Java array as defined by
   9.785 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   9.786 +     *         The behaviour on a
   9.787 +     *         <tt>null</tt> argument depends on the <a
   9.788 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   9.789 +     *
   9.790 +     * @throws  IllegalFormatException
   9.791 +     *          If a format string contains an illegal syntax, a format
   9.792 +     *          specifier that is incompatible with the given arguments,
   9.793 +     *          insufficient arguments given the format string, or other
   9.794 +     *          illegal conditions.  For specification of all possible
   9.795 +     *          formatting errors, see the <a
   9.796 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   9.797 +     *          formatter class specification.
   9.798 +     *
   9.799 +     * @throws  NullPointerException
   9.800 +     *          If the <tt>format</tt> is <tt>null</tt>
   9.801 +     *
   9.802 +     * @return  This writer
   9.803 +     *
   9.804 +     * @since  1.5
   9.805 +     */
   9.806 +    public PrintWriter printf(String format, Object ... args) {
   9.807 +        return format(format, args);
   9.808 +    }
   9.809 +
   9.810 +    /**
   9.811 +     * A convenience method to write a formatted string to this writer using
   9.812 +     * the specified format string and arguments.  If automatic flushing is
   9.813 +     * enabled, calls to this method will flush the output buffer.
   9.814 +     *
   9.815 +     * <p> An invocation of this method of the form <tt>out.printf(l, format,
   9.816 +     * args)</tt> behaves in exactly the same way as the invocation
   9.817 +     *
   9.818 +     * <pre>
   9.819 +     *     out.format(l, format, args) </pre>
   9.820 +     *
   9.821 +     * @param  l
   9.822 +     *         The {@linkplain java.util.Locale locale} to apply during
   9.823 +     *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
   9.824 +     *         is applied.
   9.825 +     *
   9.826 +     * @param  format
   9.827 +     *         A format string as described in <a
   9.828 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>.
   9.829 +     *
   9.830 +     * @param  args
   9.831 +     *         Arguments referenced by the format specifiers in the format
   9.832 +     *         string.  If there are more arguments than format specifiers, the
   9.833 +     *         extra arguments are ignored.  The number of arguments is
   9.834 +     *         variable and may be zero.  The maximum number of arguments is
   9.835 +     *         limited by the maximum dimension of a Java array as defined by
   9.836 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   9.837 +     *         The behaviour on a
   9.838 +     *         <tt>null</tt> argument depends on the <a
   9.839 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   9.840 +     *
   9.841 +     * @throws  IllegalFormatException
   9.842 +     *          If a format string contains an illegal syntax, a format
   9.843 +     *          specifier that is incompatible with the given arguments,
   9.844 +     *          insufficient arguments given the format string, or other
   9.845 +     *          illegal conditions.  For specification of all possible
   9.846 +     *          formatting errors, see the <a
   9.847 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   9.848 +     *          formatter class specification.
   9.849 +     *
   9.850 +     * @throws  NullPointerException
   9.851 +     *          If the <tt>format</tt> is <tt>null</tt>
   9.852 +     *
   9.853 +     * @return  This writer
   9.854 +     *
   9.855 +     * @since  1.5
   9.856 +     */
   9.857 +    public PrintWriter printf(Locale l, String format, Object ... args) {
   9.858 +        return format(l, format, args);
   9.859 +    }
   9.860 +
   9.861 +    /**
   9.862 +     * Writes a formatted string to this writer using the specified format
   9.863 +     * string and arguments.  If automatic flushing is enabled, calls to this
   9.864 +     * method will flush the output buffer.
   9.865 +     *
   9.866 +     * <p> The locale always used is the one returned by {@link
   9.867 +     * java.util.Locale#getDefault() Locale.getDefault()}, regardless of any
   9.868 +     * previous invocations of other formatting methods on this object.
   9.869 +     *
   9.870 +     * @param  format
   9.871 +     *         A format string as described in <a
   9.872 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>.
   9.873 +     *
   9.874 +     * @param  args
   9.875 +     *         Arguments referenced by the format specifiers in the format
   9.876 +     *         string.  If there are more arguments than format specifiers, the
   9.877 +     *         extra arguments are ignored.  The number of arguments is
   9.878 +     *         variable and may be zero.  The maximum number of arguments is
   9.879 +     *         limited by the maximum dimension of a Java array as defined by
   9.880 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   9.881 +     *         The behaviour on a
   9.882 +     *         <tt>null</tt> argument depends on the <a
   9.883 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   9.884 +     *
   9.885 +     * @throws  IllegalFormatException
   9.886 +     *          If a format string contains an illegal syntax, a format
   9.887 +     *          specifier that is incompatible with the given arguments,
   9.888 +     *          insufficient arguments given the format string, or other
   9.889 +     *          illegal conditions.  For specification of all possible
   9.890 +     *          formatting errors, see the <a
   9.891 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   9.892 +     *          Formatter class specification.
   9.893 +     *
   9.894 +     * @throws  NullPointerException
   9.895 +     *          If the <tt>format</tt> is <tt>null</tt>
   9.896 +     *
   9.897 +     * @return  This writer
   9.898 +     *
   9.899 +     * @since  1.5
   9.900 +     */
   9.901 +    public PrintWriter format(String format, Object ... args) {
   9.902 +        try {
   9.903 +            synchronized (lock) {
   9.904 +                ensureOpen();
   9.905 +                if ((formatter == null)
   9.906 +                    || (formatter.locale() != Locale.getDefault()))
   9.907 +                    formatter = new Formatter(this);
   9.908 +                formatter.format(Locale.getDefault(), format, args);
   9.909 +                if (autoFlush)
   9.910 +                    out.flush();
   9.911 +            }
   9.912 +        } catch (InterruptedIOException x) {
   9.913 +            Thread.currentThread().interrupt();
   9.914 +        } catch (IOException x) {
   9.915 +            trouble = true;
   9.916 +        }
   9.917 +        return this;
   9.918 +    }
   9.919 +
   9.920 +    /**
   9.921 +     * Writes a formatted string to this writer using the specified format
   9.922 +     * string and arguments.  If automatic flushing is enabled, calls to this
   9.923 +     * method will flush the output buffer.
   9.924 +     *
   9.925 +     * @param  l
   9.926 +     *         The {@linkplain java.util.Locale locale} to apply during
   9.927 +     *         formatting.  If <tt>l</tt> is <tt>null</tt> then no localization
   9.928 +     *         is applied.
   9.929 +     *
   9.930 +     * @param  format
   9.931 +     *         A format string as described in <a
   9.932 +     *         href="../util/Formatter.html#syntax">Format string syntax</a>.
   9.933 +     *
   9.934 +     * @param  args
   9.935 +     *         Arguments referenced by the format specifiers in the format
   9.936 +     *         string.  If there are more arguments than format specifiers, the
   9.937 +     *         extra arguments are ignored.  The number of arguments is
   9.938 +     *         variable and may be zero.  The maximum number of arguments is
   9.939 +     *         limited by the maximum dimension of a Java array as defined by
   9.940 +     *         <cite>The Java&trade; Virtual Machine Specification</cite>.
   9.941 +     *         The behaviour on a
   9.942 +     *         <tt>null</tt> argument depends on the <a
   9.943 +     *         href="../util/Formatter.html#syntax">conversion</a>.
   9.944 +     *
   9.945 +     * @throws  IllegalFormatException
   9.946 +     *          If a format string contains an illegal syntax, a format
   9.947 +     *          specifier that is incompatible with the given arguments,
   9.948 +     *          insufficient arguments given the format string, or other
   9.949 +     *          illegal conditions.  For specification of all possible
   9.950 +     *          formatting errors, see the <a
   9.951 +     *          href="../util/Formatter.html#detail">Details</a> section of the
   9.952 +     *          formatter class specification.
   9.953 +     *
   9.954 +     * @throws  NullPointerException
   9.955 +     *          If the <tt>format</tt> is <tt>null</tt>
   9.956 +     *
   9.957 +     * @return  This writer
   9.958 +     *
   9.959 +     * @since  1.5
   9.960 +     */
   9.961 +    public PrintWriter format(Locale l, String format, Object ... args) {
   9.962 +        try {
   9.963 +            synchronized (lock) {
   9.964 +                ensureOpen();
   9.965 +                if ((formatter == null) || (formatter.locale() != l))
   9.966 +                    formatter = new Formatter(this, l);
   9.967 +                formatter.format(l, format, args);
   9.968 +                if (autoFlush)
   9.969 +                    out.flush();
   9.970 +            }
   9.971 +        } catch (InterruptedIOException x) {
   9.972 +            Thread.currentThread().interrupt();
   9.973 +        } catch (IOException x) {
   9.974 +            trouble = true;
   9.975 +        }
   9.976 +        return this;
   9.977 +    }
   9.978 +
   9.979 +    /**
   9.980 +     * Appends the specified character sequence to this writer.
   9.981 +     *
   9.982 +     * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
   9.983 +     * behaves in exactly the same way as the invocation
   9.984 +     *
   9.985 +     * <pre>
   9.986 +     *     out.write(csq.toString()) </pre>
   9.987 +     *
   9.988 +     * <p> Depending on the specification of <tt>toString</tt> for the
   9.989 +     * character sequence <tt>csq</tt>, the entire sequence may not be
   9.990 +     * appended. For instance, invoking the <tt>toString</tt> method of a
   9.991 +     * character buffer will return a subsequence whose content depends upon
   9.992 +     * the buffer's position and limit.
   9.993 +     *
   9.994 +     * @param  csq
   9.995 +     *         The character sequence to append.  If <tt>csq</tt> is
   9.996 +     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
   9.997 +     *         appended to this writer.
   9.998 +     *
   9.999 +     * @return  This writer
  9.1000 +     *
  9.1001 +     * @since  1.5
  9.1002 +     */
  9.1003 +    public PrintWriter append(CharSequence csq) {
  9.1004 +        if (csq == null)
  9.1005 +            write("null");
  9.1006 +        else
  9.1007 +            write(csq.toString());
  9.1008 +        return this;
  9.1009 +    }
  9.1010 +
  9.1011 +    /**
  9.1012 +     * Appends a subsequence of the specified character sequence to this writer.
  9.1013 +     *
  9.1014 +     * <p> An invocation of this method of the form <tt>out.append(csq, start,
  9.1015 +     * end)</tt> when <tt>csq</tt> is not <tt>null</tt>, behaves in
  9.1016 +     * exactly the same way as the invocation
  9.1017 +     *
  9.1018 +     * <pre>
  9.1019 +     *     out.write(csq.subSequence(start, end).toString()) </pre>
  9.1020 +     *
  9.1021 +     * @param  csq
  9.1022 +     *         The character sequence from which a subsequence will be
  9.1023 +     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
  9.1024 +     *         will be appended as if <tt>csq</tt> contained the four
  9.1025 +     *         characters <tt>"null"</tt>.
  9.1026 +     *
  9.1027 +     * @param  start
  9.1028 +     *         The index of the first character in the subsequence
  9.1029 +     *
  9.1030 +     * @param  end
  9.1031 +     *         The index of the character following the last character in the
  9.1032 +     *         subsequence
  9.1033 +     *
  9.1034 +     * @return  This writer
  9.1035 +     *
  9.1036 +     * @throws  IndexOutOfBoundsException
  9.1037 +     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
  9.1038 +     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
  9.1039 +     *          <tt>csq.length()</tt>
  9.1040 +     *
  9.1041 +     * @since  1.5
  9.1042 +     */
  9.1043 +    public PrintWriter append(CharSequence csq, int start, int end) {
  9.1044 +        CharSequence cs = (csq == null ? "null" : csq);
  9.1045 +        write(cs.subSequence(start, end).toString());
  9.1046 +        return this;
  9.1047 +    }
  9.1048 +
  9.1049 +    /**
  9.1050 +     * Appends the specified character to this writer.
  9.1051 +     *
  9.1052 +     * <p> An invocation of this method of the form <tt>out.append(c)</tt>
  9.1053 +     * behaves in exactly the same way as the invocation
  9.1054 +     *
  9.1055 +     * <pre>
  9.1056 +     *     out.write(c) </pre>
  9.1057 +     *
  9.1058 +     * @param  c
  9.1059 +     *         The 16-bit character to append
  9.1060 +     *
  9.1061 +     * @return  This writer
  9.1062 +     *
  9.1063 +     * @since 1.5
  9.1064 +     */
  9.1065 +    public PrintWriter append(char c) {
  9.1066 +        write(c);
  9.1067 +        return this;
  9.1068 +    }
  9.1069 +}
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/rt/emul/compact/src/main/java/java/io/Writer.java	Sat Sep 07 13:55:09 2013 +0200
    10.3 @@ -0,0 +1,325 @@
    10.4 +/*
    10.5 + * Copyright (c) 1996, 2005, 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.io;
   10.30 +
   10.31 +
   10.32 +/**
   10.33 + * Abstract class for writing to character streams.  The only methods that a
   10.34 + * subclass must implement are write(char[], int, int), flush(), and close().
   10.35 + * Most subclasses, however, will override some of the methods defined here in
   10.36 + * order to provide higher efficiency, additional functionality, or both.
   10.37 + *
   10.38 + * @see Writer
   10.39 + * @see   BufferedWriter
   10.40 + * @see   CharArrayWriter
   10.41 + * @see   FilterWriter
   10.42 + * @see   OutputStreamWriter
   10.43 + * @see     FileWriter
   10.44 + * @see   PipedWriter
   10.45 + * @see   PrintWriter
   10.46 + * @see   StringWriter
   10.47 + * @see Reader
   10.48 + *
   10.49 + * @author      Mark Reinhold
   10.50 + * @since       JDK1.1
   10.51 + */
   10.52 +
   10.53 +public abstract class Writer implements Appendable, Closeable, Flushable {
   10.54 +
   10.55 +    /**
   10.56 +     * Temporary buffer used to hold writes of strings and single characters
   10.57 +     */
   10.58 +    private char[] writeBuffer;
   10.59 +
   10.60 +    /**
   10.61 +     * Size of writeBuffer, must be >= 1
   10.62 +     */
   10.63 +    private final int writeBufferSize = 1024;
   10.64 +
   10.65 +    /**
   10.66 +     * The object used to synchronize operations on this stream.  For
   10.67 +     * efficiency, a character-stream object may use an object other than
   10.68 +     * itself to protect critical sections.  A subclass should therefore use
   10.69 +     * the object in this field rather than <tt>this</tt> or a synchronized
   10.70 +     * method.
   10.71 +     */
   10.72 +    protected Object lock;
   10.73 +
   10.74 +    /**
   10.75 +     * Creates a new character-stream writer whose critical sections will
   10.76 +     * synchronize on the writer itself.
   10.77 +     */
   10.78 +    protected Writer() {
   10.79 +        this.lock = this;
   10.80 +    }
   10.81 +
   10.82 +    /**
   10.83 +     * Creates a new character-stream writer whose critical sections will
   10.84 +     * synchronize on the given object.
   10.85 +     *
   10.86 +     * @param  lock
   10.87 +     *         Object to synchronize on
   10.88 +     */
   10.89 +    protected Writer(Object lock) {
   10.90 +        if (lock == null) {
   10.91 +            throw new NullPointerException();
   10.92 +        }
   10.93 +        this.lock = lock;
   10.94 +    }
   10.95 +
   10.96 +    /**
   10.97 +     * Writes a single character.  The character to be written is contained in
   10.98 +     * the 16 low-order bits of the given integer value; the 16 high-order bits
   10.99 +     * are ignored.
  10.100 +     *
  10.101 +     * <p> Subclasses that intend to support efficient single-character output
  10.102 +     * should override this method.
  10.103 +     *
  10.104 +     * @param  c
  10.105 +     *         int specifying a character to be written
  10.106 +     *
  10.107 +     * @throws  IOException
  10.108 +     *          If an I/O error occurs
  10.109 +     */
  10.110 +    public void write(int c) throws IOException {
  10.111 +        synchronized (lock) {
  10.112 +            if (writeBuffer == null){
  10.113 +                writeBuffer = new char[writeBufferSize];
  10.114 +            }
  10.115 +            writeBuffer[0] = (char) c;
  10.116 +            write(writeBuffer, 0, 1);
  10.117 +        }
  10.118 +    }
  10.119 +
  10.120 +    /**
  10.121 +     * Writes an array of characters.
  10.122 +     *
  10.123 +     * @param  cbuf
  10.124 +     *         Array of characters to be written
  10.125 +     *
  10.126 +     * @throws  IOException
  10.127 +     *          If an I/O error occurs
  10.128 +     */
  10.129 +    public void write(char cbuf[]) throws IOException {
  10.130 +        write(cbuf, 0, cbuf.length);
  10.131 +    }
  10.132 +
  10.133 +    /**
  10.134 +     * Writes a portion of an array of characters.
  10.135 +     *
  10.136 +     * @param  cbuf
  10.137 +     *         Array of characters
  10.138 +     *
  10.139 +     * @param  off
  10.140 +     *         Offset from which to start writing characters
  10.141 +     *
  10.142 +     * @param  len
  10.143 +     *         Number of characters to write
  10.144 +     *
  10.145 +     * @throws  IOException
  10.146 +     *          If an I/O error occurs
  10.147 +     */
  10.148 +    abstract public void write(char cbuf[], int off, int len) throws IOException;
  10.149 +
  10.150 +    /**
  10.151 +     * Writes a string.
  10.152 +     *
  10.153 +     * @param  str
  10.154 +     *         String to be written
  10.155 +     *
  10.156 +     * @throws  IOException
  10.157 +     *          If an I/O error occurs
  10.158 +     */
  10.159 +    public void write(String str) throws IOException {
  10.160 +        write(str, 0, str.length());
  10.161 +    }
  10.162 +
  10.163 +    /**
  10.164 +     * Writes a portion of a string.
  10.165 +     *
  10.166 +     * @param  str
  10.167 +     *         A String
  10.168 +     *
  10.169 +     * @param  off
  10.170 +     *         Offset from which to start writing characters
  10.171 +     *
  10.172 +     * @param  len
  10.173 +     *         Number of characters to write
  10.174 +     *
  10.175 +     * @throws  IndexOutOfBoundsException
  10.176 +     *          If <tt>off</tt> is negative, or <tt>len</tt> is negative,
  10.177 +     *          or <tt>off+len</tt> is negative or greater than the length
  10.178 +     *          of the given string
  10.179 +     *
  10.180 +     * @throws  IOException
  10.181 +     *          If an I/O error occurs
  10.182 +     */
  10.183 +    public void write(String str, int off, int len) throws IOException {
  10.184 +        synchronized (lock) {
  10.185 +            char cbuf[];
  10.186 +            if (len <= writeBufferSize) {
  10.187 +                if (writeBuffer == null) {
  10.188 +                    writeBuffer = new char[writeBufferSize];
  10.189 +                }
  10.190 +                cbuf = writeBuffer;
  10.191 +            } else {    // Don't permanently allocate very large buffers.
  10.192 +                cbuf = new char[len];
  10.193 +            }
  10.194 +            str.getChars(off, (off + len), cbuf, 0);
  10.195 +            write(cbuf, 0, len);
  10.196 +        }
  10.197 +    }
  10.198 +
  10.199 +    /**
  10.200 +     * Appends the specified character sequence to this writer.
  10.201 +     *
  10.202 +     * <p> An invocation of this method of the form <tt>out.append(csq)</tt>
  10.203 +     * behaves in exactly the same way as the invocation
  10.204 +     *
  10.205 +     * <pre>
  10.206 +     *     out.write(csq.toString()) </pre>
  10.207 +     *
  10.208 +     * <p> Depending on the specification of <tt>toString</tt> for the
  10.209 +     * character sequence <tt>csq</tt>, the entire sequence may not be
  10.210 +     * appended. For instance, invoking the <tt>toString</tt> method of a
  10.211 +     * character buffer will return a subsequence whose content depends upon
  10.212 +     * the buffer's position and limit.
  10.213 +     *
  10.214 +     * @param  csq
  10.215 +     *         The character sequence to append.  If <tt>csq</tt> is
  10.216 +     *         <tt>null</tt>, then the four characters <tt>"null"</tt> are
  10.217 +     *         appended to this writer.
  10.218 +     *
  10.219 +     * @return  This writer
  10.220 +     *
  10.221 +     * @throws  IOException
  10.222 +     *          If an I/O error occurs
  10.223 +     *
  10.224 +     * @since  1.5
  10.225 +     */
  10.226 +    public Writer append(CharSequence csq) throws IOException {
  10.227 +        if (csq == null)
  10.228 +            write("null");
  10.229 +        else
  10.230 +            write(csq.toString());
  10.231 +        return this;
  10.232 +    }
  10.233 +
  10.234 +    /**
  10.235 +     * Appends a subsequence of the specified character sequence to this writer.
  10.236 +     * <tt>Appendable</tt>.
  10.237 +     *
  10.238 +     * <p> An invocation of this method of the form <tt>out.append(csq, start,
  10.239 +     * end)</tt> when <tt>csq</tt> is not <tt>null</tt> behaves in exactly the
  10.240 +     * same way as the invocation
  10.241 +     *
  10.242 +     * <pre>
  10.243 +     *     out.write(csq.subSequence(start, end).toString()) </pre>
  10.244 +     *
  10.245 +     * @param  csq
  10.246 +     *         The character sequence from which a subsequence will be
  10.247 +     *         appended.  If <tt>csq</tt> is <tt>null</tt>, then characters
  10.248 +     *         will be appended as if <tt>csq</tt> contained the four
  10.249 +     *         characters <tt>"null"</tt>.
  10.250 +     *
  10.251 +     * @param  start
  10.252 +     *         The index of the first character in the subsequence
  10.253 +     *
  10.254 +     * @param  end
  10.255 +     *         The index of the character following the last character in the
  10.256 +     *         subsequence
  10.257 +     *
  10.258 +     * @return  This writer
  10.259 +     *
  10.260 +     * @throws  IndexOutOfBoundsException
  10.261 +     *          If <tt>start</tt> or <tt>end</tt> are negative, <tt>start</tt>
  10.262 +     *          is greater than <tt>end</tt>, or <tt>end</tt> is greater than
  10.263 +     *          <tt>csq.length()</tt>
  10.264 +     *
  10.265 +     * @throws  IOException
  10.266 +     *          If an I/O error occurs
  10.267 +     *
  10.268 +     * @since  1.5
  10.269 +     */
  10.270 +    public Writer append(CharSequence csq, int start, int end) throws IOException {
  10.271 +        CharSequence cs = (csq == null ? "null" : csq);
  10.272 +        write(cs.subSequence(start, end).toString());
  10.273 +        return this;
  10.274 +    }
  10.275 +
  10.276 +    /**
  10.277 +     * Appends the specified character to this writer.
  10.278 +     *
  10.279 +     * <p> An invocation of this method of the form <tt>out.append(c)</tt>
  10.280 +     * behaves in exactly the same way as the invocation
  10.281 +     *
  10.282 +     * <pre>
  10.283 +     *     out.write(c) </pre>
  10.284 +     *
  10.285 +     * @param  c
  10.286 +     *         The 16-bit character to append
  10.287 +     *
  10.288 +     * @return  This writer
  10.289 +     *
  10.290 +     * @throws  IOException
  10.291 +     *          If an I/O error occurs
  10.292 +     *
  10.293 +     * @since 1.5
  10.294 +     */
  10.295 +    public Writer append(char c) throws IOException {
  10.296 +        write(c);
  10.297 +        return this;
  10.298 +    }
  10.299 +
  10.300 +    /**
  10.301 +     * Flushes the stream.  If the stream has saved any characters from the
  10.302 +     * various write() methods in a buffer, write them immediately to their
  10.303 +     * intended destination.  Then, if that destination is another character or
  10.304 +     * byte stream, flush it.  Thus one flush() invocation will flush all the
  10.305 +     * buffers in a chain of Writers and OutputStreams.
  10.306 +     *
  10.307 +     * <p> If the intended destination of this stream is an abstraction provided
  10.308 +     * by the underlying operating system, for example a file, then flushing the
  10.309 +     * stream guarantees only that bytes previously written to the stream are
  10.310 +     * passed to the operating system for writing; it does not guarantee that
  10.311 +     * they are actually written to a physical device such as a disk drive.
  10.312 +     *
  10.313 +     * @throws  IOException
  10.314 +     *          If an I/O error occurs
  10.315 +     */
  10.316 +    abstract public void flush() throws IOException;
  10.317 +
  10.318 +    /**
  10.319 +     * Closes the stream, flushing it first. Once the stream has been closed,
  10.320 +     * further write() or flush() invocations will cause an IOException to be
  10.321 +     * thrown. Closing a previously closed stream has no effect.
  10.322 +     *
  10.323 +     * @throws  IOException
  10.324 +     *          If an I/O error occurs
  10.325 +     */
  10.326 +    abstract public void close() throws IOException;
  10.327 +
  10.328 +}
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/rt/emul/compact/src/main/java/java/lang/StackOverflowError.java	Sat Sep 07 13:55:09 2013 +0200
    11.3 @@ -0,0 +1,55 @@
    11.4 +/*
    11.5 + * Copyright (c) 1994, 2008, 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.lang;
   11.30 +
   11.31 +/**
   11.32 + * Thrown when a stack overflow occurs because an application
   11.33 + * recurses too deeply.
   11.34 + *
   11.35 + * @author unascribed
   11.36 + * @since   JDK1.0
   11.37 + */
   11.38 +public
   11.39 +class StackOverflowError extends VirtualMachineError {
   11.40 +    private static final long serialVersionUID = 8609175038441759607L;
   11.41 +
   11.42 +    /**
   11.43 +     * Constructs a <code>StackOverflowError</code> with no detail message.
   11.44 +     */
   11.45 +    public StackOverflowError() {
   11.46 +        super();
   11.47 +    }
   11.48 +
   11.49 +    /**
   11.50 +     * Constructs a <code>StackOverflowError</code> with the specified
   11.51 +     * detail message.
   11.52 +     *
   11.53 +     * @param   s   the detail message.
   11.54 +     */
   11.55 +    public StackOverflowError(String s) {
   11.56 +        super(s);
   11.57 +    }
   11.58 +}
    12.1 --- a/rt/emul/compact/src/main/java/java/lang/System.java	Thu Sep 05 09:36:06 2013 +0200
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,36 +0,0 @@
    12.4 -/**
    12.5 - * Back 2 Browser Bytecode Translator
    12.6 - * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
    12.7 - *
    12.8 - * This program is free software: you can redistribute it and/or modify
    12.9 - * it under the terms of the GNU General Public License as published by
   12.10 - * the Free Software Foundation, version 2 of the License.
   12.11 - *
   12.12 - * This program is distributed in the hope that it will be useful,
   12.13 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12.14 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12.15 - * GNU General Public License for more details.
   12.16 - *
   12.17 - * You should have received a copy of the GNU General Public License
   12.18 - * along with this program. Look for COPYING file in the top folder.
   12.19 - * If not, see http://opensource.org/licenses/GPL-2.0.
   12.20 - */
   12.21 -package java.lang;
   12.22 -
   12.23 -/** Poor man's re-implementation of most important System methods.
   12.24 - *
   12.25 - * @author Jaroslav Tulach <jtulach@netbeans.org>
   12.26 - */
   12.27 -public class System {
   12.28 -    private System() {
   12.29 -    }
   12.30 -    
   12.31 -    public static void arraycopy(Object value, int srcBegin, Object dst, int dstBegin, int count) {
   12.32 -        org.apidesign.bck2brwsr.emul.lang.System.arraycopy(value, srcBegin, dst, dstBegin, count);
   12.33 -    }
   12.34 -    
   12.35 -    public static long currentTimeMillis() {
   12.36 -        return org.apidesign.bck2brwsr.emul.lang.System.currentTimeMillis();
   12.37 -    }
   12.38 -    
   12.39 -}
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/rt/emul/compact/src/main/java/java/lang/Thread.java	Sat Sep 07 13:55:09 2013 +0200
    13.3 @@ -0,0 +1,2035 @@
    13.4 +/*
    13.5 + * Copyright (c) 1994, 2011, 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.lang;
   13.30 +
   13.31 +import java.lang.ref.Reference;
   13.32 +import java.lang.ref.ReferenceQueue;
   13.33 +import java.lang.ref.WeakReference;
   13.34 +import java.security.AccessController;
   13.35 +import java.security.AccessControlContext;
   13.36 +import java.security.PrivilegedAction;
   13.37 +import java.util.Map;
   13.38 +import java.util.HashMap;
   13.39 +import java.util.concurrent.ConcurrentHashMap;
   13.40 +import java.util.concurrent.ConcurrentMap;
   13.41 +import java.util.concurrent.locks.LockSupport;
   13.42 +import sun.nio.ch.Interruptible;
   13.43 +import sun.security.util.SecurityConstants;
   13.44 +
   13.45 +
   13.46 +/**
   13.47 + * A <i>thread</i> is a thread of execution in a program. The Java
   13.48 + * Virtual Machine allows an application to have multiple threads of
   13.49 + * execution running concurrently.
   13.50 + * <p>
   13.51 + * Every thread has a priority. Threads with higher priority are
   13.52 + * executed in preference to threads with lower priority. Each thread
   13.53 + * may or may not also be marked as a daemon. When code running in
   13.54 + * some thread creates a new <code>Thread</code> object, the new
   13.55 + * thread has its priority initially set equal to the priority of the
   13.56 + * creating thread, and is a daemon thread if and only if the
   13.57 + * creating thread is a daemon.
   13.58 + * <p>
   13.59 + * When a Java Virtual Machine starts up, there is usually a single
   13.60 + * non-daemon thread (which typically calls the method named
   13.61 + * <code>main</code> of some designated class). The Java Virtual
   13.62 + * Machine continues to execute threads until either of the following
   13.63 + * occurs:
   13.64 + * <ul>
   13.65 + * <li>The <code>exit</code> method of class <code>Runtime</code> has been
   13.66 + *     called and the security manager has permitted the exit operation
   13.67 + *     to take place.
   13.68 + * <li>All threads that are not daemon threads have died, either by
   13.69 + *     returning from the call to the <code>run</code> method or by
   13.70 + *     throwing an exception that propagates beyond the <code>run</code>
   13.71 + *     method.
   13.72 + * </ul>
   13.73 + * <p>
   13.74 + * There are two ways to create a new thread of execution. One is to
   13.75 + * declare a class to be a subclass of <code>Thread</code>. This
   13.76 + * subclass should override the <code>run</code> method of class
   13.77 + * <code>Thread</code>. An instance of the subclass can then be
   13.78 + * allocated and started. For example, a thread that computes primes
   13.79 + * larger than a stated value could be written as follows:
   13.80 + * <p><hr><blockquote><pre>
   13.81 + *     class PrimeThread extends Thread {
   13.82 + *         long minPrime;
   13.83 + *         PrimeThread(long minPrime) {
   13.84 + *             this.minPrime = minPrime;
   13.85 + *         }
   13.86 + *
   13.87 + *         public void run() {
   13.88 + *             // compute primes larger than minPrime
   13.89 + *             &nbsp;.&nbsp;.&nbsp;.
   13.90 + *         }
   13.91 + *     }
   13.92 + * </pre></blockquote><hr>
   13.93 + * <p>
   13.94 + * The following code would then create a thread and start it running:
   13.95 + * <p><blockquote><pre>
   13.96 + *     PrimeThread p = new PrimeThread(143);
   13.97 + *     p.start();
   13.98 + * </pre></blockquote>
   13.99 + * <p>
  13.100 + * The other way to create a thread is to declare a class that
  13.101 + * implements the <code>Runnable</code> interface. That class then
  13.102 + * implements the <code>run</code> method. An instance of the class can
  13.103 + * then be allocated, passed as an argument when creating
  13.104 + * <code>Thread</code>, and started. The same example in this other
  13.105 + * style looks like the following:
  13.106 + * <p><hr><blockquote><pre>
  13.107 + *     class PrimeRun implements Runnable {
  13.108 + *         long minPrime;
  13.109 + *         PrimeRun(long minPrime) {
  13.110 + *             this.minPrime = minPrime;
  13.111 + *         }
  13.112 + *
  13.113 + *         public void run() {
  13.114 + *             // compute primes larger than minPrime
  13.115 + *             &nbsp;.&nbsp;.&nbsp;.
  13.116 + *         }
  13.117 + *     }
  13.118 + * </pre></blockquote><hr>
  13.119 + * <p>
  13.120 + * The following code would then create a thread and start it running:
  13.121 + * <p><blockquote><pre>
  13.122 + *     PrimeRun p = new PrimeRun(143);
  13.123 + *     new Thread(p).start();
  13.124 + * </pre></blockquote>
  13.125 + * <p>
  13.126 + * Every thread has a name for identification purposes. More than
  13.127 + * one thread may have the same name. If a name is not specified when
  13.128 + * a thread is created, a new name is generated for it.
  13.129 + * <p>
  13.130 + * Unless otherwise noted, passing a {@code null} argument to a constructor
  13.131 + * or method in this class will cause a {@link NullPointerException} to be
  13.132 + * thrown.
  13.133 + *
  13.134 + * @author  unascribed
  13.135 + * @see     Runnable
  13.136 + * @see     Runtime#exit(int)
  13.137 + * @see     #run()
  13.138 + * @see     #stop()
  13.139 + * @since   JDK1.0
  13.140 + */
  13.141 +public
  13.142 +class Thread implements Runnable {
  13.143 +    /* Make sure registerNatives is the first thing <clinit> does. */
  13.144 +    private static native void registerNatives();
  13.145 +    static {
  13.146 +        registerNatives();
  13.147 +    }
  13.148 +
  13.149 +    private char        name[];
  13.150 +    private int         priority;
  13.151 +    private Thread      threadQ;
  13.152 +    private long        eetop;
  13.153 +
  13.154 +    /* Whether or not to single_step this thread. */
  13.155 +    private boolean     single_step;
  13.156 +
  13.157 +    /* Whether or not the thread is a daemon thread. */
  13.158 +    private boolean     daemon = false;
  13.159 +
  13.160 +    /* JVM state */
  13.161 +    private boolean     stillborn = false;
  13.162 +
  13.163 +    /* What will be run. */
  13.164 +    private Runnable target;
  13.165 +
  13.166 +    /* The group of this thread */
  13.167 +    private ThreadGroup group;
  13.168 +
  13.169 +    /* The context ClassLoader for this thread */
  13.170 +    private ClassLoader contextClassLoader;
  13.171 +
  13.172 +    /* The inherited AccessControlContext of this thread */
  13.173 +    private AccessControlContext inheritedAccessControlContext;
  13.174 +
  13.175 +    /* For autonumbering anonymous threads. */
  13.176 +    private static int threadInitNumber;
  13.177 +    private static synchronized int nextThreadNum() {
  13.178 +        return threadInitNumber++;
  13.179 +    }
  13.180 +
  13.181 +    /* ThreadLocal values pertaining to this thread. This map is maintained
  13.182 +     * by the ThreadLocal class. */
  13.183 +    ThreadLocal.ThreadLocalMap threadLocals = null;
  13.184 +
  13.185 +    /*
  13.186 +     * InheritableThreadLocal values pertaining to this thread. This map is
  13.187 +     * maintained by the InheritableThreadLocal class.
  13.188 +     */
  13.189 +    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
  13.190 +
  13.191 +    /*
  13.192 +     * The requested stack size for this thread, or 0 if the creator did
  13.193 +     * not specify a stack size.  It is up to the VM to do whatever it
  13.194 +     * likes with this number; some VMs will ignore it.
  13.195 +     */
  13.196 +    private long stackSize;
  13.197 +
  13.198 +    /*
  13.199 +     * JVM-private state that persists after native thread termination.
  13.200 +     */
  13.201 +    private long nativeParkEventPointer;
  13.202 +
  13.203 +    /*
  13.204 +     * Thread ID
  13.205 +     */
  13.206 +    private long tid;
  13.207 +
  13.208 +    /* For generating thread ID */
  13.209 +    private static long threadSeqNumber;
  13.210 +
  13.211 +    /* Java thread status for tools,
  13.212 +     * initialized to indicate thread 'not yet started'
  13.213 +     */
  13.214 +
  13.215 +    private volatile int threadStatus = 0;
  13.216 +
  13.217 +
  13.218 +    private static synchronized long nextThreadID() {
  13.219 +        return ++threadSeqNumber;
  13.220 +    }
  13.221 +
  13.222 +    /**
  13.223 +     * The argument supplied to the current call to
  13.224 +     * java.util.concurrent.locks.LockSupport.park.
  13.225 +     * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
  13.226 +     * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
  13.227 +     */
  13.228 +    volatile Object parkBlocker;
  13.229 +
  13.230 +    /* The object in which this thread is blocked in an interruptible I/O
  13.231 +     * operation, if any.  The blocker's interrupt method should be invoked
  13.232 +     * after setting this thread's interrupt status.
  13.233 +     */
  13.234 +    private volatile Interruptible blocker;
  13.235 +    private final Object blockerLock = new Object();
  13.236 +
  13.237 +    /* Set the blocker field; invoked via sun.misc.SharedSecrets from java.nio code
  13.238 +     */
  13.239 +    void blockedOn(Interruptible b) {
  13.240 +        synchronized (blockerLock) {
  13.241 +            blocker = b;
  13.242 +        }
  13.243 +    }
  13.244 +
  13.245 +    /**
  13.246 +     * The minimum priority that a thread can have.
  13.247 +     */
  13.248 +    public final static int MIN_PRIORITY = 1;
  13.249 +
  13.250 +   /**
  13.251 +     * The default priority that is assigned to a thread.
  13.252 +     */
  13.253 +    public final static int NORM_PRIORITY = 5;
  13.254 +
  13.255 +    /**
  13.256 +     * The maximum priority that a thread can have.
  13.257 +     */
  13.258 +    public final static int MAX_PRIORITY = 10;
  13.259 +
  13.260 +    /**
  13.261 +     * Returns a reference to the currently executing thread object.
  13.262 +     *
  13.263 +     * @return  the currently executing thread.
  13.264 +     */
  13.265 +    public static native Thread currentThread();
  13.266 +
  13.267 +    /**
  13.268 +     * A hint to the scheduler that the current thread is willing to yield
  13.269 +     * its current use of a processor. The scheduler is free to ignore this
  13.270 +     * hint.
  13.271 +     *
  13.272 +     * <p> Yield is a heuristic attempt to improve relative progression
  13.273 +     * between threads that would otherwise over-utilise a CPU. Its use
  13.274 +     * should be combined with detailed profiling and benchmarking to
  13.275 +     * ensure that it actually has the desired effect.
  13.276 +     *
  13.277 +     * <p> It is rarely appropriate to use this method. It may be useful
  13.278 +     * for debugging or testing purposes, where it may help to reproduce
  13.279 +     * bugs due to race conditions. It may also be useful when designing
  13.280 +     * concurrency control constructs such as the ones in the
  13.281 +     * {@link java.util.concurrent.locks} package.
  13.282 +     */
  13.283 +    public static native void yield();
  13.284 +
  13.285 +    /**
  13.286 +     * Causes the currently executing thread to sleep (temporarily cease
  13.287 +     * execution) for the specified number of milliseconds, subject to
  13.288 +     * the precision and accuracy of system timers and schedulers. The thread
  13.289 +     * does not lose ownership of any monitors.
  13.290 +     *
  13.291 +     * @param  millis
  13.292 +     *         the length of time to sleep in milliseconds
  13.293 +     *
  13.294 +     * @throws  IllegalArgumentException
  13.295 +     *          if the value of {@code millis} is negative
  13.296 +     *
  13.297 +     * @throws  InterruptedException
  13.298 +     *          if any thread has interrupted the current thread. The
  13.299 +     *          <i>interrupted status</i> of the current thread is
  13.300 +     *          cleared when this exception is thrown.
  13.301 +     */
  13.302 +    public static native void sleep(long millis) throws InterruptedException;
  13.303 +
  13.304 +    /**
  13.305 +     * Causes the currently executing thread to sleep (temporarily cease
  13.306 +     * execution) for the specified number of milliseconds plus the specified
  13.307 +     * number of nanoseconds, subject to the precision and accuracy of system
  13.308 +     * timers and schedulers. The thread does not lose ownership of any
  13.309 +     * monitors.
  13.310 +     *
  13.311 +     * @param  millis
  13.312 +     *         the length of time to sleep in milliseconds
  13.313 +     *
  13.314 +     * @param  nanos
  13.315 +     *         {@code 0-999999} additional nanoseconds to sleep
  13.316 +     *
  13.317 +     * @throws  IllegalArgumentException
  13.318 +     *          if the value of {@code millis} is negative, or the value of
  13.319 +     *          {@code nanos} is not in the range {@code 0-999999}
  13.320 +     *
  13.321 +     * @throws  InterruptedException
  13.322 +     *          if any thread has interrupted the current thread. The
  13.323 +     *          <i>interrupted status</i> of the current thread is
  13.324 +     *          cleared when this exception is thrown.
  13.325 +     */
  13.326 +    public static void sleep(long millis, int nanos)
  13.327 +    throws InterruptedException {
  13.328 +        if (millis < 0) {
  13.329 +            throw new IllegalArgumentException("timeout value is negative");
  13.330 +        }
  13.331 +
  13.332 +        if (nanos < 0 || nanos > 999999) {
  13.333 +            throw new IllegalArgumentException(
  13.334 +                                "nanosecond timeout value out of range");
  13.335 +        }
  13.336 +
  13.337 +        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
  13.338 +            millis++;
  13.339 +        }
  13.340 +
  13.341 +        sleep(millis);
  13.342 +    }
  13.343 +
  13.344 +    /**
  13.345 +     * Initializes a Thread.
  13.346 +     *
  13.347 +     * @param g the Thread group
  13.348 +     * @param target the object whose run() method gets called
  13.349 +     * @param name the name of the new Thread
  13.350 +     * @param stackSize the desired stack size for the new thread, or
  13.351 +     *        zero to indicate that this parameter is to be ignored.
  13.352 +     */
  13.353 +    private void init(ThreadGroup g, Runnable target, String name,
  13.354 +                      long stackSize) {
  13.355 +        if (name == null) {
  13.356 +            throw new NullPointerException("name cannot be null");
  13.357 +        }
  13.358 +
  13.359 +        Thread parent = currentThread();
  13.360 +        SecurityManager security = System.getSecurityManager();
  13.361 +        if (g == null) {
  13.362 +            /* Determine if it's an applet or not */
  13.363 +
  13.364 +            /* If there is a security manager, ask the security manager
  13.365 +               what to do. */
  13.366 +            if (security != null) {
  13.367 +                g = security.getThreadGroup();
  13.368 +            }
  13.369 +
  13.370 +            /* If the security doesn't have a strong opinion of the matter
  13.371 +               use the parent thread group. */
  13.372 +            if (g == null) {
  13.373 +                g = parent.getThreadGroup();
  13.374 +            }
  13.375 +        }
  13.376 +
  13.377 +        /* checkAccess regardless of whether or not threadgroup is
  13.378 +           explicitly passed in. */
  13.379 +        g.checkAccess();
  13.380 +
  13.381 +        /*
  13.382 +         * Do we have the required permissions?
  13.383 +         */
  13.384 +        if (security != null) {
  13.385 +            if (isCCLOverridden(getClass())) {
  13.386 +                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
  13.387 +            }
  13.388 +        }
  13.389 +
  13.390 +        g.addUnstarted();
  13.391 +
  13.392 +        this.group = g;
  13.393 +        this.daemon = parent.isDaemon();
  13.394 +        this.priority = parent.getPriority();
  13.395 +        this.name = name.toCharArray();
  13.396 +        if (security == null || isCCLOverridden(parent.getClass()))
  13.397 +            this.contextClassLoader = parent.getContextClassLoader();
  13.398 +        else
  13.399 +            this.contextClassLoader = parent.contextClassLoader;
  13.400 +        this.inheritedAccessControlContext = AccessController.getContext();
  13.401 +        this.target = target;
  13.402 +        setPriority(priority);
  13.403 +        if (parent.inheritableThreadLocals != null)
  13.404 +            this.inheritableThreadLocals =
  13.405 +                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
  13.406 +        /* Stash the specified stack size in case the VM cares */
  13.407 +        this.stackSize = stackSize;
  13.408 +
  13.409 +        /* Set thread ID */
  13.410 +        tid = nextThreadID();
  13.411 +    }
  13.412 +
  13.413 +    /**
  13.414 +     * Throws CloneNotSupportedException as a Thread can not be meaningfully
  13.415 +     * cloned. Construct a new Thread instead.
  13.416 +     *
  13.417 +     * @throws  CloneNotSupportedException
  13.418 +     *          always
  13.419 +     */
  13.420 +    @Override
  13.421 +    protected Object clone() throws CloneNotSupportedException {
  13.422 +        throw new CloneNotSupportedException();
  13.423 +    }
  13.424 +
  13.425 +    /**
  13.426 +     * Allocates a new {@code Thread} object. This constructor has the same
  13.427 +     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
  13.428 +     * {@code (null, null, gname)}, where {@code gname} is a newly generated
  13.429 +     * name. Automatically generated names are of the form
  13.430 +     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
  13.431 +     */
  13.432 +    public Thread() {
  13.433 +        init(null, null, "Thread-" + nextThreadNum(), 0);
  13.434 +    }
  13.435 +
  13.436 +    /**
  13.437 +     * Allocates a new {@code Thread} object. This constructor has the same
  13.438 +     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
  13.439 +     * {@code (null, target, gname)}, where {@code gname} is a newly generated
  13.440 +     * name. Automatically generated names are of the form
  13.441 +     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
  13.442 +     *
  13.443 +     * @param  target
  13.444 +     *         the object whose {@code run} method is invoked when this thread
  13.445 +     *         is started. If {@code null}, this classes {@code run} method does
  13.446 +     *         nothing.
  13.447 +     */
  13.448 +    public Thread(Runnable target) {
  13.449 +        init(null, target, "Thread-" + nextThreadNum(), 0);
  13.450 +    }
  13.451 +
  13.452 +    /**
  13.453 +     * Allocates a new {@code Thread} object. This constructor has the same
  13.454 +     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
  13.455 +     * {@code (group, target, gname)} ,where {@code gname} is a newly generated
  13.456 +     * name. Automatically generated names are of the form
  13.457 +     * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
  13.458 +     *
  13.459 +     * @param  group
  13.460 +     *         the thread group. If {@code null} and there is a security
  13.461 +     *         manager, the group is determined by {@linkplain
  13.462 +     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
  13.463 +     *         If there is not a security manager or {@code
  13.464 +     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
  13.465 +     *         is set to the current thread's thread group.
  13.466 +     *
  13.467 +     * @param  target
  13.468 +     *         the object whose {@code run} method is invoked when this thread
  13.469 +     *         is started. If {@code null}, this thread's run method is invoked.
  13.470 +     *
  13.471 +     * @throws  SecurityException
  13.472 +     *          if the current thread cannot create a thread in the specified
  13.473 +     *          thread group
  13.474 +     */
  13.475 +    public Thread(ThreadGroup group, Runnable target) {
  13.476 +        init(group, target, "Thread-" + nextThreadNum(), 0);
  13.477 +    }
  13.478 +
  13.479 +    /**
  13.480 +     * Allocates a new {@code Thread} object. This constructor has the same
  13.481 +     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
  13.482 +     * {@code (null, null, name)}.
  13.483 +     *
  13.484 +     * @param   name
  13.485 +     *          the name of the new thread
  13.486 +     */
  13.487 +    public Thread(String name) {
  13.488 +        init(null, null, name, 0);
  13.489 +    }
  13.490 +
  13.491 +    /**
  13.492 +     * Allocates a new {@code Thread} object. This constructor has the same
  13.493 +     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
  13.494 +     * {@code (group, null, name)}.
  13.495 +     *
  13.496 +     * @param  group
  13.497 +     *         the thread group. If {@code null} and there is a security
  13.498 +     *         manager, the group is determined by {@linkplain
  13.499 +     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
  13.500 +     *         If there is not a security manager or {@code
  13.501 +     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
  13.502 +     *         is set to the current thread's thread group.
  13.503 +     *
  13.504 +     * @param  name
  13.505 +     *         the name of the new thread
  13.506 +     *
  13.507 +     * @throws  SecurityException
  13.508 +     *          if the current thread cannot create a thread in the specified
  13.509 +     *          thread group
  13.510 +     */
  13.511 +    public Thread(ThreadGroup group, String name) {
  13.512 +        init(group, null, name, 0);
  13.513 +    }
  13.514 +
  13.515 +    /**
  13.516 +     * Allocates a new {@code Thread} object. This constructor has the same
  13.517 +     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
  13.518 +     * {@code (null, target, name)}.
  13.519 +     *
  13.520 +     * @param  target
  13.521 +     *         the object whose {@code run} method is invoked when this thread
  13.522 +     *         is started. If {@code null}, this thread's run method is invoked.
  13.523 +     *
  13.524 +     * @param  name
  13.525 +     *         the name of the new thread
  13.526 +     */
  13.527 +    public Thread(Runnable target, String name) {
  13.528 +        init(null, target, name, 0);
  13.529 +    }
  13.530 +
  13.531 +    /**
  13.532 +     * Allocates a new {@code Thread} object so that it has {@code target}
  13.533 +     * as its run object, has the specified {@code name} as its name,
  13.534 +     * and belongs to the thread group referred to by {@code group}.
  13.535 +     *
  13.536 +     * <p>If there is a security manager, its
  13.537 +     * {@link SecurityManager#checkAccess(ThreadGroup) checkAccess}
  13.538 +     * method is invoked with the ThreadGroup as its argument.
  13.539 +     *
  13.540 +     * <p>In addition, its {@code checkPermission} method is invoked with
  13.541 +     * the {@code RuntimePermission("enableContextClassLoaderOverride")}
  13.542 +     * permission when invoked directly or indirectly by the constructor
  13.543 +     * of a subclass which overrides the {@code getContextClassLoader}
  13.544 +     * or {@code setContextClassLoader} methods.
  13.545 +     *
  13.546 +     * <p>The priority of the newly created thread is set equal to the
  13.547 +     * priority of the thread creating it, that is, the currently running
  13.548 +     * thread. The method {@linkplain #setPriority setPriority} may be
  13.549 +     * used to change the priority to a new value.
  13.550 +     *
  13.551 +     * <p>The newly created thread is initially marked as being a daemon
  13.552 +     * thread if and only if the thread creating it is currently marked
  13.553 +     * as a daemon thread. The method {@linkplain #setDaemon setDaemon}
  13.554 +     * may be used to change whether or not a thread is a daemon.
  13.555 +     *
  13.556 +     * @param  group
  13.557 +     *         the thread group. If {@code null} and there is a security
  13.558 +     *         manager, the group is determined by {@linkplain
  13.559 +     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
  13.560 +     *         If there is not a security manager or {@code
  13.561 +     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
  13.562 +     *         is set to the current thread's thread group.
  13.563 +     *
  13.564 +     * @param  target
  13.565 +     *         the object whose {@code run} method is invoked when this thread
  13.566 +     *         is started. If {@code null}, this thread's run method is invoked.
  13.567 +     *
  13.568 +     * @param  name
  13.569 +     *         the name of the new thread
  13.570 +     *
  13.571 +     * @throws  SecurityException
  13.572 +     *          if the current thread cannot create a thread in the specified
  13.573 +     *          thread group or cannot override the context class loader methods.
  13.574 +     */
  13.575 +    public Thread(ThreadGroup group, Runnable target, String name) {
  13.576 +        init(group, target, name, 0);
  13.577 +    }
  13.578 +
  13.579 +    /**
  13.580 +     * Allocates a new {@code Thread} object so that it has {@code target}
  13.581 +     * as its run object, has the specified {@code name} as its name,
  13.582 +     * and belongs to the thread group referred to by {@code group}, and has
  13.583 +     * the specified <i>stack size</i>.
  13.584 +     *
  13.585 +     * <p>This constructor is identical to {@link
  13.586 +     * #Thread(ThreadGroup,Runnable,String)} with the exception of the fact
  13.587 +     * that it allows the thread stack size to be specified.  The stack size
  13.588 +     * is the approximate number of bytes of address space that the virtual
  13.589 +     * machine is to allocate for this thread's stack.  <b>The effect of the
  13.590 +     * {@code stackSize} parameter, if any, is highly platform dependent.</b>
  13.591 +     *
  13.592 +     * <p>On some platforms, specifying a higher value for the
  13.593 +     * {@code stackSize} parameter may allow a thread to achieve greater
  13.594 +     * recursion depth before throwing a {@link StackOverflowError}.
  13.595 +     * Similarly, specifying a lower value may allow a greater number of
  13.596 +     * threads to exist concurrently without throwing an {@link
  13.597 +     * OutOfMemoryError} (or other internal error).  The details of
  13.598 +     * the relationship between the value of the <tt>stackSize</tt> parameter
  13.599 +     * and the maximum recursion depth and concurrency level are
  13.600 +     * platform-dependent.  <b>On some platforms, the value of the
  13.601 +     * {@code stackSize} parameter may have no effect whatsoever.</b>
  13.602 +     *
  13.603 +     * <p>The virtual machine is free to treat the {@code stackSize}
  13.604 +     * parameter as a suggestion.  If the specified value is unreasonably low
  13.605 +     * for the platform, the virtual machine may instead use some
  13.606 +     * platform-specific minimum value; if the specified value is unreasonably
  13.607 +     * high, the virtual machine may instead use some platform-specific
  13.608 +     * maximum.  Likewise, the virtual machine is free to round the specified
  13.609 +     * value up or down as it sees fit (or to ignore it completely).
  13.610 +     *
  13.611 +     * <p>Specifying a value of zero for the {@code stackSize} parameter will
  13.612 +     * cause this constructor to behave exactly like the
  13.613 +     * {@code Thread(ThreadGroup, Runnable, String)} constructor.
  13.614 +     *
  13.615 +     * <p><i>Due to the platform-dependent nature of the behavior of this
  13.616 +     * constructor, extreme care should be exercised in its use.
  13.617 +     * The thread stack size necessary to perform a given computation will
  13.618 +     * likely vary from one JRE implementation to another.  In light of this
  13.619 +     * variation, careful tuning of the stack size parameter may be required,
  13.620 +     * and the tuning may need to be repeated for each JRE implementation on
  13.621 +     * which an application is to run.</i>
  13.622 +     *
  13.623 +     * <p>Implementation note: Java platform implementers are encouraged to
  13.624 +     * document their implementation's behavior with respect to the
  13.625 +     * {@code stackSize} parameter.
  13.626 +     *
  13.627 +     *
  13.628 +     * @param  group
  13.629 +     *         the thread group. If {@code null} and there is a security
  13.630 +     *         manager, the group is determined by {@linkplain
  13.631 +     *         SecurityManager#getThreadGroup SecurityManager.getThreadGroup()}.
  13.632 +     *         If there is not a security manager or {@code
  13.633 +     *         SecurityManager.getThreadGroup()} returns {@code null}, the group
  13.634 +     *         is set to the current thread's thread group.
  13.635 +     *
  13.636 +     * @param  target
  13.637 +     *         the object whose {@code run} method is invoked when this thread
  13.638 +     *         is started. If {@code null}, this thread's run method is invoked.
  13.639 +     *
  13.640 +     * @param  name
  13.641 +     *         the name of the new thread
  13.642 +     *
  13.643 +     * @param  stackSize
  13.644 +     *         the desired stack size for the new thread, or zero to indicate
  13.645 +     *         that this parameter is to be ignored.
  13.646 +     *
  13.647 +     * @throws  SecurityException
  13.648 +     *          if the current thread cannot create a thread in the specified
  13.649 +     *          thread group
  13.650 +     *
  13.651 +     * @since 1.4
  13.652 +     */
  13.653 +    public Thread(ThreadGroup group, Runnable target, String name,
  13.654 +                  long stackSize) {
  13.655 +        init(group, target, name, stackSize);
  13.656 +    }
  13.657 +
  13.658 +    /**
  13.659 +     * Causes this thread to begin execution; the Java Virtual Machine
  13.660 +     * calls the <code>run</code> method of this thread.
  13.661 +     * <p>
  13.662 +     * The result is that two threads are running concurrently: the
  13.663 +     * current thread (which returns from the call to the
  13.664 +     * <code>start</code> method) and the other thread (which executes its
  13.665 +     * <code>run</code> method).
  13.666 +     * <p>
  13.667 +     * It is never legal to start a thread more than once.
  13.668 +     * In particular, a thread may not be restarted once it has completed
  13.669 +     * execution.
  13.670 +     *
  13.671 +     * @exception  IllegalThreadStateException  if the thread was already
  13.672 +     *               started.
  13.673 +     * @see        #run()
  13.674 +     * @see        #stop()
  13.675 +     */
  13.676 +    public synchronized void start() {
  13.677 +        /**
  13.678 +         * This method is not invoked for the main method thread or "system"
  13.679 +         * group threads created/set up by the VM. Any new functionality added
  13.680 +         * to this method in the future may have to also be added to the VM.
  13.681 +         *
  13.682 +         * A zero status value corresponds to state "NEW".
  13.683 +         */
  13.684 +        if (threadStatus != 0)
  13.685 +            throw new IllegalThreadStateException();
  13.686 +
  13.687 +        /* Notify the group that this thread is about to be started
  13.688 +         * so that it can be added to the group's list of threads
  13.689 +         * and the group's unstarted count can be decremented. */
  13.690 +        group.add(this);
  13.691 +
  13.692 +        boolean started = false;
  13.693 +        try {
  13.694 +            start0();
  13.695 +            started = true;
  13.696 +        } finally {
  13.697 +            try {
  13.698 +                if (!started) {
  13.699 +                    group.threadStartFailed(this);
  13.700 +                }
  13.701 +            } catch (Throwable ignore) {
  13.702 +                /* do nothing. If start0 threw a Throwable then
  13.703 +                  it will be passed up the call stack */
  13.704 +            }
  13.705 +        }
  13.706 +    }
  13.707 +
  13.708 +    private native void start0();
  13.709 +
  13.710 +    /**
  13.711 +     * If this thread was constructed using a separate
  13.712 +     * <code>Runnable</code> run object, then that
  13.713 +     * <code>Runnable</code> object's <code>run</code> method is called;
  13.714 +     * otherwise, this method does nothing and returns.
  13.715 +     * <p>
  13.716 +     * Subclasses of <code>Thread</code> should override this method.
  13.717 +     *
  13.718 +     * @see     #start()
  13.719 +     * @see     #stop()
  13.720 +     * @see     #Thread(ThreadGroup, Runnable, String)
  13.721 +     */
  13.722 +    @Override
  13.723 +    public void run() {
  13.724 +        if (target != null) {
  13.725 +            target.run();
  13.726 +        }
  13.727 +    }
  13.728 +
  13.729 +    /**
  13.730 +     * This method is called by the system to give a Thread
  13.731 +     * a chance to clean up before it actually exits.
  13.732 +     */
  13.733 +    private void exit() {
  13.734 +        if (group != null) {
  13.735 +            group.threadTerminated(this);
  13.736 +            group = null;
  13.737 +        }
  13.738 +        /* Aggressively null out all reference fields: see bug 4006245 */
  13.739 +        target = null;
  13.740 +        /* Speed the release of some of these resources */
  13.741 +        threadLocals = null;
  13.742 +        inheritableThreadLocals = null;
  13.743 +        inheritedAccessControlContext = null;
  13.744 +        blocker = null;
  13.745 +        uncaughtExceptionHandler = null;
  13.746 +    }
  13.747 +
  13.748 +    /**
  13.749 +     * Forces the thread to stop executing.
  13.750 +     * <p>
  13.751 +     * If there is a security manager installed, its <code>checkAccess</code>
  13.752 +     * method is called with <code>this</code>
  13.753 +     * as its argument. This may result in a
  13.754 +     * <code>SecurityException</code> being raised (in the current thread).
  13.755 +     * <p>
  13.756 +     * If this thread is different from the current thread (that is, the current
  13.757 +     * thread is trying to stop a thread other than itself), the
  13.758 +     * security manager's <code>checkPermission</code> method (with a
  13.759 +     * <code>RuntimePermission("stopThread")</code> argument) is called in
  13.760 +     * addition.
  13.761 +     * Again, this may result in throwing a
  13.762 +     * <code>SecurityException</code> (in the current thread).
  13.763 +     * <p>
  13.764 +     * The thread represented by this thread is forced to stop whatever
  13.765 +     * it is doing abnormally and to throw a newly created
  13.766 +     * <code>ThreadDeath</code> object as an exception.
  13.767 +     * <p>
  13.768 +     * It is permitted to stop a thread that has not yet been started.
  13.769 +     * If the thread is eventually started, it immediately terminates.
  13.770 +     * <p>
  13.771 +     * An application should not normally try to catch
  13.772 +     * <code>ThreadDeath</code> unless it must do some extraordinary
  13.773 +     * cleanup operation (note that the throwing of
  13.774 +     * <code>ThreadDeath</code> causes <code>finally</code> clauses of
  13.775 +     * <code>try</code> statements to be executed before the thread
  13.776 +     * officially dies).  If a <code>catch</code> clause catches a
  13.777 +     * <code>ThreadDeath</code> object, it is important to rethrow the
  13.778 +     * object so that the thread actually dies.
  13.779 +     * <p>
  13.780 +     * The top-level error handler that reacts to otherwise uncaught
  13.781 +     * exceptions does not print out a message or otherwise notify the
  13.782 +     * application if the uncaught exception is an instance of
  13.783 +     * <code>ThreadDeath</code>.
  13.784 +     *
  13.785 +     * @exception  SecurityException  if the current thread cannot
  13.786 +     *               modify this thread.
  13.787 +     * @see        #interrupt()
  13.788 +     * @see        #checkAccess()
  13.789 +     * @see        #run()
  13.790 +     * @see        #start()
  13.791 +     * @see        ThreadDeath
  13.792 +     * @see        ThreadGroup#uncaughtException(Thread,Throwable)
  13.793 +     * @see        SecurityManager#checkAccess(Thread)
  13.794 +     * @see        SecurityManager#checkPermission
  13.795 +     * @deprecated This method is inherently unsafe.  Stopping a thread with
  13.796 +     *       Thread.stop causes it to unlock all of the monitors that it
  13.797 +     *       has locked (as a natural consequence of the unchecked
  13.798 +     *       <code>ThreadDeath</code> exception propagating up the stack).  If
  13.799 +     *       any of the objects previously protected by these monitors were in
  13.800 +     *       an inconsistent state, the damaged objects become visible to
  13.801 +     *       other threads, potentially resulting in arbitrary behavior.  Many
  13.802 +     *       uses of <code>stop</code> should be replaced by code that simply
  13.803 +     *       modifies some variable to indicate that the target thread should
  13.804 +     *       stop running.  The target thread should check this variable
  13.805 +     *       regularly, and return from its run method in an orderly fashion
  13.806 +     *       if the variable indicates that it is to stop running.  If the
  13.807 +     *       target thread waits for long periods (on a condition variable,
  13.808 +     *       for example), the <code>interrupt</code> method should be used to
  13.809 +     *       interrupt the wait.
  13.810 +     *       For more information, see
  13.811 +     *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
  13.812 +     *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
  13.813 +     */
  13.814 +    @Deprecated
  13.815 +    public final void stop() {
  13.816 +        stop(new ThreadDeath());
  13.817 +    }
  13.818 +
  13.819 +    /**
  13.820 +     * Forces the thread to stop executing.
  13.821 +     * <p>
  13.822 +     * If there is a security manager installed, the <code>checkAccess</code>
  13.823 +     * method of this thread is called, which may result in a
  13.824 +     * <code>SecurityException</code> being raised (in the current thread).
  13.825 +     * <p>
  13.826 +     * If this thread is different from the current thread (that is, the current
  13.827 +     * thread is trying to stop a thread other than itself) or
  13.828 +     * <code>obj</code> is not an instance of <code>ThreadDeath</code>, the
  13.829 +     * security manager's <code>checkPermission</code> method (with the
  13.830 +     * <code>RuntimePermission("stopThread")</code> argument) is called in
  13.831 +     * addition.
  13.832 +     * Again, this may result in throwing a
  13.833 +     * <code>SecurityException</code> (in the current thread).
  13.834 +     * <p>
  13.835 +     * If the argument <code>obj</code> is null, a
  13.836 +     * <code>NullPointerException</code> is thrown (in the current thread).
  13.837 +     * <p>
  13.838 +     * The thread represented by this thread is forced to stop
  13.839 +     * whatever it is doing abnormally and to throw the
  13.840 +     * <code>Throwable</code> object <code>obj</code> as an exception. This
  13.841 +     * is an unusual action to take; normally, the <code>stop</code> method
  13.842 +     * that takes no arguments should be used.
  13.843 +     * <p>
  13.844 +     * It is permitted to stop a thread that has not yet been started.
  13.845 +     * If the thread is eventually started, it immediately terminates.
  13.846 +     *
  13.847 +     * @param      obj   the Throwable object to be thrown.
  13.848 +     * @exception  SecurityException  if the current thread cannot modify
  13.849 +     *               this thread.
  13.850 +     * @throws     NullPointerException if obj is <tt>null</tt>.
  13.851 +     * @see        #interrupt()
  13.852 +     * @see        #checkAccess()
  13.853 +     * @see        #run()
  13.854 +     * @see        #start()
  13.855 +     * @see        #stop()
  13.856 +     * @see        SecurityManager#checkAccess(Thread)
  13.857 +     * @see        SecurityManager#checkPermission
  13.858 +     * @deprecated This method is inherently unsafe.  See {@link #stop()}
  13.859 +     *        for details.  An additional danger of this
  13.860 +     *        method is that it may be used to generate exceptions that the
  13.861 +     *        target thread is unprepared to handle (including checked
  13.862 +     *        exceptions that the thread could not possibly throw, were it
  13.863 +     *        not for this method).
  13.864 +     *        For more information, see
  13.865 +     *        <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
  13.866 +     *        are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
  13.867 +     */
  13.868 +    @Deprecated
  13.869 +    public final synchronized void stop(Throwable obj) {
  13.870 +        if (obj == null)
  13.871 +            throw new NullPointerException();
  13.872 +
  13.873 +        SecurityManager security = System.getSecurityManager();
  13.874 +        if (security != null) {
  13.875 +            checkAccess();
  13.876 +            if ((this != Thread.currentThread()) ||
  13.877 +                (!(obj instanceof ThreadDeath))) {
  13.878 +                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
  13.879 +            }
  13.880 +        }
  13.881 +        // A zero status value corresponds to "NEW", it can't change to
  13.882 +        // not-NEW because we hold the lock.
  13.883 +        if (threadStatus != 0) {
  13.884 +            resume(); // Wake up thread if it was suspended; no-op otherwise
  13.885 +        }
  13.886 +
  13.887 +        // The VM can handle all thread states
  13.888 +        stop0(obj);
  13.889 +    }
  13.890 +
  13.891 +    /**
  13.892 +     * Interrupts this thread.
  13.893 +     *
  13.894 +     * <p> Unless the current thread is interrupting itself, which is
  13.895 +     * always permitted, the {@link #checkAccess() checkAccess} method
  13.896 +     * of this thread is invoked, which may cause a {@link
  13.897 +     * SecurityException} to be thrown.
  13.898 +     *
  13.899 +     * <p> If this thread is blocked in an invocation of the {@link
  13.900 +     * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
  13.901 +     * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
  13.902 +     * class, or of the {@link #join()}, {@link #join(long)}, {@link
  13.903 +     * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
  13.904 +     * methods of this class, then its interrupt status will be cleared and it
  13.905 +     * will receive an {@link InterruptedException}.
  13.906 +     *
  13.907 +     * <p> If this thread is blocked in an I/O operation upon an {@link
  13.908 +     * java.nio.channels.InterruptibleChannel </code>interruptible
  13.909 +     * channel<code>} then the channel will be closed, the thread's interrupt
  13.910 +     * status will be set, and the thread will receive a {@link
  13.911 +     * java.nio.channels.ClosedByInterruptException}.
  13.912 +     *
  13.913 +     * <p> If this thread is blocked in a {@link java.nio.channels.Selector}
  13.914 +     * then the thread's interrupt status will be set and it will return
  13.915 +     * immediately from the selection operation, possibly with a non-zero
  13.916 +     * value, just as if the selector's {@link
  13.917 +     * java.nio.channels.Selector#wakeup wakeup} method were invoked.
  13.918 +     *
  13.919 +     * <p> If none of the previous conditions hold then this thread's interrupt
  13.920 +     * status will be set. </p>
  13.921 +     *
  13.922 +     * <p> Interrupting a thread that is not alive need not have any effect.
  13.923 +     *
  13.924 +     * @throws  SecurityException
  13.925 +     *          if the current thread cannot modify this thread
  13.926 +     *
  13.927 +     * @revised 6.0
  13.928 +     * @spec JSR-51
  13.929 +     */
  13.930 +    public void interrupt() {
  13.931 +        if (this != Thread.currentThread())
  13.932 +            checkAccess();
  13.933 +
  13.934 +        synchronized (blockerLock) {
  13.935 +            Interruptible b = blocker;
  13.936 +            if (b != null) {
  13.937 +                interrupt0();           // Just to set the interrupt flag
  13.938 +                b.interrupt(this);
  13.939 +                return;
  13.940 +            }
  13.941 +        }
  13.942 +        interrupt0();
  13.943 +    }
  13.944 +
  13.945 +    /**
  13.946 +     * Tests whether the current thread has been interrupted.  The
  13.947 +     * <i>interrupted status</i> of the thread is cleared by this method.  In
  13.948 +     * other words, if this method were to be called twice in succession, the
  13.949 +     * second call would return false (unless the current thread were
  13.950 +     * interrupted again, after the first call had cleared its interrupted
  13.951 +     * status and before the second call had examined it).
  13.952 +     *
  13.953 +     * <p>A thread interruption ignored because a thread was not alive
  13.954 +     * at the time of the interrupt will be reflected by this method
  13.955 +     * returning false.
  13.956 +     *
  13.957 +     * @return  <code>true</code> if the current thread has been interrupted;
  13.958 +     *          <code>false</code> otherwise.
  13.959 +     * @see #isInterrupted()
  13.960 +     * @revised 6.0
  13.961 +     */
  13.962 +    public static boolean interrupted() {
  13.963 +        return currentThread().isInterrupted(true);
  13.964 +    }
  13.965 +
  13.966 +    /**
  13.967 +     * Tests whether this thread has been interrupted.  The <i>interrupted
  13.968 +     * status</i> of the thread is unaffected by this method.
  13.969 +     *
  13.970 +     * <p>A thread interruption ignored because a thread was not alive
  13.971 +     * at the time of the interrupt will be reflected by this method
  13.972 +     * returning false.
  13.973 +     *
  13.974 +     * @return  <code>true</code> if this thread has been interrupted;
  13.975 +     *          <code>false</code> otherwise.
  13.976 +     * @see     #interrupted()
  13.977 +     * @revised 6.0
  13.978 +     */
  13.979 +    public boolean isInterrupted() {
  13.980 +        return isInterrupted(false);
  13.981 +    }
  13.982 +
  13.983 +    /**
  13.984 +     * Tests if some Thread has been interrupted.  The interrupted state
  13.985 +     * is reset or not based on the value of ClearInterrupted that is
  13.986 +     * passed.
  13.987 +     */
  13.988 +    private native boolean isInterrupted(boolean ClearInterrupted);
  13.989 +
  13.990 +    /**
  13.991 +     * Throws {@link NoSuchMethodError}.
  13.992 +     *
  13.993 +     * @deprecated This method was originally designed to destroy this
  13.994 +     *     thread without any cleanup. Any monitors it held would have
  13.995 +     *     remained locked. However, the method was never implemented.
  13.996 +     *     If if were to be implemented, it would be deadlock-prone in
  13.997 +     *     much the manner of {@link #suspend}. If the target thread held
  13.998 +     *     a lock protecting a critical system resource when it was
  13.999 +     *     destroyed, no thread could ever access this resource again.
 13.1000 +     *     If another thread ever attempted to lock this resource, deadlock
 13.1001 +     *     would result. Such deadlocks typically manifest themselves as
 13.1002 +     *     "frozen" processes. For more information, see
 13.1003 +     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">
 13.1004 +     *     Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 13.1005 +     * @throws NoSuchMethodError always
 13.1006 +     */
 13.1007 +    @Deprecated
 13.1008 +    public void destroy() {
 13.1009 +        throw new NoSuchMethodError();
 13.1010 +    }
 13.1011 +
 13.1012 +    /**
 13.1013 +     * Tests if this thread is alive. A thread is alive if it has
 13.1014 +     * been started and has not yet died.
 13.1015 +     *
 13.1016 +     * @return  <code>true</code> if this thread is alive;
 13.1017 +     *          <code>false</code> otherwise.
 13.1018 +     */
 13.1019 +    public final native boolean isAlive();
 13.1020 +
 13.1021 +    /**
 13.1022 +     * Suspends this thread.
 13.1023 +     * <p>
 13.1024 +     * First, the <code>checkAccess</code> method of this thread is called
 13.1025 +     * with no arguments. This may result in throwing a
 13.1026 +     * <code>SecurityException </code>(in the current thread).
 13.1027 +     * <p>
 13.1028 +     * If the thread is alive, it is suspended and makes no further
 13.1029 +     * progress unless and until it is resumed.
 13.1030 +     *
 13.1031 +     * @exception  SecurityException  if the current thread cannot modify
 13.1032 +     *               this thread.
 13.1033 +     * @see #checkAccess
 13.1034 +     * @deprecated   This method has been deprecated, as it is
 13.1035 +     *   inherently deadlock-prone.  If the target thread holds a lock on the
 13.1036 +     *   monitor protecting a critical system resource when it is suspended, no
 13.1037 +     *   thread can access this resource until the target thread is resumed. If
 13.1038 +     *   the thread that would resume the target thread attempts to lock this
 13.1039 +     *   monitor prior to calling <code>resume</code>, deadlock results.  Such
 13.1040 +     *   deadlocks typically manifest themselves as "frozen" processes.
 13.1041 +     *   For more information, see
 13.1042 +     *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 13.1043 +     *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 13.1044 +     */
 13.1045 +    @Deprecated
 13.1046 +    public final void suspend() {
 13.1047 +        checkAccess();
 13.1048 +        suspend0();
 13.1049 +    }
 13.1050 +
 13.1051 +    /**
 13.1052 +     * Resumes a suspended thread.
 13.1053 +     * <p>
 13.1054 +     * First, the <code>checkAccess</code> method of this thread is called
 13.1055 +     * with no arguments. This may result in throwing a
 13.1056 +     * <code>SecurityException</code> (in the current thread).
 13.1057 +     * <p>
 13.1058 +     * If the thread is alive but suspended, it is resumed and is
 13.1059 +     * permitted to make progress in its execution.
 13.1060 +     *
 13.1061 +     * @exception  SecurityException  if the current thread cannot modify this
 13.1062 +     *               thread.
 13.1063 +     * @see        #checkAccess
 13.1064 +     * @see        #suspend()
 13.1065 +     * @deprecated This method exists solely for use with {@link #suspend},
 13.1066 +     *     which has been deprecated because it is deadlock-prone.
 13.1067 +     *     For more information, see
 13.1068 +     *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 13.1069 +     *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 13.1070 +     */
 13.1071 +    @Deprecated
 13.1072 +    public final void resume() {
 13.1073 +        checkAccess();
 13.1074 +        resume0();
 13.1075 +    }
 13.1076 +
 13.1077 +    /**
 13.1078 +     * Changes the priority of this thread.
 13.1079 +     * <p>
 13.1080 +     * First the <code>checkAccess</code> method of this thread is called
 13.1081 +     * with no arguments. This may result in throwing a
 13.1082 +     * <code>SecurityException</code>.
 13.1083 +     * <p>
 13.1084 +     * Otherwise, the priority of this thread is set to the smaller of
 13.1085 +     * the specified <code>newPriority</code> and the maximum permitted
 13.1086 +     * priority of the thread's thread group.
 13.1087 +     *
 13.1088 +     * @param newPriority priority to set this thread to
 13.1089 +     * @exception  IllegalArgumentException  If the priority is not in the
 13.1090 +     *               range <code>MIN_PRIORITY</code> to
 13.1091 +     *               <code>MAX_PRIORITY</code>.
 13.1092 +     * @exception  SecurityException  if the current thread cannot modify
 13.1093 +     *               this thread.
 13.1094 +     * @see        #getPriority
 13.1095 +     * @see        #checkAccess()
 13.1096 +     * @see        #getThreadGroup()
 13.1097 +     * @see        #MAX_PRIORITY
 13.1098 +     * @see        #MIN_PRIORITY
 13.1099 +     * @see        ThreadGroup#getMaxPriority()
 13.1100 +     */
 13.1101 +    public final void setPriority(int newPriority) {
 13.1102 +        ThreadGroup g;
 13.1103 +        checkAccess();
 13.1104 +        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
 13.1105 +            throw new IllegalArgumentException();
 13.1106 +        }
 13.1107 +        if((g = getThreadGroup()) != null) {
 13.1108 +            if (newPriority > g.getMaxPriority()) {
 13.1109 +                newPriority = g.getMaxPriority();
 13.1110 +            }
 13.1111 +            setPriority0(priority = newPriority);
 13.1112 +        }
 13.1113 +    }
 13.1114 +
 13.1115 +    /**
 13.1116 +     * Returns this thread's priority.
 13.1117 +     *
 13.1118 +     * @return  this thread's priority.
 13.1119 +     * @see     #setPriority
 13.1120 +     */
 13.1121 +    public final int getPriority() {
 13.1122 +        return priority;
 13.1123 +    }
 13.1124 +
 13.1125 +    /**
 13.1126 +     * Changes the name of this thread to be equal to the argument
 13.1127 +     * <code>name</code>.
 13.1128 +     * <p>
 13.1129 +     * First the <code>checkAccess</code> method of this thread is called
 13.1130 +     * with no arguments. This may result in throwing a
 13.1131 +     * <code>SecurityException</code>.
 13.1132 +     *
 13.1133 +     * @param      name   the new name for this thread.
 13.1134 +     * @exception  SecurityException  if the current thread cannot modify this
 13.1135 +     *               thread.
 13.1136 +     * @see        #getName
 13.1137 +     * @see        #checkAccess()
 13.1138 +     */
 13.1139 +    public final void setName(String name) {
 13.1140 +        checkAccess();
 13.1141 +        this.name = name.toCharArray();
 13.1142 +    }
 13.1143 +
 13.1144 +    /**
 13.1145 +     * Returns this thread's name.
 13.1146 +     *
 13.1147 +     * @return  this thread's name.
 13.1148 +     * @see     #setName(String)
 13.1149 +     */
 13.1150 +    public final String getName() {
 13.1151 +        return String.valueOf(name);
 13.1152 +    }
 13.1153 +
 13.1154 +    /**
 13.1155 +     * Returns the thread group to which this thread belongs.
 13.1156 +     * This method returns null if this thread has died
 13.1157 +     * (been stopped).
 13.1158 +     *
 13.1159 +     * @return  this thread's thread group.
 13.1160 +     */
 13.1161 +    public final ThreadGroup getThreadGroup() {
 13.1162 +        return group;
 13.1163 +    }
 13.1164 +
 13.1165 +    /**
 13.1166 +     * Returns an estimate of the number of active threads in the current
 13.1167 +     * thread's {@linkplain java.lang.ThreadGroup thread group} and its
 13.1168 +     * subgroups. Recursively iterates over all subgroups in the current
 13.1169 +     * thread's thread group.
 13.1170 +     *
 13.1171 +     * <p> The value returned is only an estimate because the number of
 13.1172 +     * threads may change dynamically while this method traverses internal
 13.1173 +     * data structures, and might be affected by the presence of certain
 13.1174 +     * system threads. This method is intended primarily for debugging
 13.1175 +     * and monitoring purposes.
 13.1176 +     *
 13.1177 +     * @return  an estimate of the number of active threads in the current
 13.1178 +     *          thread's thread group and in any other thread group that
 13.1179 +     *          has the current thread's thread group as an ancestor
 13.1180 +     */
 13.1181 +    public static int activeCount() {
 13.1182 +        return currentThread().getThreadGroup().activeCount();
 13.1183 +    }
 13.1184 +
 13.1185 +    /**
 13.1186 +     * Copies into the specified array every active thread in the current
 13.1187 +     * thread's thread group and its subgroups. This method simply
 13.1188 +     * invokes the {@link java.lang.ThreadGroup#enumerate(Thread[])}
 13.1189 +     * method of the current thread's thread group.
 13.1190 +     *
 13.1191 +     * <p> An application might use the {@linkplain #activeCount activeCount}
 13.1192 +     * method to get an estimate of how big the array should be, however
 13.1193 +     * <i>if the array is too short to hold all the threads, the extra threads
 13.1194 +     * are silently ignored.</i>  If it is critical to obtain every active
 13.1195 +     * thread in the current thread's thread group and its subgroups, the
 13.1196 +     * invoker should verify that the returned int value is strictly less
 13.1197 +     * than the length of {@code tarray}.
 13.1198 +     *
 13.1199 +     * <p> Due to the inherent race condition in this method, it is recommended
 13.1200 +     * that the method only be used for debugging and monitoring purposes.
 13.1201 +     *
 13.1202 +     * @param  tarray
 13.1203 +     *         an array into which to put the list of threads
 13.1204 +     *
 13.1205 +     * @return  the number of threads put into the array
 13.1206 +     *
 13.1207 +     * @throws  SecurityException
 13.1208 +     *          if {@link java.lang.ThreadGroup#checkAccess} determines that
 13.1209 +     *          the current thread cannot access its thread group
 13.1210 +     */
 13.1211 +    public static int enumerate(Thread tarray[]) {
 13.1212 +        return currentThread().getThreadGroup().enumerate(tarray);
 13.1213 +    }
 13.1214 +
 13.1215 +    /**
 13.1216 +     * Counts the number of stack frames in this thread. The thread must
 13.1217 +     * be suspended.
 13.1218 +     *
 13.1219 +     * @return     the number of stack frames in this thread.
 13.1220 +     * @exception  IllegalThreadStateException  if this thread is not
 13.1221 +     *             suspended.
 13.1222 +     * @deprecated The definition of this call depends on {@link #suspend},
 13.1223 +     *             which is deprecated.  Further, the results of this call
 13.1224 +     *             were never well-defined.
 13.1225 +     */
 13.1226 +    @Deprecated
 13.1227 +    public native int countStackFrames();
 13.1228 +
 13.1229 +    /**
 13.1230 +     * Waits at most {@code millis} milliseconds for this thread to
 13.1231 +     * die. A timeout of {@code 0} means to wait forever.
 13.1232 +     *
 13.1233 +     * <p> This implementation uses a loop of {@code this.wait} calls
 13.1234 +     * conditioned on {@code this.isAlive}. As a thread terminates the
 13.1235 +     * {@code this.notifyAll} method is invoked. It is recommended that
 13.1236 +     * applications not use {@code wait}, {@code notify}, or
 13.1237 +     * {@code notifyAll} on {@code Thread} instances.
 13.1238 +     *
 13.1239 +     * @param  millis
 13.1240 +     *         the time to wait in milliseconds
 13.1241 +     *
 13.1242 +     * @throws  IllegalArgumentException
 13.1243 +     *          if the value of {@code millis} is negative
 13.1244 +     *
 13.1245 +     * @throws  InterruptedException
 13.1246 +     *          if any thread has interrupted the current thread. The
 13.1247 +     *          <i>interrupted status</i> of the current thread is
 13.1248 +     *          cleared when this exception is thrown.
 13.1249 +     */
 13.1250 +    public final synchronized void join(long millis)
 13.1251 +    throws InterruptedException {
 13.1252 +        long base = System.currentTimeMillis();
 13.1253 +        long now = 0;
 13.1254 +
 13.1255 +        if (millis < 0) {
 13.1256 +            throw new IllegalArgumentException("timeout value is negative");
 13.1257 +        }
 13.1258 +
 13.1259 +        if (millis == 0) {
 13.1260 +            while (isAlive()) {
 13.1261 +                wait(0);
 13.1262 +            }
 13.1263 +        } else {
 13.1264 +            while (isAlive()) {
 13.1265 +                long delay = millis - now;
 13.1266 +                if (delay <= 0) {
 13.1267 +                    break;
 13.1268 +                }
 13.1269 +                wait(delay);
 13.1270 +                now = System.currentTimeMillis() - base;
 13.1271 +            }
 13.1272 +        }
 13.1273 +    }
 13.1274 +
 13.1275 +    /**
 13.1276 +     * Waits at most {@code millis} milliseconds plus
 13.1277 +     * {@code nanos} nanoseconds for this thread to die.
 13.1278 +     *
 13.1279 +     * <p> This implementation uses a loop of {@code this.wait} calls
 13.1280 +     * conditioned on {@code this.isAlive}. As a thread terminates the
 13.1281 +     * {@code this.notifyAll} method is invoked. It is recommended that
 13.1282 +     * applications not use {@code wait}, {@code notify}, or
 13.1283 +     * {@code notifyAll} on {@code Thread} instances.
 13.1284 +     *
 13.1285 +     * @param  millis
 13.1286 +     *         the time to wait in milliseconds
 13.1287 +     *
 13.1288 +     * @param  nanos
 13.1289 +     *         {@code 0-999999} additional nanoseconds to wait
 13.1290 +     *
 13.1291 +     * @throws  IllegalArgumentException
 13.1292 +     *          if the value of {@code millis} is negative, or the value
 13.1293 +     *          of {@code nanos} is not in the range {@code 0-999999}
 13.1294 +     *
 13.1295 +     * @throws  InterruptedException
 13.1296 +     *          if any thread has interrupted the current thread. The
 13.1297 +     *          <i>interrupted status</i> of the current thread is
 13.1298 +     *          cleared when this exception is thrown.
 13.1299 +     */
 13.1300 +    public final synchronized void join(long millis, int nanos)
 13.1301 +    throws InterruptedException {
 13.1302 +
 13.1303 +        if (millis < 0) {
 13.1304 +            throw new IllegalArgumentException("timeout value is negative");
 13.1305 +        }
 13.1306 +
 13.1307 +        if (nanos < 0 || nanos > 999999) {
 13.1308 +            throw new IllegalArgumentException(
 13.1309 +                                "nanosecond timeout value out of range");
 13.1310 +        }
 13.1311 +
 13.1312 +        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
 13.1313 +            millis++;
 13.1314 +        }
 13.1315 +
 13.1316 +        join(millis);
 13.1317 +    }
 13.1318 +
 13.1319 +    /**
 13.1320 +     * Waits for this thread to die.
 13.1321 +     *
 13.1322 +     * <p> An invocation of this method behaves in exactly the same
 13.1323 +     * way as the invocation
 13.1324 +     *
 13.1325 +     * <blockquote>
 13.1326 +     * {@linkplain #join(long) join}{@code (0)}
 13.1327 +     * </blockquote>
 13.1328 +     *
 13.1329 +     * @throws  InterruptedException
 13.1330 +     *          if any thread has interrupted the current thread. The
 13.1331 +     *          <i>interrupted status</i> of the current thread is
 13.1332 +     *          cleared when this exception is thrown.
 13.1333 +     */
 13.1334 +    public final void join() throws InterruptedException {
 13.1335 +        join(0);
 13.1336 +    }
 13.1337 +
 13.1338 +    /**
 13.1339 +     * Prints a stack trace of the current thread to the standard error stream.
 13.1340 +     * This method is used only for debugging.
 13.1341 +     *
 13.1342 +     * @see     Throwable#printStackTrace()
 13.1343 +     */
 13.1344 +    public static void dumpStack() {
 13.1345 +        new Exception("Stack trace").printStackTrace();
 13.1346 +    }
 13.1347 +
 13.1348 +    /**
 13.1349 +     * Marks this thread as either a {@linkplain #isDaemon daemon} thread
 13.1350 +     * or a user thread. The Java Virtual Machine exits when the only
 13.1351 +     * threads running are all daemon threads.
 13.1352 +     *
 13.1353 +     * <p> This method must be invoked before the thread is started.
 13.1354 +     *
 13.1355 +     * @param  on
 13.1356 +     *         if {@code true}, marks this thread as a daemon thread
 13.1357 +     *
 13.1358 +     * @throws  IllegalThreadStateException
 13.1359 +     *          if this thread is {@linkplain #isAlive alive}
 13.1360 +     *
 13.1361 +     * @throws  SecurityException
 13.1362 +     *          if {@link #checkAccess} determines that the current
 13.1363 +     *          thread cannot modify this thread
 13.1364 +     */
 13.1365 +    public final void setDaemon(boolean on) {
 13.1366 +        checkAccess();
 13.1367 +        if (isAlive()) {
 13.1368 +            throw new IllegalThreadStateException();
 13.1369 +        }
 13.1370 +        daemon = on;
 13.1371 +    }
 13.1372 +
 13.1373 +    /**
 13.1374 +     * Tests if this thread is a daemon thread.
 13.1375 +     *
 13.1376 +     * @return  <code>true</code> if this thread is a daemon thread;
 13.1377 +     *          <code>false</code> otherwise.
 13.1378 +     * @see     #setDaemon(boolean)
 13.1379 +     */
 13.1380 +    public final boolean isDaemon() {
 13.1381 +        return daemon;
 13.1382 +    }
 13.1383 +
 13.1384 +    /**
 13.1385 +     * Determines if the currently running thread has permission to
 13.1386 +     * modify this thread.
 13.1387 +     * <p>
 13.1388 +     * If there is a security manager, its <code>checkAccess</code> method
 13.1389 +     * is called with this thread as its argument. This may result in
 13.1390 +     * throwing a <code>SecurityException</code>.
 13.1391 +     *
 13.1392 +     * @exception  SecurityException  if the current thread is not allowed to
 13.1393 +     *               access this thread.
 13.1394 +     * @see        SecurityManager#checkAccess(Thread)
 13.1395 +     */
 13.1396 +    public final void checkAccess() {
 13.1397 +        SecurityManager security = System.getSecurityManager();
 13.1398 +        if (security != null) {
 13.1399 +            security.checkAccess(this);
 13.1400 +        }
 13.1401 +    }
 13.1402 +
 13.1403 +    /**
 13.1404 +     * Returns a string representation of this thread, including the
 13.1405 +     * thread's name, priority, and thread group.
 13.1406 +     *
 13.1407 +     * @return  a string representation of this thread.
 13.1408 +     */
 13.1409 +    public String toString() {
 13.1410 +        ThreadGroup group = getThreadGroup();
 13.1411 +        if (group != null) {
 13.1412 +            return "Thread[" + getName() + "," + getPriority() + "," +
 13.1413 +                           group.getName() + "]";
 13.1414 +        } else {
 13.1415 +            return "Thread[" + getName() + "," + getPriority() + "," +
 13.1416 +                            "" + "]";
 13.1417 +        }
 13.1418 +    }
 13.1419 +
 13.1420 +    /**
 13.1421 +     * Returns the context ClassLoader for this Thread. The context
 13.1422 +     * ClassLoader is provided by the creator of the thread for use
 13.1423 +     * by code running in this thread when loading classes and resources.
 13.1424 +     * If not {@linkplain #setContextClassLoader set}, the default is the
 13.1425 +     * ClassLoader context of the parent Thread. The context ClassLoader of the
 13.1426 +     * primordial thread is typically set to the class loader used to load the
 13.1427 +     * application.
 13.1428 +     *
 13.1429 +     * <p>If a security manager is present, and the invoker's class loader is not
 13.1430 +     * {@code null} and is not the same as or an ancestor of the context class
 13.1431 +     * loader, then this method invokes the security manager's {@link
 13.1432 +     * SecurityManager#checkPermission(java.security.Permission) checkPermission}
 13.1433 +     * method with a {@link RuntimePermission RuntimePermission}{@code
 13.1434 +     * ("getClassLoader")} permission to verify that retrieval of the context
 13.1435 +     * class loader is permitted.
 13.1436 +     *
 13.1437 +     * @return  the context ClassLoader for this Thread, or {@code null}
 13.1438 +     *          indicating the system class loader (or, failing that, the
 13.1439 +     *          bootstrap class loader)
 13.1440 +     *
 13.1441 +     * @throws  SecurityException
 13.1442 +     *          if the current thread cannot get the context ClassLoader
 13.1443 +     *
 13.1444 +     * @since 1.2
 13.1445 +     */
 13.1446 +    public ClassLoader getContextClassLoader() {
 13.1447 +        if (contextClassLoader == null)
 13.1448 +            return null;
 13.1449 +        SecurityManager sm = System.getSecurityManager();
 13.1450 +        if (sm != null) {
 13.1451 +            ClassLoader ccl = ClassLoader.getCallerClassLoader();
 13.1452 +            if (ccl != null && ccl != contextClassLoader &&
 13.1453 +                    !contextClassLoader.isAncestor(ccl)) {
 13.1454 +                sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
 13.1455 +            }
 13.1456 +        }
 13.1457 +        return contextClassLoader;
 13.1458 +    }
 13.1459 +
 13.1460 +    /**
 13.1461 +     * Sets the context ClassLoader for this Thread. The context
 13.1462 +     * ClassLoader can be set when a thread is created, and allows
 13.1463 +     * the creator of the thread to provide the appropriate class loader,
 13.1464 +     * through {@code getContextClassLoader}, to code running in the thread
 13.1465 +     * when loading classes and resources.
 13.1466 +     *
 13.1467 +     * <p>If a security manager is present, its {@link
 13.1468 +     * SecurityManager#checkPermission(java.security.Permission) checkPermission}
 13.1469 +     * method is invoked with a {@link RuntimePermission RuntimePermission}{@code
 13.1470 +     * ("setContextClassLoader")} permission to see if setting the context
 13.1471 +     * ClassLoader is permitted.
 13.1472 +     *
 13.1473 +     * @param  cl
 13.1474 +     *         the context ClassLoader for this Thread, or null  indicating the
 13.1475 +     *         system class loader (or, failing that, the bootstrap class loader)
 13.1476 +     *
 13.1477 +     * @throws  SecurityException
 13.1478 +     *          if the current thread cannot set the context ClassLoader
 13.1479 +     *
 13.1480 +     * @since 1.2
 13.1481 +     */
 13.1482 +    public void setContextClassLoader(ClassLoader cl) {
 13.1483 +        SecurityManager sm = System.getSecurityManager();
 13.1484 +        if (sm != null) {
 13.1485 +            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
 13.1486 +        }
 13.1487 +        contextClassLoader = cl;
 13.1488 +    }
 13.1489 +
 13.1490 +    /**
 13.1491 +     * Returns <tt>true</tt> if and only if the current thread holds the
 13.1492 +     * monitor lock on the specified object.
 13.1493 +     *
 13.1494 +     * <p>This method is designed to allow a program to assert that
 13.1495 +     * the current thread already holds a specified lock:
 13.1496 +     * <pre>
 13.1497 +     *     assert Thread.holdsLock(obj);
 13.1498 +     * </pre>
 13.1499 +     *
 13.1500 +     * @param  obj the object on which to test lock ownership
 13.1501 +     * @throws NullPointerException if obj is <tt>null</tt>
 13.1502 +     * @return <tt>true</tt> if the current thread holds the monitor lock on
 13.1503 +     *         the specified object.
 13.1504 +     * @since 1.4
 13.1505 +     */
 13.1506 +    public static native boolean holdsLock(Object obj);
 13.1507 +
 13.1508 +    private static final StackTraceElement[] EMPTY_STACK_TRACE
 13.1509 +        = new StackTraceElement[0];
 13.1510 +
 13.1511 +    /**
 13.1512 +     * Returns an array of stack trace elements representing the stack dump
 13.1513 +     * of this thread.  This method will return a zero-length array if
 13.1514 +     * this thread has not started, has started but has not yet been
 13.1515 +     * scheduled to run by the system, or has terminated.
 13.1516 +     * If the returned array is of non-zero length then the first element of
 13.1517 +     * the array represents the top of the stack, which is the most recent
 13.1518 +     * method invocation in the sequence.  The last element of the array
 13.1519 +     * represents the bottom of the stack, which is the least recent method
 13.1520 +     * invocation in the sequence.
 13.1521 +     *
 13.1522 +     * <p>If there is a security manager, and this thread is not
 13.1523 +     * the current thread, then the security manager's
 13.1524 +     * <tt>checkPermission</tt> method is called with a
 13.1525 +     * <tt>RuntimePermission("getStackTrace")</tt> permission
 13.1526 +     * to see if it's ok to get the stack trace.
 13.1527 +     *
 13.1528 +     * <p>Some virtual machines may, under some circumstances, omit one
 13.1529 +     * or more stack frames from the stack trace.  In the extreme case,
 13.1530 +     * a virtual machine that has no stack trace information concerning
 13.1531 +     * this thread is permitted to return a zero-length array from this
 13.1532 +     * method.
 13.1533 +     *
 13.1534 +     * @return an array of <tt>StackTraceElement</tt>,
 13.1535 +     * each represents one stack frame.
 13.1536 +     *
 13.1537 +     * @throws SecurityException
 13.1538 +     *        if a security manager exists and its
 13.1539 +     *        <tt>checkPermission</tt> method doesn't allow
 13.1540 +     *        getting the stack trace of thread.
 13.1541 +     * @see SecurityManager#checkPermission
 13.1542 +     * @see RuntimePermission
 13.1543 +     * @see Throwable#getStackTrace
 13.1544 +     *
 13.1545 +     * @since 1.5
 13.1546 +     */
 13.1547 +    public StackTraceElement[] getStackTrace() {
 13.1548 +        if (this != Thread.currentThread()) {
 13.1549 +            // check for getStackTrace permission
 13.1550 +            SecurityManager security = System.getSecurityManager();
 13.1551 +            if (security != null) {
 13.1552 +                security.checkPermission(
 13.1553 +                    SecurityConstants.GET_STACK_TRACE_PERMISSION);
 13.1554 +            }
 13.1555 +            // optimization so we do not call into the vm for threads that
 13.1556 +            // have not yet started or have terminated
 13.1557 +            if (!isAlive()) {
 13.1558 +                return EMPTY_STACK_TRACE;
 13.1559 +            }
 13.1560 +            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
 13.1561 +            StackTraceElement[] stackTrace = stackTraceArray[0];
 13.1562 +            // a thread that was alive during the previous isAlive call may have
 13.1563 +            // since terminated, therefore not having a stacktrace.
 13.1564 +            if (stackTrace == null) {
 13.1565 +                stackTrace = EMPTY_STACK_TRACE;
 13.1566 +            }
 13.1567 +            return stackTrace;
 13.1568 +        } else {
 13.1569 +            // Don't need JVM help for current thread
 13.1570 +            return (new Exception()).getStackTrace();
 13.1571 +        }
 13.1572 +    }
 13.1573 +
 13.1574 +    /**
 13.1575 +     * Returns a map of stack traces for all live threads.
 13.1576 +     * The map keys are threads and each map value is an array of
 13.1577 +     * <tt>StackTraceElement</tt> that represents the stack dump
 13.1578 +     * of the corresponding <tt>Thread</tt>.
 13.1579 +     * The returned stack traces are in the format specified for
 13.1580 +     * the {@link #getStackTrace getStackTrace} method.
 13.1581 +     *
 13.1582 +     * <p>The threads may be executing while this method is called.
 13.1583 +     * The stack trace of each thread only represents a snapshot and
 13.1584 +     * each stack trace may be obtained at different time.  A zero-length
 13.1585 +     * array will be returned in the map value if the virtual machine has
 13.1586 +     * no stack trace information about a thread.
 13.1587 +     *
 13.1588 +     * <p>If there is a security manager, then the security manager's
 13.1589 +     * <tt>checkPermission</tt> method is called with a
 13.1590 +     * <tt>RuntimePermission("getStackTrace")</tt> permission as well as
 13.1591 +     * <tt>RuntimePermission("modifyThreadGroup")</tt> permission
 13.1592 +     * to see if it is ok to get the stack trace of all threads.
 13.1593 +     *
 13.1594 +     * @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
 13.1595 +     * <tt>StackTraceElement</tt> that represents the stack trace of
 13.1596 +     * the corresponding thread.
 13.1597 +     *
 13.1598 +     * @throws SecurityException
 13.1599 +     *        if a security manager exists and its
 13.1600 +     *        <tt>checkPermission</tt> method doesn't allow
 13.1601 +     *        getting the stack trace of thread.
 13.1602 +     * @see #getStackTrace
 13.1603 +     * @see SecurityManager#checkPermission
 13.1604 +     * @see RuntimePermission
 13.1605 +     * @see Throwable#getStackTrace
 13.1606 +     *
 13.1607 +     * @since 1.5
 13.1608 +     */
 13.1609 +    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
 13.1610 +        // check for getStackTrace permission
 13.1611 +        SecurityManager security = System.getSecurityManager();
 13.1612 +        if (security != null) {
 13.1613 +            security.checkPermission(
 13.1614 +                SecurityConstants.GET_STACK_TRACE_PERMISSION);
 13.1615 +            security.checkPermission(
 13.1616 +                SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
 13.1617 +        }
 13.1618 +
 13.1619 +        // Get a snapshot of the list of all threads
 13.1620 +        Thread[] threads = getThreads();
 13.1621 +        StackTraceElement[][] traces = dumpThreads(threads);
 13.1622 +        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
 13.1623 +        for (int i = 0; i < threads.length; i++) {
 13.1624 +            StackTraceElement[] stackTrace = traces[i];
 13.1625 +            if (stackTrace != null) {
 13.1626 +                m.put(threads[i], stackTrace);
 13.1627 +            }
 13.1628 +            // else terminated so we don't put it in the map
 13.1629 +        }
 13.1630 +        return m;
 13.1631 +    }
 13.1632 +
 13.1633 +
 13.1634 +    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
 13.1635 +                    new RuntimePermission("enableContextClassLoaderOverride");
 13.1636 +
 13.1637 +    /** cache of subclass security audit results */
 13.1638 +    /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
 13.1639 +     * release */
 13.1640 +    private static class Caches {
 13.1641 +        /** cache of subclass security audit results */
 13.1642 +        static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
 13.1643 +            new ConcurrentHashMap<>();
 13.1644 +
 13.1645 +        /** queue for WeakReferences to audited subclasses */
 13.1646 +        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
 13.1647 +            new ReferenceQueue<>();
 13.1648 +    }
 13.1649 +
 13.1650 +    /**
 13.1651 +     * Verifies that this (possibly subclass) instance can be constructed
 13.1652 +     * without violating security constraints: the subclass must not override
 13.1653 +     * security-sensitive non-final methods, or else the
 13.1654 +     * "enableContextClassLoaderOverride" RuntimePermission is checked.
 13.1655 +     */
 13.1656 +    private static boolean isCCLOverridden(Class cl) {
 13.1657 +        if (cl == Thread.class)
 13.1658 +            return false;
 13.1659 +
 13.1660 +        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
 13.1661 +        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
 13.1662 +        Boolean result = Caches.subclassAudits.get(key);
 13.1663 +        if (result == null) {
 13.1664 +            result = Boolean.valueOf(auditSubclass(cl));
 13.1665 +            Caches.subclassAudits.putIfAbsent(key, result);
 13.1666 +        }
 13.1667 +
 13.1668 +        return result.booleanValue();
 13.1669 +    }
 13.1670 +
 13.1671 +    /**
 13.1672 +     * Performs reflective checks on given subclass to verify that it doesn't
 13.1673 +     * override security-sensitive non-final methods.  Returns true if the
 13.1674 +     * subclass overrides any of the methods, false otherwise.
 13.1675 +     */
 13.1676 +    private static boolean auditSubclass(final Class subcl) {
 13.1677 +        Boolean result = AccessController.doPrivileged(
 13.1678 +            new PrivilegedAction<Boolean>() {
 13.1679 +                public Boolean run() {
 13.1680 +                    for (Class cl = subcl;
 13.1681 +                         cl != Thread.class;
 13.1682 +                         cl = cl.getSuperclass())
 13.1683 +                    {
 13.1684 +                        try {
 13.1685 +                            cl.getDeclaredMethod("getContextClassLoader", new Class[0]);
 13.1686 +                            return Boolean.TRUE;
 13.1687 +                        } catch (NoSuchMethodException ex) {
 13.1688 +                        }
 13.1689 +                        try {
 13.1690 +                            Class[] params = {ClassLoader.class};
 13.1691 +                            cl.getDeclaredMethod("setContextClassLoader", params);
 13.1692 +                            return Boolean.TRUE;
 13.1693 +                        } catch (NoSuchMethodException ex) {
 13.1694 +                        }
 13.1695 +                    }
 13.1696 +                    return Boolean.FALSE;
 13.1697 +                }
 13.1698 +            }
 13.1699 +        );
 13.1700 +        return result.booleanValue();
 13.1701 +    }
 13.1702 +
 13.1703 +    private native static StackTraceElement[][] dumpThreads(Thread[] threads);
 13.1704 +    private native static Thread[] getThreads();
 13.1705 +
 13.1706 +    /**
 13.1707 +     * Returns the identifier of this Thread.  The thread ID is a positive
 13.1708 +     * <tt>long</tt> number generated when this thread was created.
 13.1709 +     * The thread ID is unique and remains unchanged during its lifetime.
 13.1710 +     * When a thread is terminated, this thread ID may be reused.
 13.1711 +     *
 13.1712 +     * @return this thread's ID.
 13.1713 +     * @since 1.5
 13.1714 +     */
 13.1715 +    public long getId() {
 13.1716 +        return tid;
 13.1717 +    }
 13.1718 +
 13.1719 +    /**
 13.1720 +     * A thread state.  A thread can be in one of the following states:
 13.1721 +     * <ul>
 13.1722 +     * <li>{@link #NEW}<br>
 13.1723 +     *     A thread that has not yet started is in this state.
 13.1724 +     *     </li>
 13.1725 +     * <li>{@link #RUNNABLE}<br>
 13.1726 +     *     A thread executing in the Java virtual machine is in this state.
 13.1727 +     *     </li>
 13.1728 +     * <li>{@link #BLOCKED}<br>
 13.1729 +     *     A thread that is blocked waiting for a monitor lock
 13.1730 +     *     is in this state.
 13.1731 +     *     </li>
 13.1732 +     * <li>{@link #WAITING}<br>
 13.1733 +     *     A thread that is waiting indefinitely for another thread to
 13.1734 +     *     perform a particular action is in this state.
 13.1735 +     *     </li>
 13.1736 +     * <li>{@link #TIMED_WAITING}<br>
 13.1737 +     *     A thread that is waiting for another thread to perform an action
 13.1738 +     *     for up to a specified waiting time is in this state.
 13.1739 +     *     </li>
 13.1740 +     * <li>{@link #TERMINATED}<br>
 13.1741 +     *     A thread that has exited is in this state.
 13.1742 +     *     </li>
 13.1743 +     * </ul>
 13.1744 +     *
 13.1745 +     * <p>
 13.1746 +     * A thread can be in only one state at a given point in time.
 13.1747 +     * These states are virtual machine states which do not reflect
 13.1748 +     * any operating system thread states.
 13.1749 +     *
 13.1750 +     * @since   1.5
 13.1751 +     * @see #getState
 13.1752 +     */
 13.1753 +    public enum State {
 13.1754 +        /**
 13.1755 +         * Thread state for a thread which has not yet started.
 13.1756 +         */
 13.1757 +        NEW,
 13.1758 +
 13.1759 +        /**
 13.1760 +         * Thread state for a runnable thread.  A thread in the runnable
 13.1761 +         * state is executing in the Java virtual machine but it may
 13.1762 +         * be waiting for other resources from the operating system
 13.1763 +         * such as processor.
 13.1764 +         */
 13.1765 +        RUNNABLE,
 13.1766 +
 13.1767 +        /**
 13.1768 +         * Thread state for a thread blocked waiting for a monitor lock.
 13.1769 +         * A thread in the blocked state is waiting for a monitor lock
 13.1770 +         * to enter a synchronized block/method or
 13.1771 +         * reenter a synchronized block/method after calling
 13.1772 +         * {@link Object#wait() Object.wait}.
 13.1773 +         */
 13.1774 +        BLOCKED,
 13.1775 +
 13.1776 +        /**
 13.1777 +         * Thread state for a waiting thread.
 13.1778 +         * A thread is in the waiting state due to calling one of the
 13.1779 +         * following methods:
 13.1780 +         * <ul>
 13.1781 +         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
 13.1782 +         *   <li>{@link #join() Thread.join} with no timeout</li>
 13.1783 +         *   <li>{@link LockSupport#park() LockSupport.park}</li>
 13.1784 +         * </ul>
 13.1785 +         *
 13.1786 +         * <p>A thread in the waiting state is waiting for another thread to
 13.1787 +         * perform a particular action.
 13.1788 +         *
 13.1789 +         * For example, a thread that has called <tt>Object.wait()</tt>
 13.1790 +         * on an object is waiting for another thread to call
 13.1791 +         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
 13.1792 +         * that object. A thread that has called <tt>Thread.join()</tt>
 13.1793 +         * is waiting for a specified thread to terminate.
 13.1794 +         */
 13.1795 +        WAITING,
 13.1796 +
 13.1797 +        /**
 13.1798 +         * Thread state for a waiting thread with a specified waiting time.
 13.1799 +         * A thread is in the timed waiting state due to calling one of
 13.1800 +         * the following methods with a specified positive waiting time:
 13.1801 +         * <ul>
 13.1802 +         *   <li>{@link #sleep Thread.sleep}</li>
 13.1803 +         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
 13.1804 +         *   <li>{@link #join(long) Thread.join} with timeout</li>
 13.1805 +         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
 13.1806 +         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
 13.1807 +         * </ul>
 13.1808 +         */
 13.1809 +        TIMED_WAITING,
 13.1810 +
 13.1811 +        /**
 13.1812 +         * Thread state for a terminated thread.
 13.1813 +         * The thread has completed execution.
 13.1814 +         */
 13.1815 +        TERMINATED;
 13.1816 +    }
 13.1817 +
 13.1818 +    /**
 13.1819 +     * Returns the state of this thread.
 13.1820 +     * This method is designed for use in monitoring of the system state,
 13.1821 +     * not for synchronization control.
 13.1822 +     *
 13.1823 +     * @return this thread's state.
 13.1824 +     * @since 1.5
 13.1825 +     */
 13.1826 +    public State getState() {
 13.1827 +        // get current thread state
 13.1828 +        return sun.misc.VM.toThreadState(threadStatus);
 13.1829 +    }
 13.1830 +
 13.1831 +    // Added in JSR-166
 13.1832 +
 13.1833 +    /**
 13.1834 +     * Interface for handlers invoked when a <tt>Thread</tt> abruptly
 13.1835 +     * terminates due to an uncaught exception.
 13.1836 +     * <p>When a thread is about to terminate due to an uncaught exception
 13.1837 +     * the Java Virtual Machine will query the thread for its
 13.1838 +     * <tt>UncaughtExceptionHandler</tt> using
 13.1839 +     * {@link #getUncaughtExceptionHandler} and will invoke the handler's
 13.1840 +     * <tt>uncaughtException</tt> method, passing the thread and the
 13.1841 +     * exception as arguments.
 13.1842 +     * If a thread has not had its <tt>UncaughtExceptionHandler</tt>
 13.1843 +     * explicitly set, then its <tt>ThreadGroup</tt> object acts as its
 13.1844 +     * <tt>UncaughtExceptionHandler</tt>. If the <tt>ThreadGroup</tt> object
 13.1845 +     * has no
 13.1846 +     * special requirements for dealing with the exception, it can forward
 13.1847 +     * the invocation to the {@linkplain #getDefaultUncaughtExceptionHandler
 13.1848 +     * default uncaught exception handler}.
 13.1849 +     *
 13.1850 +     * @see #setDefaultUncaughtExceptionHandler
 13.1851 +     * @see #setUncaughtExceptionHandler
 13.1852 +     * @see ThreadGroup#uncaughtException
 13.1853 +     * @since 1.5
 13.1854 +     */
 13.1855 +    public interface UncaughtExceptionHandler {
 13.1856 +        /**
 13.1857 +         * Method invoked when the given thread terminates due to the
 13.1858 +         * given uncaught exception.
 13.1859 +         * <p>Any exception thrown by this method will be ignored by the
 13.1860 +         * Java Virtual Machine.
 13.1861 +         * @param t the thread
 13.1862 +         * @param e the exception
 13.1863 +         */
 13.1864 +        void uncaughtException(Thread t, Throwable e);
 13.1865 +    }
 13.1866 +
 13.1867 +    // null unless explicitly set
 13.1868 +    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
 13.1869 +
 13.1870 +    // null unless explicitly set
 13.1871 +    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
 13.1872 +
 13.1873 +    /**
 13.1874 +     * Set the default handler invoked when a thread abruptly terminates
 13.1875 +     * due to an uncaught exception, and no other handler has been defined
 13.1876 +     * for that thread.
 13.1877 +     *
 13.1878 +     * <p>Uncaught exception handling is controlled first by the thread, then
 13.1879 +     * by the thread's {@link ThreadGroup} object and finally by the default
 13.1880 +     * uncaught exception handler. If the thread does not have an explicit
 13.1881 +     * uncaught exception handler set, and the thread's thread group
 13.1882 +     * (including parent thread groups)  does not specialize its
 13.1883 +     * <tt>uncaughtException</tt> method, then the default handler's
 13.1884 +     * <tt>uncaughtException</tt> method will be invoked.
 13.1885 +     * <p>By setting the default uncaught exception handler, an application
 13.1886 +     * can change the way in which uncaught exceptions are handled (such as
 13.1887 +     * logging to a specific device, or file) for those threads that would
 13.1888 +     * already accept whatever &quot;default&quot; behavior the system
 13.1889 +     * provided.
 13.1890 +     *
 13.1891 +     * <p>Note that the default uncaught exception handler should not usually
 13.1892 +     * defer to the thread's <tt>ThreadGroup</tt> object, as that could cause
 13.1893 +     * infinite recursion.
 13.1894 +     *
 13.1895 +     * @param eh the object to use as the default uncaught exception handler.
 13.1896 +     * If <tt>null</tt> then there is no default handler.
 13.1897 +     *
 13.1898 +     * @throws SecurityException if a security manager is present and it
 13.1899 +     *         denies <tt>{@link RuntimePermission}
 13.1900 +     *         (&quot;setDefaultUncaughtExceptionHandler&quot;)</tt>
 13.1901 +     *
 13.1902 +     * @see #setUncaughtExceptionHandler
 13.1903 +     * @see #getUncaughtExceptionHandler
 13.1904 +     * @see ThreadGroup#uncaughtException
 13.1905 +     * @since 1.5
 13.1906 +     */
 13.1907 +    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
 13.1908 +        SecurityManager sm = System.getSecurityManager();
 13.1909 +        if (sm != null) {
 13.1910 +            sm.checkPermission(
 13.1911 +                new RuntimePermission("setDefaultUncaughtExceptionHandler")
 13.1912 +                    );
 13.1913 +        }
 13.1914 +
 13.1915 +         defaultUncaughtExceptionHandler = eh;
 13.1916 +     }
 13.1917 +
 13.1918 +    /**
 13.1919 +     * Returns the default handler invoked when a thread abruptly terminates
 13.1920 +     * due to an uncaught exception. If the returned value is <tt>null</tt>,
 13.1921 +     * there is no default.
 13.1922 +     * @since 1.5
 13.1923 +     * @see #setDefaultUncaughtExceptionHandler
 13.1924 +     */
 13.1925 +    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
 13.1926 +        return defaultUncaughtExceptionHandler;
 13.1927 +    }
 13.1928 +
 13.1929 +    /**
 13.1930 +     * Returns the handler invoked when this thread abruptly terminates
 13.1931 +     * due to an uncaught exception. If this thread has not had an
 13.1932 +     * uncaught exception handler explicitly set then this thread's
 13.1933 +     * <tt>ThreadGroup</tt> object is returned, unless this thread
 13.1934 +     * has terminated, in which case <tt>null</tt> is returned.
 13.1935 +     * @since 1.5
 13.1936 +     */
 13.1937 +    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
 13.1938 +        return uncaughtExceptionHandler != null ?
 13.1939 +            uncaughtExceptionHandler : group;
 13.1940 +    }
 13.1941 +
 13.1942 +    /**
 13.1943 +     * Set the handler invoked when this thread abruptly terminates
 13.1944 +     * due to an uncaught exception.
 13.1945 +     * <p>A thread can take full control of how it responds to uncaught
 13.1946 +     * exceptions by having its uncaught exception handler explicitly set.
 13.1947 +     * If no such handler is set then the thread's <tt>ThreadGroup</tt>
 13.1948 +     * object acts as its handler.
 13.1949 +     * @param eh the object to use as this thread's uncaught exception
 13.1950 +     * handler. If <tt>null</tt> then this thread has no explicit handler.
 13.1951 +     * @throws  SecurityException  if the current thread is not allowed to
 13.1952 +     *          modify this thread.
 13.1953 +     * @see #setDefaultUncaughtExceptionHandler
 13.1954 +     * @see ThreadGroup#uncaughtException
 13.1955 +     * @since 1.5
 13.1956 +     */
 13.1957 +    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
 13.1958 +        checkAccess();
 13.1959 +        uncaughtExceptionHandler = eh;
 13.1960 +    }
 13.1961 +
 13.1962 +    /**
 13.1963 +     * Dispatch an uncaught exception to the handler. This method is
 13.1964 +     * intended to be called only by the JVM.
 13.1965 +     */
 13.1966 +    private void dispatchUncaughtException(Throwable e) {
 13.1967 +        getUncaughtExceptionHandler().uncaughtException(this, e);
 13.1968 +    }
 13.1969 +
 13.1970 +    /**
 13.1971 +     * Removes from the specified map any keys that have been enqueued
 13.1972 +     * on the specified reference queue.
 13.1973 +     */
 13.1974 +    static void processQueue(ReferenceQueue<Class<?>> queue,
 13.1975 +                             ConcurrentMap<? extends
 13.1976 +                             WeakReference<Class<?>>, ?> map)
 13.1977 +    {
 13.1978 +        Reference<? extends Class<?>> ref;
 13.1979 +        while((ref = queue.poll()) != null) {
 13.1980 +            map.remove(ref);
 13.1981 +        }
 13.1982 +    }
 13.1983 +
 13.1984 +    /**
 13.1985 +     *  Weak key for Class objects.
 13.1986 +     **/
 13.1987 +    static class WeakClassKey extends WeakReference<Class<?>> {
 13.1988 +        /**
 13.1989 +         * saved value of the referent's identity hash code, to maintain
 13.1990 +         * a consistent hash code after the referent has been cleared
 13.1991 +         */
 13.1992 +        private final int hash;
 13.1993 +
 13.1994 +        /**
 13.1995 +         * Create a new WeakClassKey to the given object, registered
 13.1996 +         * with a queue.
 13.1997 +         */
 13.1998 +        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
 13.1999 +            super(cl, refQueue);
 13.2000 +            hash = System.identityHashCode(cl);
 13.2001 +        }
 13.2002 +
 13.2003 +        /**
 13.2004 +         * Returns the identity hash code of the original referent.
 13.2005 +         */
 13.2006 +        @Override
 13.2007 +        public int hashCode() {
 13.2008 +            return hash;
 13.2009 +        }
 13.2010 +
 13.2011 +        /**
 13.2012 +         * Returns true if the given object is this identical
 13.2013 +         * WeakClassKey instance, or, if this object's referent has not
 13.2014 +         * been cleared, if the given object is another WeakClassKey
 13.2015 +         * instance with the identical non-null referent as this one.
 13.2016 +         */
 13.2017 +        @Override
 13.2018 +        public boolean equals(Object obj) {
 13.2019 +            if (obj == this)
 13.2020 +                return true;
 13.2021 +
 13.2022 +            if (obj instanceof WeakClassKey) {
 13.2023 +                Object referent = get();
 13.2024 +                return (referent != null) &&
 13.2025 +                       (referent == ((WeakClassKey) obj).get());
 13.2026 +            } else {
 13.2027 +                return false;
 13.2028 +            }
 13.2029 +        }
 13.2030 +    }
 13.2031 +
 13.2032 +    /* Some private helper methods */
 13.2033 +    private native void setPriority0(int newPriority);
 13.2034 +    private native void stop0(Object o);
 13.2035 +    private native void suspend0();
 13.2036 +    private native void resume0();
 13.2037 +    private native void interrupt0();
 13.2038 +}
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/rt/emul/compact/src/main/java/java/math/BigDecimal.java	Sat Sep 07 13:55:09 2013 +0200
    14.3 @@ -0,0 +1,3855 @@
    14.4 +/*
    14.5 + * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    14.7 + *
    14.8 + * This code is free software; you can redistribute it and/or modify it
    14.9 + * under the terms of the GNU General Public License version 2 only, as
   14.10 + * published by the Free Software Foundation.  Oracle designates this
   14.11 + * particular file as subject to the "Classpath" exception as provided
   14.12 + * by Oracle in the LICENSE file that accompanied this code.
   14.13 + *
   14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14.17 + * version 2 for more details (a copy is included in the LICENSE file that
   14.18 + * accompanied this code).
   14.19 + *
   14.20 + * You should have received a copy of the GNU General Public License version
   14.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   14.23 + *
   14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   14.25 + * or visit www.oracle.com if you need additional information or have any
   14.26 + * questions.
   14.27 + */
   14.28 +
   14.29 +/*
   14.30 + * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
   14.31 + */
   14.32 +
   14.33 +package java.math;
   14.34 +
   14.35 +import java.util.Arrays;
   14.36 +import static java.math.BigInteger.LONG_MASK;
   14.37 +
   14.38 +/**
   14.39 + * Immutable, arbitrary-precision signed decimal numbers.  A
   14.40 + * {@code BigDecimal} consists of an arbitrary precision integer
   14.41 + * <i>unscaled value</i> and a 32-bit integer <i>scale</i>.  If zero
   14.42 + * or positive, the scale is the number of digits to the right of the
   14.43 + * decimal point.  If negative, the unscaled value of the number is
   14.44 + * multiplied by ten to the power of the negation of the scale.  The
   14.45 + * value of the number represented by the {@code BigDecimal} is
   14.46 + * therefore <tt>(unscaledValue &times; 10<sup>-scale</sup>)</tt>.
   14.47 + *
   14.48 + * <p>The {@code BigDecimal} class provides operations for
   14.49 + * arithmetic, scale manipulation, rounding, comparison, hashing, and
   14.50 + * format conversion.  The {@link #toString} method provides a
   14.51 + * canonical representation of a {@code BigDecimal}.
   14.52 + *
   14.53 + * <p>The {@code BigDecimal} class gives its user complete control
   14.54 + * over rounding behavior.  If no rounding mode is specified and the
   14.55 + * exact result cannot be represented, an exception is thrown;
   14.56 + * otherwise, calculations can be carried out to a chosen precision
   14.57 + * and rounding mode by supplying an appropriate {@link MathContext}
   14.58 + * object to the operation.  In either case, eight <em>rounding
   14.59 + * modes</em> are provided for the control of rounding.  Using the
   14.60 + * integer fields in this class (such as {@link #ROUND_HALF_UP}) to
   14.61 + * represent rounding mode is largely obsolete; the enumeration values
   14.62 + * of the {@code RoundingMode} {@code enum}, (such as {@link
   14.63 + * RoundingMode#HALF_UP}) should be used instead.
   14.64 + *
   14.65 + * <p>When a {@code MathContext} object is supplied with a precision
   14.66 + * setting of 0 (for example, {@link MathContext#UNLIMITED}),
   14.67 + * arithmetic operations are exact, as are the arithmetic methods
   14.68 + * which take no {@code MathContext} object.  (This is the only
   14.69 + * behavior that was supported in releases prior to 5.)  As a
   14.70 + * corollary of computing the exact result, the rounding mode setting
   14.71 + * of a {@code MathContext} object with a precision setting of 0 is
   14.72 + * not used and thus irrelevant.  In the case of divide, the exact
   14.73 + * quotient could have an infinitely long decimal expansion; for
   14.74 + * example, 1 divided by 3.  If the quotient has a nonterminating
   14.75 + * decimal expansion and the operation is specified to return an exact
   14.76 + * result, an {@code ArithmeticException} is thrown.  Otherwise, the
   14.77 + * exact result of the division is returned, as done for other
   14.78 + * operations.
   14.79 + *
   14.80 + * <p>When the precision setting is not 0, the rules of
   14.81 + * {@code BigDecimal} arithmetic are broadly compatible with selected
   14.82 + * modes of operation of the arithmetic defined in ANSI X3.274-1996
   14.83 + * and ANSI X3.274-1996/AM 1-2000 (section 7.4).  Unlike those
   14.84 + * standards, {@code BigDecimal} includes many rounding modes, which
   14.85 + * were mandatory for division in {@code BigDecimal} releases prior
   14.86 + * to 5.  Any conflicts between these ANSI standards and the
   14.87 + * {@code BigDecimal} specification are resolved in favor of
   14.88 + * {@code BigDecimal}.
   14.89 + *
   14.90 + * <p>Since the same numerical value can have different
   14.91 + * representations (with different scales), the rules of arithmetic
   14.92 + * and rounding must specify both the numerical result and the scale
   14.93 + * used in the result's representation.
   14.94 + *
   14.95 + *
   14.96 + * <p>In general the rounding modes and precision setting determine
   14.97 + * how operations return results with a limited number of digits when
   14.98 + * the exact result has more digits (perhaps infinitely many in the
   14.99 + * case of division) than the number of digits returned.
  14.100 + *
  14.101 + * First, the
  14.102 + * total number of digits to return is specified by the
  14.103 + * {@code MathContext}'s {@code precision} setting; this determines
  14.104 + * the result's <i>precision</i>.  The digit count starts from the
  14.105 + * leftmost nonzero digit of the exact result.  The rounding mode
  14.106 + * determines how any discarded trailing digits affect the returned
  14.107 + * result.
  14.108 + *
  14.109 + * <p>For all arithmetic operators , the operation is carried out as
  14.110 + * though an exact intermediate result were first calculated and then
  14.111 + * rounded to the number of digits specified by the precision setting
  14.112 + * (if necessary), using the selected rounding mode.  If the exact
  14.113 + * result is not returned, some digit positions of the exact result
  14.114 + * are discarded.  When rounding increases the magnitude of the
  14.115 + * returned result, it is possible for a new digit position to be
  14.116 + * created by a carry propagating to a leading {@literal "9"} digit.
  14.117 + * For example, rounding the value 999.9 to three digits rounding up
  14.118 + * would be numerically equal to one thousand, represented as
  14.119 + * 100&times;10<sup>1</sup>.  In such cases, the new {@literal "1"} is
  14.120 + * the leading digit position of the returned result.
  14.121 + *
  14.122 + * <p>Besides a logical exact result, each arithmetic operation has a
  14.123 + * preferred scale for representing a result.  The preferred
  14.124 + * scale for each operation is listed in the table below.
  14.125 + *
  14.126 + * <table border>
  14.127 + * <caption><b>Preferred Scales for Results of Arithmetic Operations
  14.128 + * </b></caption>
  14.129 + * <tr><th>Operation</th><th>Preferred Scale of Result</th></tr>
  14.130 + * <tr><td>Add</td><td>max(addend.scale(), augend.scale())</td>
  14.131 + * <tr><td>Subtract</td><td>max(minuend.scale(), subtrahend.scale())</td>
  14.132 + * <tr><td>Multiply</td><td>multiplier.scale() + multiplicand.scale()</td>
  14.133 + * <tr><td>Divide</td><td>dividend.scale() - divisor.scale()</td>
  14.134 + * </table>
  14.135 + *
  14.136 + * These scales are the ones used by the methods which return exact
  14.137 + * arithmetic results; except that an exact divide may have to use a
  14.138 + * larger scale since the exact result may have more digits.  For
  14.139 + * example, {@code 1/32} is {@code 0.03125}.
  14.140 + *
  14.141 + * <p>Before rounding, the scale of the logical exact intermediate
  14.142 + * result is the preferred scale for that operation.  If the exact
  14.143 + * numerical result cannot be represented in {@code precision}
  14.144 + * digits, rounding selects the set of digits to return and the scale
  14.145 + * of the result is reduced from the scale of the intermediate result
  14.146 + * to the least scale which can represent the {@code precision}
  14.147 + * digits actually returned.  If the exact result can be represented
  14.148 + * with at most {@code precision} digits, the representation
  14.149 + * of the result with the scale closest to the preferred scale is
  14.150 + * returned.  In particular, an exactly representable quotient may be
  14.151 + * represented in fewer than {@code precision} digits by removing
  14.152 + * trailing zeros and decreasing the scale.  For example, rounding to
  14.153 + * three digits using the {@linkplain RoundingMode#FLOOR floor}
  14.154 + * rounding mode, <br>
  14.155 + *
  14.156 + * {@code 19/100 = 0.19   // integer=19,  scale=2} <br>
  14.157 + *
  14.158 + * but<br>
  14.159 + *
  14.160 + * {@code 21/110 = 0.190  // integer=190, scale=3} <br>
  14.161 + *
  14.162 + * <p>Note that for add, subtract, and multiply, the reduction in
  14.163 + * scale will equal the number of digit positions of the exact result
  14.164 + * which are discarded. If the rounding causes a carry propagation to
  14.165 + * create a new high-order digit position, an additional digit of the
  14.166 + * result is discarded than when no new digit position is created.
  14.167 + *
  14.168 + * <p>Other methods may have slightly different rounding semantics.
  14.169 + * For example, the result of the {@code pow} method using the
  14.170 + * {@linkplain #pow(int, MathContext) specified algorithm} can
  14.171 + * occasionally differ from the rounded mathematical result by more
  14.172 + * than one unit in the last place, one <i>{@linkplain #ulp() ulp}</i>.
  14.173 + *
  14.174 + * <p>Two types of operations are provided for manipulating the scale
  14.175 + * of a {@code BigDecimal}: scaling/rounding operations and decimal
  14.176 + * point motion operations.  Scaling/rounding operations ({@link
  14.177 + * #setScale setScale} and {@link #round round}) return a
  14.178 + * {@code BigDecimal} whose value is approximately (or exactly) equal
  14.179 + * to that of the operand, but whose scale or precision is the
  14.180 + * specified value; that is, they increase or decrease the precision
  14.181 + * of the stored number with minimal effect on its value.  Decimal
  14.182 + * point motion operations ({@link #movePointLeft movePointLeft} and
  14.183 + * {@link #movePointRight movePointRight}) return a
  14.184 + * {@code BigDecimal} created from the operand by moving the decimal
  14.185 + * point a specified distance in the specified direction.
  14.186 + *
  14.187 + * <p>For the sake of brevity and clarity, pseudo-code is used
  14.188 + * throughout the descriptions of {@code BigDecimal} methods.  The
  14.189 + * pseudo-code expression {@code (i + j)} is shorthand for "a
  14.190 + * {@code BigDecimal} whose value is that of the {@code BigDecimal}
  14.191 + * {@code i} added to that of the {@code BigDecimal}
  14.192 + * {@code j}." The pseudo-code expression {@code (i == j)} is
  14.193 + * shorthand for "{@code true} if and only if the
  14.194 + * {@code BigDecimal} {@code i} represents the same value as the
  14.195 + * {@code BigDecimal} {@code j}." Other pseudo-code expressions
  14.196 + * are interpreted similarly.  Square brackets are used to represent
  14.197 + * the particular {@code BigInteger} and scale pair defining a
  14.198 + * {@code BigDecimal} value; for example [19, 2] is the
  14.199 + * {@code BigDecimal} numerically equal to 0.19 having a scale of 2.
  14.200 + *
  14.201 + * <p>Note: care should be exercised if {@code BigDecimal} objects
  14.202 + * are used as keys in a {@link java.util.SortedMap SortedMap} or
  14.203 + * elements in a {@link java.util.SortedSet SortedSet} since
  14.204 + * {@code BigDecimal}'s <i>natural ordering</i> is <i>inconsistent
  14.205 + * with equals</i>.  See {@link Comparable}, {@link
  14.206 + * java.util.SortedMap} or {@link java.util.SortedSet} for more
  14.207 + * information.
  14.208 + *
  14.209 + * <p>All methods and constructors for this class throw
  14.210 + * {@code NullPointerException} when passed a {@code null} object
  14.211 + * reference for any input parameter.
  14.212 + *
  14.213 + * @see     BigInteger
  14.214 + * @see     MathContext
  14.215 + * @see     RoundingMode
  14.216 + * @see     java.util.SortedMap
  14.217 + * @see     java.util.SortedSet
  14.218 + * @author  Josh Bloch
  14.219 + * @author  Mike Cowlishaw
  14.220 + * @author  Joseph D. Darcy
  14.221 + */
  14.222 +public class BigDecimal extends Number implements Comparable<BigDecimal> {
  14.223 +    /**
  14.224 +     * The unscaled value of this BigDecimal, as returned by {@link
  14.225 +     * #unscaledValue}.
  14.226 +     *
  14.227 +     * @serial
  14.228 +     * @see #unscaledValue
  14.229 +     */
  14.230 +    private volatile BigInteger intVal;
  14.231 +
  14.232 +    /**
  14.233 +     * The scale of this BigDecimal, as returned by {@link #scale}.
  14.234 +     *
  14.235 +     * @serial
  14.236 +     * @see #scale
  14.237 +     */
  14.238 +    private int scale;  // Note: this may have any value, so
  14.239 +                        // calculations must be done in longs
  14.240 +    /**
  14.241 +     * The number of decimal digits in this BigDecimal, or 0 if the
  14.242 +     * number of digits are not known (lookaside information).  If
  14.243 +     * nonzero, the value is guaranteed correct.  Use the precision()
  14.244 +     * method to obtain and set the value if it might be 0.  This
  14.245 +     * field is mutable until set nonzero.
  14.246 +     *
  14.247 +     * @since  1.5
  14.248 +     */
  14.249 +    private transient int precision;
  14.250 +
  14.251 +    /**
  14.252 +     * Used to store the canonical string representation, if computed.
  14.253 +     */
  14.254 +    private transient String stringCache;
  14.255 +
  14.256 +    /**
  14.257 +     * Sentinel value for {@link #intCompact} indicating the
  14.258 +     * significand information is only available from {@code intVal}.
  14.259 +     */
  14.260 +    static final long INFLATED = Long.MIN_VALUE;
  14.261 +
  14.262 +    /**
  14.263 +     * If the absolute value of the significand of this BigDecimal is
  14.264 +     * less than or equal to {@code Long.MAX_VALUE}, the value can be
  14.265 +     * compactly stored in this field and used in computations.
  14.266 +     */
  14.267 +    private transient long intCompact;
  14.268 +
  14.269 +    // All 18-digit base ten strings fit into a long; not all 19-digit
  14.270 +    // strings will
  14.271 +    private static final int MAX_COMPACT_DIGITS = 18;
  14.272 +
  14.273 +    private static final int MAX_BIGINT_BITS = 62;
  14.274 +
  14.275 +    /* Appease the serialization gods */
  14.276 +    private static final long serialVersionUID = 6108874887143696463L;
  14.277 +
  14.278 +    private static final ThreadLocal<StringBuilderHelper>
  14.279 +        threadLocalStringBuilderHelper = new ThreadLocal<StringBuilderHelper>() {
  14.280 +        @Override
  14.281 +        protected StringBuilderHelper initialValue() {
  14.282 +            return new StringBuilderHelper();
  14.283 +        }
  14.284 +    };
  14.285 +
  14.286 +    // Cache of common small BigDecimal values.
  14.287 +    private static final BigDecimal zeroThroughTen[] = {
  14.288 +        new BigDecimal(BigInteger.ZERO,         0,  0, 1),
  14.289 +        new BigDecimal(BigInteger.ONE,          1,  0, 1),
  14.290 +        new BigDecimal(BigInteger.valueOf(2),   2,  0, 1),
  14.291 +        new BigDecimal(BigInteger.valueOf(3),   3,  0, 1),
  14.292 +        new BigDecimal(BigInteger.valueOf(4),   4,  0, 1),
  14.293 +        new BigDecimal(BigInteger.valueOf(5),   5,  0, 1),
  14.294 +        new BigDecimal(BigInteger.valueOf(6),   6,  0, 1),
  14.295 +        new BigDecimal(BigInteger.valueOf(7),   7,  0, 1),
  14.296 +        new BigDecimal(BigInteger.valueOf(8),   8,  0, 1),
  14.297 +        new BigDecimal(BigInteger.valueOf(9),   9,  0, 1),
  14.298 +        new BigDecimal(BigInteger.TEN,          10, 0, 2),
  14.299 +    };
  14.300 +
  14.301 +    // Cache of zero scaled by 0 - 15
  14.302 +    private static final BigDecimal[] ZERO_SCALED_BY = {
  14.303 +        zeroThroughTen[0],
  14.304 +        new BigDecimal(BigInteger.ZERO, 0, 1, 1),
  14.305 +        new BigDecimal(BigInteger.ZERO, 0, 2, 1),
  14.306 +        new BigDecimal(BigInteger.ZERO, 0, 3, 1),
  14.307 +        new BigDecimal(BigInteger.ZERO, 0, 4, 1),
  14.308 +        new BigDecimal(BigInteger.ZERO, 0, 5, 1),
  14.309 +        new BigDecimal(BigInteger.ZERO, 0, 6, 1),
  14.310 +        new BigDecimal(BigInteger.ZERO, 0, 7, 1),
  14.311 +        new BigDecimal(BigInteger.ZERO, 0, 8, 1),
  14.312 +        new BigDecimal(BigInteger.ZERO, 0, 9, 1),
  14.313 +        new BigDecimal(BigInteger.ZERO, 0, 10, 1),
  14.314 +        new BigDecimal(BigInteger.ZERO, 0, 11, 1),
  14.315 +        new BigDecimal(BigInteger.ZERO, 0, 12, 1),
  14.316 +        new BigDecimal(BigInteger.ZERO, 0, 13, 1),
  14.317 +        new BigDecimal(BigInteger.ZERO, 0, 14, 1),
  14.318 +        new BigDecimal(BigInteger.ZERO, 0, 15, 1),
  14.319 +    };
  14.320 +
  14.321 +    // Half of Long.MIN_VALUE & Long.MAX_VALUE.
  14.322 +    private static final long HALF_LONG_MAX_VALUE = Long.MAX_VALUE / 2;
  14.323 +    private static final long HALF_LONG_MIN_VALUE = Long.MIN_VALUE / 2;
  14.324 +
  14.325 +    // Constants
  14.326 +    /**
  14.327 +     * The value 0, with a scale of 0.
  14.328 +     *
  14.329 +     * @since  1.5
  14.330 +     */
  14.331 +    public static final BigDecimal ZERO =
  14.332 +        zeroThroughTen[0];
  14.333 +
  14.334 +    /**
  14.335 +     * The value 1, with a scale of 0.
  14.336 +     *
  14.337 +     * @since  1.5
  14.338 +     */
  14.339 +    public static final BigDecimal ONE =
  14.340 +        zeroThroughTen[1];
  14.341 +
  14.342 +    /**
  14.343 +     * The value 10, with a scale of 0.
  14.344 +     *
  14.345 +     * @since  1.5
  14.346 +     */
  14.347 +    public static final BigDecimal TEN =
  14.348 +        zeroThroughTen[10];
  14.349 +
  14.350 +    // Constructors
  14.351 +
  14.352 +    /**
  14.353 +     * Trusted package private constructor.
  14.354 +     * Trusted simply means if val is INFLATED, intVal could not be null and
  14.355 +     * if intVal is null, val could not be INFLATED.
  14.356 +     */
  14.357 +    BigDecimal(BigInteger intVal, long val, int scale, int prec) {
  14.358 +        this.scale = scale;
  14.359 +        this.precision = prec;
  14.360 +        this.intCompact = val;
  14.361 +        this.intVal = intVal;
  14.362 +    }
  14.363 +
  14.364 +    /**
  14.365 +     * Translates a character array representation of a
  14.366 +     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
  14.367 +     * same sequence of characters as the {@link #BigDecimal(String)}
  14.368 +     * constructor, while allowing a sub-array to be specified.
  14.369 +     *
  14.370 +     * <p>Note that if the sequence of characters is already available
  14.371 +     * within a character array, using this constructor is faster than
  14.372 +     * converting the {@code char} array to string and using the
  14.373 +     * {@code BigDecimal(String)} constructor .
  14.374 +     *
  14.375 +     * @param  in {@code char} array that is the source of characters.
  14.376 +     * @param  offset first character in the array to inspect.
  14.377 +     * @param  len number of characters to consider.
  14.378 +     * @throws NumberFormatException if {@code in} is not a valid
  14.379 +     *         representation of a {@code BigDecimal} or the defined subarray
  14.380 +     *         is not wholly within {@code in}.
  14.381 +     * @since  1.5
  14.382 +     */
  14.383 +    public BigDecimal(char[] in, int offset, int len) {
  14.384 +        // protect against huge length.
  14.385 +        if (offset+len > in.length || offset < 0)
  14.386 +            throw new NumberFormatException();
  14.387 +        // This is the primary string to BigDecimal constructor; all
  14.388 +        // incoming strings end up here; it uses explicit (inline)
  14.389 +        // parsing for speed and generates at most one intermediate
  14.390 +        // (temporary) object (a char[] array) for non-compact case.
  14.391 +
  14.392 +        // Use locals for all fields values until completion
  14.393 +        int prec = 0;                 // record precision value
  14.394 +        int scl = 0;                  // record scale value
  14.395 +        long rs = 0;                  // the compact value in long
  14.396 +        BigInteger rb = null;         // the inflated value in BigInteger
  14.397 +
  14.398 +        // use array bounds checking to handle too-long, len == 0,
  14.399 +        // bad offset, etc.
  14.400 +        try {
  14.401 +            // handle the sign
  14.402 +            boolean isneg = false;          // assume positive
  14.403 +            if (in[offset] == '-') {
  14.404 +                isneg = true;               // leading minus means negative
  14.405 +                offset++;
  14.406 +                len--;
  14.407 +            } else if (in[offset] == '+') { // leading + allowed
  14.408 +                offset++;
  14.409 +                len--;
  14.410 +            }
  14.411 +
  14.412 +            // should now be at numeric part of the significand
  14.413 +            boolean dot = false;             // true when there is a '.'
  14.414 +            int cfirst = offset;             // record start of integer
  14.415 +            long exp = 0;                    // exponent
  14.416 +            char c;                          // current character
  14.417 +
  14.418 +            boolean isCompact = (len <= MAX_COMPACT_DIGITS);
  14.419 +            // integer significand array & idx is the index to it. The array
  14.420 +            // is ONLY used when we can't use a compact representation.
  14.421 +            char coeff[] = isCompact ? null : new char[len];
  14.422 +            int idx = 0;
  14.423 +
  14.424 +            for (; len > 0; offset++, len--) {
  14.425 +                c = in[offset];
  14.426 +                // have digit
  14.427 +                if ((c >= '0' && c <= '9') || Character.isDigit(c)) {
  14.428 +                    // First compact case, we need not to preserve the character
  14.429 +                    // and we can just compute the value in place.
  14.430 +                    if (isCompact) {
  14.431 +                        int digit = Character.digit(c, 10);
  14.432 +                        if (digit == 0) {
  14.433 +                            if (prec == 0)
  14.434 +                                prec = 1;
  14.435 +                            else if (rs != 0) {
  14.436 +                                rs *= 10;
  14.437 +                                ++prec;
  14.438 +                            } // else digit is a redundant leading zero
  14.439 +                        } else {
  14.440 +                            if (prec != 1 || rs != 0)
  14.441 +                                ++prec; // prec unchanged if preceded by 0s
  14.442 +                            rs = rs * 10 + digit;
  14.443 +                        }
  14.444 +                    } else { // the unscaled value is likely a BigInteger object.
  14.445 +                        if (c == '0' || Character.digit(c, 10) == 0) {
  14.446 +                            if (prec == 0) {
  14.447 +                                coeff[idx] = c;
  14.448 +                                prec = 1;
  14.449 +                            } else if (idx != 0) {
  14.450 +                                coeff[idx++] = c;
  14.451 +                                ++prec;
  14.452 +                            } // else c must be a redundant leading zero
  14.453 +                        } else {
  14.454 +                            if (prec != 1 || idx != 0)
  14.455 +                                ++prec; // prec unchanged if preceded by 0s
  14.456 +                            coeff[idx++] = c;
  14.457 +                        }
  14.458 +                    }
  14.459 +                    if (dot)
  14.460 +                        ++scl;
  14.461 +                    continue;
  14.462 +                }
  14.463 +                // have dot
  14.464 +                if (c == '.') {
  14.465 +                    // have dot
  14.466 +                    if (dot)         // two dots
  14.467 +                        throw new NumberFormatException();
  14.468 +                    dot = true;
  14.469 +                    continue;
  14.470 +                }
  14.471 +                // exponent expected
  14.472 +                if ((c != 'e') && (c != 'E'))
  14.473 +                    throw new NumberFormatException();
  14.474 +                offset++;
  14.475 +                c = in[offset];
  14.476 +                len--;
  14.477 +                boolean negexp = (c == '-');
  14.478 +                // optional sign
  14.479 +                if (negexp || c == '+') {
  14.480 +                    offset++;
  14.481 +                    c = in[offset];
  14.482 +                    len--;
  14.483 +                }
  14.484 +                if (len <= 0)    // no exponent digits
  14.485 +                    throw new NumberFormatException();
  14.486 +                // skip leading zeros in the exponent
  14.487 +                while (len > 10 && Character.digit(c, 10) == 0) {
  14.488 +                    offset++;
  14.489 +                    c = in[offset];
  14.490 +                    len--;
  14.491 +                }
  14.492 +                if (len > 10)  // too many nonzero exponent digits
  14.493 +                    throw new NumberFormatException();
  14.494 +                // c now holds first digit of exponent
  14.495 +                for (;; len--) {
  14.496 +                    int v;
  14.497 +                    if (c >= '0' && c <= '9') {
  14.498 +                        v = c - '0';
  14.499 +                    } else {
  14.500 +                        v = Character.digit(c, 10);
  14.501 +                        if (v < 0)            // not a digit
  14.502 +                            throw new NumberFormatException();
  14.503 +                    }
  14.504 +                    exp = exp * 10 + v;
  14.505 +                    if (len == 1)
  14.506 +                        break;               // that was final character
  14.507 +                    offset++;
  14.508 +                    c = in[offset];
  14.509 +                }
  14.510 +                if (negexp)                  // apply sign
  14.511 +                    exp = -exp;
  14.512 +                // Next test is required for backwards compatibility
  14.513 +                if ((int)exp != exp)         // overflow
  14.514 +                    throw new NumberFormatException();
  14.515 +                break;                       // [saves a test]
  14.516 +            }
  14.517 +            // here when no characters left
  14.518 +            if (prec == 0)              // no digits found
  14.519 +                throw new NumberFormatException();
  14.520 +
  14.521 +            // Adjust scale if exp is not zero.
  14.522 +            if (exp != 0) {                  // had significant exponent
  14.523 +                // Can't call checkScale which relies on proper fields value
  14.524 +                long adjustedScale = scl - exp;
  14.525 +                if (adjustedScale > Integer.MAX_VALUE ||
  14.526 +                    adjustedScale < Integer.MIN_VALUE)
  14.527 +                    throw new NumberFormatException("Scale out of range.");
  14.528 +                scl = (int)adjustedScale;
  14.529 +            }
  14.530 +
  14.531 +            // Remove leading zeros from precision (digits count)
  14.532 +            if (isCompact) {
  14.533 +                rs = isneg ? -rs : rs;
  14.534 +            } else {
  14.535 +                char quick[];
  14.536 +                if (!isneg) {
  14.537 +                    quick = (coeff.length != prec) ?
  14.538 +                        Arrays.copyOf(coeff, prec) : coeff;
  14.539 +                } else {
  14.540 +                    quick = new char[prec + 1];
  14.541 +                    quick[0] = '-';
  14.542 +                    System.arraycopy(coeff, 0, quick, 1, prec);
  14.543 +                }
  14.544 +                rb = new BigInteger(quick);
  14.545 +                rs = compactValFor(rb);
  14.546 +            }
  14.547 +        } catch (ArrayIndexOutOfBoundsException e) {
  14.548 +            throw new NumberFormatException();
  14.549 +        } catch (NegativeArraySizeException e) {
  14.550 +            throw new NumberFormatException();
  14.551 +        }
  14.552 +        this.scale = scl;
  14.553 +        this.precision = prec;
  14.554 +        this.intCompact = rs;
  14.555 +        this.intVal = (rs != INFLATED) ? null : rb;
  14.556 +    }
  14.557 +
  14.558 +    /**
  14.559 +     * Translates a character array representation of a
  14.560 +     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
  14.561 +     * same sequence of characters as the {@link #BigDecimal(String)}
  14.562 +     * constructor, while allowing a sub-array to be specified and
  14.563 +     * with rounding according to the context settings.
  14.564 +     *
  14.565 +     * <p>Note that if the sequence of characters is already available
  14.566 +     * within a character array, using this constructor is faster than
  14.567 +     * converting the {@code char} array to string and using the
  14.568 +     * {@code BigDecimal(String)} constructor .
  14.569 +     *
  14.570 +     * @param  in {@code char} array that is the source of characters.
  14.571 +     * @param  offset first character in the array to inspect.
  14.572 +     * @param  len number of characters to consider..
  14.573 +     * @param  mc the context to use.
  14.574 +     * @throws ArithmeticException if the result is inexact but the
  14.575 +     *         rounding mode is {@code UNNECESSARY}.
  14.576 +     * @throws NumberFormatException if {@code in} is not a valid
  14.577 +     *         representation of a {@code BigDecimal} or the defined subarray
  14.578 +     *         is not wholly within {@code in}.
  14.579 +     * @since  1.5
  14.580 +     */
  14.581 +    public BigDecimal(char[] in, int offset, int len, MathContext mc) {
  14.582 +        this(in, offset, len);
  14.583 +        if (mc.precision > 0)
  14.584 +            roundThis(mc);
  14.585 +    }
  14.586 +
  14.587 +    /**
  14.588 +     * Translates a character array representation of a
  14.589 +     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
  14.590 +     * same sequence of characters as the {@link #BigDecimal(String)}
  14.591 +     * constructor.
  14.592 +     *
  14.593 +     * <p>Note that if the sequence of characters is already available
  14.594 +     * as a character array, using this constructor is faster than
  14.595 +     * converting the {@code char} array to string and using the
  14.596 +     * {@code BigDecimal(String)} constructor .
  14.597 +     *
  14.598 +     * @param in {@code char} array that is the source of characters.
  14.599 +     * @throws NumberFormatException if {@code in} is not a valid
  14.600 +     *         representation of a {@code BigDecimal}.
  14.601 +     * @since  1.5
  14.602 +     */
  14.603 +    public BigDecimal(char[] in) {
  14.604 +        this(in, 0, in.length);
  14.605 +    }
  14.606 +
  14.607 +    /**
  14.608 +     * Translates a character array representation of a
  14.609 +     * {@code BigDecimal} into a {@code BigDecimal}, accepting the
  14.610 +     * same sequence of characters as the {@link #BigDecimal(String)}
  14.611 +     * constructor and with rounding according to the context
  14.612 +     * settings.
  14.613 +     *
  14.614 +     * <p>Note that if the sequence of characters is already available
  14.615 +     * as a character array, using this constructor is faster than
  14.616 +     * converting the {@code char} array to string and using the
  14.617 +     * {@code BigDecimal(String)} constructor .
  14.618 +     *
  14.619 +     * @param  in {@code char} array that is the source of characters.
  14.620 +     * @param  mc the context to use.
  14.621 +     * @throws ArithmeticException if the result is inexact but the
  14.622 +     *         rounding mode is {@code UNNECESSARY}.
  14.623 +     * @throws NumberFormatException if {@code in} is not a valid
  14.624 +     *         representation of a {@code BigDecimal}.
  14.625 +     * @since  1.5
  14.626 +     */
  14.627 +    public BigDecimal(char[] in, MathContext mc) {
  14.628 +        this(in, 0, in.length, mc);
  14.629 +    }
  14.630 +
  14.631 +    /**
  14.632 +     * Translates the string representation of a {@code BigDecimal}
  14.633 +     * into a {@code BigDecimal}.  The string representation consists
  14.634 +     * of an optional sign, {@code '+'} (<tt> '&#92;u002B'</tt>) or
  14.635 +     * {@code '-'} (<tt>'&#92;u002D'</tt>), followed by a sequence of
  14.636 +     * zero or more decimal digits ("the integer"), optionally
  14.637 +     * followed by a fraction, optionally followed by an exponent.
  14.638 +     *
  14.639 +     * <p>The fraction consists of a decimal point followed by zero
  14.640 +     * or more decimal digits.  The string must contain at least one
  14.641 +     * digit in either the integer or the fraction.  The number formed
  14.642 +     * by the sign, the integer and the fraction is referred to as the
  14.643 +     * <i>significand</i>.
  14.644 +     *
  14.645 +     * <p>The exponent consists of the character {@code 'e'}
  14.646 +     * (<tt>'&#92;u0065'</tt>) or {@code 'E'} (<tt>'&#92;u0045'</tt>)
  14.647 +     * followed by one or more decimal digits.  The value of the
  14.648 +     * exponent must lie between -{@link Integer#MAX_VALUE} ({@link
  14.649 +     * Integer#MIN_VALUE}+1) and {@link Integer#MAX_VALUE}, inclusive.
  14.650 +     *
  14.651 +     * <p>More formally, the strings this constructor accepts are
  14.652 +     * described by the following grammar:
  14.653 +     * <blockquote>
  14.654 +     * <dl>
  14.655 +     * <dt><i>BigDecimalString:</i>
  14.656 +     * <dd><i>Sign<sub>opt</sub> Significand Exponent<sub>opt</sub></i>
  14.657 +     * <p>
  14.658 +     * <dt><i>Sign:</i>
  14.659 +     * <dd>{@code +}
  14.660 +     * <dd>{@code -}
  14.661 +     * <p>
  14.662 +     * <dt><i>Significand:</i>
  14.663 +     * <dd><i>IntegerPart</i> {@code .} <i>FractionPart<sub>opt</sub></i>
  14.664 +     * <dd>{@code .} <i>FractionPart</i>
  14.665 +     * <dd><i>IntegerPart</i>
  14.666 +     * <p>
  14.667 +     * <dt><i>IntegerPart:</i>
  14.668 +     * <dd><i>Digits</i>
  14.669 +     * <p>
  14.670 +     * <dt><i>FractionPart:</i>
  14.671 +     * <dd><i>Digits</i>
  14.672 +     * <p>
  14.673 +     * <dt><i>Exponent:</i>
  14.674 +     * <dd><i>ExponentIndicator SignedInteger</i>
  14.675 +     * <p>
  14.676 +     * <dt><i>ExponentIndicator:</i>
  14.677 +     * <dd>{@code e}
  14.678 +     * <dd>{@code E}
  14.679 +     * <p>
  14.680 +     * <dt><i>SignedInteger:</i>
  14.681 +     * <dd><i>Sign<sub>opt</sub> Digits</i>
  14.682 +     * <p>
  14.683 +     * <dt><i>Digits:</i>
  14.684 +     * <dd><i>Digit</i>
  14.685 +     * <dd><i>Digits Digit</i>
  14.686 +     * <p>
  14.687 +     * <dt><i>Digit:</i>
  14.688 +     * <dd>any character for which {@link Character#isDigit}
  14.689 +     * returns {@code true}, including 0, 1, 2 ...
  14.690 +     * </dl>
  14.691 +     * </blockquote>
  14.692 +     *
  14.693 +     * <p>The scale of the returned {@code BigDecimal} will be the
  14.694 +     * number of digits in the fraction, or zero if the string
  14.695 +     * contains no decimal point, subject to adjustment for any
  14.696 +     * exponent; if the string contains an exponent, the exponent is
  14.697 +     * subtracted from the scale.  The value of the resulting scale
  14.698 +     * must lie between {@code Integer.MIN_VALUE} and
  14.699 +     * {@code Integer.MAX_VALUE}, inclusive.
  14.700 +     *
  14.701 +     * <p>The character-to-digit mapping is provided by {@link
  14.702 +     * java.lang.Character#digit} set to convert to radix 10.  The
  14.703 +     * String may not contain any extraneous characters (whitespace,
  14.704 +     * for example).
  14.705 +     *
  14.706 +     * <p><b>Examples:</b><br>
  14.707 +     * The value of the returned {@code BigDecimal} is equal to
  14.708 +     * <i>significand</i> &times; 10<sup>&nbsp;<i>exponent</i></sup>.
  14.709 +     * For each string on the left, the resulting representation
  14.710 +     * [{@code BigInteger}, {@code scale}] is shown on the right.
  14.711 +     * <pre>
  14.712 +     * "0"            [0,0]
  14.713 +     * "0.00"         [0,2]
  14.714 +     * "123"          [123,0]
  14.715 +     * "-123"         [-123,0]
  14.716 +     * "1.23E3"       [123,-1]
  14.717 +     * "1.23E+3"      [123,-1]
  14.718 +     * "12.3E+7"      [123,-6]
  14.719 +     * "12.0"         [120,1]
  14.720 +     * "12.3"         [123,1]
  14.721 +     * "0.00123"      [123,5]
  14.722 +     * "-1.23E-12"    [-123,14]
  14.723 +     * "1234.5E-4"    [12345,5]
  14.724 +     * "0E+7"         [0,-7]
  14.725 +     * "-0"           [0,0]
  14.726 +     * </pre>
  14.727 +     *
  14.728 +     * <p>Note: For values other than {@code float} and
  14.729 +     * {@code double} NaN and &plusmn;Infinity, this constructor is
  14.730 +     * compatible with the values returned by {@link Float#toString}
  14.731 +     * and {@link Double#toString}.  This is generally the preferred
  14.732 +     * way to convert a {@code float} or {@code double} into a
  14.733 +     * BigDecimal, as it doesn't suffer from the unpredictability of
  14.734 +     * the {@link #BigDecimal(double)} constructor.
  14.735 +     *
  14.736 +     * @param val String representation of {@code BigDecimal}.
  14.737 +     *
  14.738 +     * @throws NumberFormatException if {@code val} is not a valid
  14.739 +     *         representation of a {@code BigDecimal}.
  14.740 +     */
  14.741 +    public BigDecimal(String val) {
  14.742 +        this(val.toCharArray(), 0, val.length());
  14.743 +    }
  14.744 +
  14.745 +    /**
  14.746 +     * Translates the string representation of a {@code BigDecimal}
  14.747 +     * into a {@code BigDecimal}, accepting the same strings as the
  14.748 +     * {@link #BigDecimal(String)} constructor, with rounding
  14.749 +     * according to the context settings.
  14.750 +     *
  14.751 +     * @param  val string representation of a {@code BigDecimal}.
  14.752 +     * @param  mc the context to use.
  14.753 +     * @throws ArithmeticException if the result is inexact but the
  14.754 +     *         rounding mode is {@code UNNECESSARY}.
  14.755 +     * @throws NumberFormatException if {@code val} is not a valid
  14.756 +     *         representation of a BigDecimal.
  14.757 +     * @since  1.5
  14.758 +     */
  14.759 +    public BigDecimal(String val, MathContext mc) {
  14.760 +        this(val.toCharArray(), 0, val.length());
  14.761 +        if (mc.precision > 0)
  14.762 +            roundThis(mc);
  14.763 +    }
  14.764 +
  14.765 +    /**
  14.766 +     * Translates a {@code double} into a {@code BigDecimal} which
  14.767 +     * is the exact decimal representation of the {@code double}'s
  14.768 +     * binary floating-point value.  The scale of the returned
  14.769 +     * {@code BigDecimal} is the smallest value such that
  14.770 +     * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer.
  14.771 +     * <p>
  14.772 +     * <b>Notes:</b>
  14.773 +     * <ol>
  14.774 +     * <li>
  14.775 +     * The results of this constructor can be somewhat unpredictable.
  14.776 +     * One might assume that writing {@code new BigDecimal(0.1)} in
  14.777 +     * Java creates a {@code BigDecimal} which is exactly equal to
  14.778 +     * 0.1 (an unscaled value of 1, with a scale of 1), but it is
  14.779 +     * actually equal to
  14.780 +     * 0.1000000000000000055511151231257827021181583404541015625.
  14.781 +     * This is because 0.1 cannot be represented exactly as a
  14.782 +     * {@code double} (or, for that matter, as a binary fraction of
  14.783 +     * any finite length).  Thus, the value that is being passed
  14.784 +     * <i>in</i> to the constructor is not exactly equal to 0.1,
  14.785 +     * appearances notwithstanding.
  14.786 +     *
  14.787 +     * <li>
  14.788 +     * The {@code String} constructor, on the other hand, is
  14.789 +     * perfectly predictable: writing {@code new BigDecimal("0.1")}
  14.790 +     * creates a {@code BigDecimal} which is <i>exactly</i> equal to
  14.791 +     * 0.1, as one would expect.  Therefore, it is generally
  14.792 +     * recommended that the {@linkplain #BigDecimal(String)
  14.793 +     * <tt>String</tt> constructor} be used in preference to this one.
  14.794 +     *
  14.795 +     * <li>
  14.796 +     * When a {@code double} must be used as a source for a
  14.797 +     * {@code BigDecimal}, note that this constructor provides an
  14.798 +     * exact conversion; it does not give the same result as
  14.799 +     * converting the {@code double} to a {@code String} using the
  14.800 +     * {@link Double#toString(double)} method and then using the
  14.801 +     * {@link #BigDecimal(String)} constructor.  To get that result,
  14.802 +     * use the {@code static} {@link #valueOf(double)} method.
  14.803 +     * </ol>
  14.804 +     *
  14.805 +     * @param val {@code double} value to be converted to
  14.806 +     *        {@code BigDecimal}.
  14.807 +     * @throws NumberFormatException if {@code val} is infinite or NaN.
  14.808 +     */
  14.809 +    public BigDecimal(double val) {
  14.810 +        if (Double.isInfinite(val) || Double.isNaN(val))
  14.811 +            throw new NumberFormatException("Infinite or NaN");
  14.812 +
  14.813 +        // Translate the double into sign, exponent and significand, according
  14.814 +        // to the formulae in JLS, Section 20.10.22.
  14.815 +        long valBits = Double.doubleToLongBits(val);
  14.816 +        int sign = ((valBits >> 63)==0 ? 1 : -1);
  14.817 +        int exponent = (int) ((valBits >> 52) & 0x7ffL);
  14.818 +        long significand = (exponent==0 ? (valBits & ((1L<<52) - 1)) << 1
  14.819 +                            : (valBits & ((1L<<52) - 1)) | (1L<<52));
  14.820 +        exponent -= 1075;
  14.821 +        // At this point, val == sign * significand * 2**exponent.
  14.822 +
  14.823 +        /*
  14.824 +         * Special case zero to supress nonterminating normalization
  14.825 +         * and bogus scale calculation.
  14.826 +         */
  14.827 +        if (significand == 0) {
  14.828 +            intVal = BigInteger.ZERO;
  14.829 +            intCompact = 0;
  14.830 +            precision = 1;
  14.831 +            return;
  14.832 +        }
  14.833 +
  14.834 +        // Normalize
  14.835 +        while((significand & 1) == 0) {    //  i.e., significand is even
  14.836 +            significand >>= 1;
  14.837 +            exponent++;
  14.838 +        }
  14.839 +
  14.840 +        // Calculate intVal and scale
  14.841 +        long s = sign * significand;
  14.842 +        BigInteger b;
  14.843 +        if (exponent < 0) {
  14.844 +            b = BigInteger.valueOf(5).pow(-exponent).multiply(s);
  14.845 +            scale = -exponent;
  14.846 +        } else if (exponent > 0) {
  14.847 +            b = BigInteger.valueOf(2).pow(exponent).multiply(s);
  14.848 +        } else {
  14.849 +            b = BigInteger.valueOf(s);
  14.850 +        }
  14.851 +        intCompact = compactValFor(b);
  14.852 +        intVal = (intCompact != INFLATED) ? null : b;
  14.853 +    }
  14.854 +
  14.855 +    /**
  14.856 +     * Translates a {@code double} into a {@code BigDecimal}, with
  14.857 +     * rounding according to the context settings.  The scale of the
  14.858 +     * {@code BigDecimal} is the smallest value such that
  14.859 +     * <tt>(10<sup>scale</sup> &times; val)</tt> is an integer.
  14.860 +     *
  14.861 +     * <p>The results of this constructor can be somewhat unpredictable
  14.862 +     * and its use is generally not recommended; see the notes under
  14.863 +     * the {@link #BigDecimal(double)} constructor.
  14.864 +     *
  14.865 +     * @param  val {@code double} value to be converted to
  14.866 +     *         {@code BigDecimal}.
  14.867 +     * @param  mc the context to use.
  14.868 +     * @throws ArithmeticException if the result is inexact but the
  14.869 +     *         RoundingMode is UNNECESSARY.
  14.870 +     * @throws NumberFormatException if {@code val} is infinite or NaN.
  14.871 +     * @since  1.5
  14.872 +     */
  14.873 +    public BigDecimal(double val, MathContext mc) {
  14.874 +        this(val);
  14.875 +        if (mc.precision > 0)
  14.876 +            roundThis(mc);
  14.877 +    }
  14.878 +
  14.879 +    /**
  14.880 +     * Translates a {@code BigInteger} into a {@code BigDecimal}.
  14.881 +     * The scale of the {@code BigDecimal} is zero.
  14.882 +     *
  14.883 +     * @param val {@code BigInteger} value to be converted to
  14.884 +     *            {@code BigDecimal}.
  14.885 +     */
  14.886 +    public BigDecimal(BigInteger val) {
  14.887 +        intCompact = compactValFor(val);
  14.888 +        intVal = (intCompact != INFLATED) ? null : val;
  14.889 +    }
  14.890 +
  14.891 +    /**
  14.892 +     * Translates a {@code BigInteger} into a {@code BigDecimal}
  14.893 +     * rounding according to the context settings.  The scale of the
  14.894 +     * {@code BigDecimal} is zero.
  14.895 +     *
  14.896 +     * @param val {@code BigInteger} value to be converted to
  14.897 +     *            {@code BigDecimal}.
  14.898 +     * @param  mc the context to use.
  14.899 +     * @throws ArithmeticException if the result is inexact but the
  14.900 +     *         rounding mode is {@code UNNECESSARY}.
  14.901 +     * @since  1.5
  14.902 +     */
  14.903 +    public BigDecimal(BigInteger val, MathContext mc) {
  14.904 +        this(val);
  14.905 +        if (mc.precision > 0)
  14.906 +            roundThis(mc);
  14.907 +    }
  14.908 +
  14.909 +    /**
  14.910 +     * Translates a {@code BigInteger} unscaled value and an
  14.911 +     * {@code int} scale into a {@code BigDecimal}.  The value of
  14.912 +     * the {@code BigDecimal} is
  14.913 +     * <tt>(unscaledVal &times; 10<sup>-scale</sup>)</tt>.
  14.914 +     *
  14.915 +     * @param unscaledVal unscaled value of the {@code BigDecimal}.
  14.916 +     * @param scale scale of the {@code BigDecimal}.
  14.917 +     */
  14.918 +    public BigDecimal(BigInteger unscaledVal, int scale) {
  14.919 +        // Negative scales are now allowed
  14.920 +        this(unscaledVal);
  14.921 +        this.scale = scale;
  14.922 +    }
  14.923 +
  14.924 +    /**
  14.925 +     * Translates a {@code BigInteger} unscaled value and an
  14.926 +     * {@code int} scale into a {@code BigDecimal}, with rounding
  14.927 +     * according to the context settings.  The value of the
  14.928 +     * {@code BigDecimal} is <tt>(unscaledVal &times;
  14.929 +     * 10<sup>-scale</sup>)</tt>, rounded according to the
  14.930 +     * {@code precision} and rounding mode settings.
  14.931 +     *
  14.932 +     * @param  unscaledVal unscaled value of the {@code BigDecimal}.
  14.933 +     * @param  scale scale of the {@code BigDecimal}.
  14.934 +     * @param  mc the context to use.
  14.935 +     * @throws ArithmeticException if the result is inexact but the
  14.936 +     *         rounding mode is {@code UNNECESSARY}.
  14.937 +     * @since  1.5
  14.938 +     */
  14.939 +    public BigDecimal(BigInteger unscaledVal, int scale, MathContext mc) {
  14.940 +        this(unscaledVal);
  14.941 +        this.scale = scale;
  14.942 +        if (mc.precision > 0)
  14.943 +            roundThis(mc);
  14.944 +    }
  14.945 +
  14.946 +    /**
  14.947 +     * Translates an {@code int} into a {@code BigDecimal}.  The
  14.948 +     * scale of the {@code BigDecimal} is zero.
  14.949 +     *
  14.950 +     * @param val {@code int} value to be converted to
  14.951 +     *            {@code BigDecimal}.
  14.952 +     * @since  1.5
  14.953 +     */
  14.954 +    public BigDecimal(int val) {
  14.955 +        intCompact = val;
  14.956 +    }
  14.957 +
  14.958 +    /**
  14.959 +     * Translates an {@code int} into a {@code BigDecimal}, with
  14.960 +     * rounding according to the context settings.  The scale of the
  14.961 +     * {@code BigDecimal}, before any rounding, is zero.
  14.962 +     *
  14.963 +     * @param  val {@code int} value to be converted to {@code BigDecimal}.
  14.964 +     * @param  mc the context to use.
  14.965 +     * @throws ArithmeticException if the result is inexact but the
  14.966 +     *         rounding mode is {@code UNNECESSARY}.
  14.967 +     * @since  1.5
  14.968 +     */
  14.969 +    public BigDecimal(int val, MathContext mc) {
  14.970 +        intCompact = val;
  14.971 +        if (mc.precision > 0)
  14.972 +            roundThis(mc);
  14.973 +    }
  14.974 +
  14.975 +    /**
  14.976 +     * Translates a {@code long} into a {@code BigDecimal}.  The
  14.977 +     * scale of the {@code BigDecimal} is zero.
  14.978 +     *
  14.979 +     * @param val {@code long} value to be converted to {@code BigDecimal}.
  14.980 +     * @since  1.5
  14.981 +     */
  14.982 +    public BigDecimal(long val) {
  14.983 +        this.intCompact = val;
  14.984 +        this.intVal = (val == INFLATED) ? BigInteger.valueOf(val) : null;
  14.985 +    }
  14.986 +
  14.987 +    /**
  14.988 +     * Translates a {@code long} into a {@code BigDecimal}, with
  14.989 +     * rounding according to the context settings.  The scale of the
  14.990 +     * {@code BigDecimal}, before any rounding, is zero.
  14.991 +     *
  14.992 +     * @param  val {@code long} value to be converted to {@code BigDecimal}.
  14.993 +     * @param  mc the context to use.
  14.994 +     * @throws ArithmeticException if the result is inexact but the
  14.995 +     *         rounding mode is {@code UNNECESSARY}.
  14.996 +     * @since  1.5
  14.997 +     */
  14.998 +    public BigDecimal(long val, MathContext mc) {
  14.999 +        this(val);
 14.1000 +        if (mc.precision > 0)
 14.1001 +            roundThis(mc);
 14.1002 +    }
 14.1003 +
 14.1004 +    // Static Factory Methods
 14.1005 +
 14.1006 +    /**
 14.1007 +     * Translates a {@code long} unscaled value and an
 14.1008 +     * {@code int} scale into a {@code BigDecimal}.  This
 14.1009 +     * {@literal "static factory method"} is provided in preference to
 14.1010 +     * a ({@code long}, {@code int}) constructor because it
 14.1011 +     * allows for reuse of frequently used {@code BigDecimal} values..
 14.1012 +     *
 14.1013 +     * @param unscaledVal unscaled value of the {@code BigDecimal}.
 14.1014 +     * @param scale scale of the {@code BigDecimal}.
 14.1015 +     * @return a {@code BigDecimal} whose value is
 14.1016 +     *         <tt>(unscaledVal &times; 10<sup>-scale</sup>)</tt>.
 14.1017 +     */
 14.1018 +    public static BigDecimal valueOf(long unscaledVal, int scale) {
 14.1019 +        if (scale == 0)
 14.1020 +            return valueOf(unscaledVal);
 14.1021 +        else if (unscaledVal == 0) {
 14.1022 +            if (scale > 0 && scale < ZERO_SCALED_BY.length)
 14.1023 +                return ZERO_SCALED_BY[scale];
 14.1024 +            else
 14.1025 +                return new BigDecimal(BigInteger.ZERO, 0, scale, 1);
 14.1026 +        }
 14.1027 +        return new BigDecimal(unscaledVal == INFLATED ?
 14.1028 +                              BigInteger.valueOf(unscaledVal) : null,
 14.1029 +                              unscaledVal, scale, 0);
 14.1030 +    }
 14.1031 +
 14.1032 +    /**
 14.1033 +     * Translates a {@code long} value into a {@code BigDecimal}
 14.1034 +     * with a scale of zero.  This {@literal "static factory method"}
 14.1035 +     * is provided in preference to a ({@code long}) constructor
 14.1036 +     * because it allows for reuse of frequently used
 14.1037 +     * {@code BigDecimal} values.
 14.1038 +     *
 14.1039 +     * @param val value of the {@code BigDecimal}.
 14.1040 +     * @return a {@code BigDecimal} whose value is {@code val}.
 14.1041 +     */
 14.1042 +    public static BigDecimal valueOf(long val) {
 14.1043 +        if (val >= 0 && val < zeroThroughTen.length)
 14.1044 +            return zeroThroughTen[(int)val];
 14.1045 +        else if (val != INFLATED)
 14.1046 +            return new BigDecimal(null, val, 0, 0);
 14.1047 +        return new BigDecimal(BigInteger.valueOf(val), val, 0, 0);
 14.1048 +    }
 14.1049 +
 14.1050 +    /**
 14.1051 +     * Translates a {@code double} into a {@code BigDecimal}, using
 14.1052 +     * the {@code double}'s canonical string representation provided
 14.1053 +     * by the {@link Double#toString(double)} method.
 14.1054 +     *
 14.1055 +     * <p><b>Note:</b> This is generally the preferred way to convert
 14.1056 +     * a {@code double} (or {@code float}) into a
 14.1057 +     * {@code BigDecimal}, as the value returned is equal to that
 14.1058 +     * resulting from constructing a {@code BigDecimal} from the
 14.1059 +     * result of using {@link Double#toString(double)}.
 14.1060 +     *
 14.1061 +     * @param  val {@code double} to convert to a {@code BigDecimal}.
 14.1062 +     * @return a {@code BigDecimal} whose value is equal to or approximately
 14.1063 +     *         equal to the value of {@code val}.
 14.1064 +     * @throws NumberFormatException if {@code val} is infinite or NaN.
 14.1065 +     * @since  1.5
 14.1066 +     */
 14.1067 +    public static BigDecimal valueOf(double val) {
 14.1068 +        // Reminder: a zero double returns '0.0', so we cannot fastpath
 14.1069 +        // to use the constant ZERO.  This might be important enough to
 14.1070 +        // justify a factory approach, a cache, or a few private
 14.1071 +        // constants, later.
 14.1072 +        return new BigDecimal(Double.toString(val));
 14.1073 +    }
 14.1074 +
 14.1075 +    // Arithmetic Operations
 14.1076 +    /**
 14.1077 +     * Returns a {@code BigDecimal} whose value is {@code (this +
 14.1078 +     * augend)}, and whose scale is {@code max(this.scale(),
 14.1079 +     * augend.scale())}.
 14.1080 +     *
 14.1081 +     * @param  augend value to be added to this {@code BigDecimal}.
 14.1082 +     * @return {@code this + augend}
 14.1083 +     */
 14.1084 +    public BigDecimal add(BigDecimal augend) {
 14.1085 +        long xs = this.intCompact;
 14.1086 +        long ys = augend.intCompact;
 14.1087 +        BigInteger fst = (xs != INFLATED) ? null : this.intVal;
 14.1088 +        BigInteger snd = (ys != INFLATED) ? null : augend.intVal;
 14.1089 +        int rscale = this.scale;
 14.1090 +
 14.1091 +        long sdiff = (long)rscale - augend.scale;
 14.1092 +        if (sdiff != 0) {
 14.1093 +            if (sdiff < 0) {
 14.1094 +                int raise = checkScale(-sdiff);
 14.1095 +                rscale = augend.scale;
 14.1096 +                if (xs == INFLATED ||
 14.1097 +                    (xs = longMultiplyPowerTen(xs, raise)) == INFLATED)
 14.1098 +                    fst = bigMultiplyPowerTen(raise);
 14.1099 +            } else {
 14.1100 +                int raise = augend.checkScale(sdiff);
 14.1101 +                if (ys == INFLATED ||
 14.1102 +                    (ys = longMultiplyPowerTen(ys, raise)) == INFLATED)
 14.1103 +                    snd = augend.bigMultiplyPowerTen(raise);
 14.1104 +            }
 14.1105 +        }
 14.1106 +        if (xs != INFLATED && ys != INFLATED) {
 14.1107 +            long sum = xs + ys;
 14.1108 +            // See "Hacker's Delight" section 2-12 for explanation of
 14.1109 +            // the overflow test.
 14.1110 +            if ( (((sum ^ xs) & (sum ^ ys))) >= 0L) // not overflowed
 14.1111 +                return BigDecimal.valueOf(sum, rscale);
 14.1112 +        }
 14.1113 +        if (fst == null)
 14.1114 +            fst = BigInteger.valueOf(xs);
 14.1115 +        if (snd == null)
 14.1116 +            snd = BigInteger.valueOf(ys);
 14.1117 +        BigInteger sum = fst.add(snd);
 14.1118 +        return (fst.signum == snd.signum) ?
 14.1119 +            new BigDecimal(sum, INFLATED, rscale, 0) :
 14.1120 +            new BigDecimal(sum, rscale);
 14.1121 +    }
 14.1122 +
 14.1123 +    /**
 14.1124 +     * Returns a {@code BigDecimal} whose value is {@code (this + augend)},
 14.1125 +     * with rounding according to the context settings.
 14.1126 +     *
 14.1127 +     * If either number is zero and the precision setting is nonzero then
 14.1128 +     * the other number, rounded if necessary, is used as the result.
 14.1129 +     *
 14.1130 +     * @param  augend value to be added to this {@code BigDecimal}.
 14.1131 +     * @param  mc the context to use.
 14.1132 +     * @return {@code this + augend}, rounded as necessary.
 14.1133 +     * @throws ArithmeticException if the result is inexact but the
 14.1134 +     *         rounding mode is {@code UNNECESSARY}.
 14.1135 +     * @since  1.5
 14.1136 +     */
 14.1137 +    public BigDecimal add(BigDecimal augend, MathContext mc) {
 14.1138 +        if (mc.precision == 0)
 14.1139 +            return add(augend);
 14.1140 +        BigDecimal lhs = this;
 14.1141 +
 14.1142 +        // Could optimize if values are compact
 14.1143 +        this.inflate();
 14.1144 +        augend.inflate();
 14.1145 +
 14.1146 +        // If either number is zero then the other number, rounded and
 14.1147 +        // scaled if necessary, is used as the result.
 14.1148 +        {
 14.1149 +            boolean lhsIsZero = lhs.signum() == 0;
 14.1150 +            boolean augendIsZero = augend.signum() == 0;
 14.1151 +
 14.1152 +            if (lhsIsZero || augendIsZero) {
 14.1153 +                int preferredScale = Math.max(lhs.scale(), augend.scale());
 14.1154 +                BigDecimal result;
 14.1155 +
 14.1156 +                // Could use a factory for zero instead of a new object
 14.1157 +                if (lhsIsZero && augendIsZero)
 14.1158 +                    return new BigDecimal(BigInteger.ZERO, 0, preferredScale, 0);
 14.1159 +
 14.1160 +                result = lhsIsZero ? doRound(augend, mc) : doRound(lhs, mc);
 14.1161 +
 14.1162 +                if (result.scale() == preferredScale)
 14.1163 +                    return result;
 14.1164 +                else if (result.scale() > preferredScale) {
 14.1165 +                    BigDecimal scaledResult =
 14.1166 +                        new BigDecimal(result.intVal, result.intCompact,
 14.1167 +                                       result.scale, 0);
 14.1168 +                    scaledResult.stripZerosToMatchScale(preferredScale);
 14.1169 +                    return scaledResult;
 14.1170 +                } else { // result.scale < preferredScale
 14.1171 +                    int precisionDiff = mc.precision - result.precision();
 14.1172 +                    int scaleDiff     = preferredScale - result.scale();
 14.1173 +
 14.1174 +                    if (precisionDiff >= scaleDiff)
 14.1175 +                        return result.setScale(preferredScale); // can achieve target scale
 14.1176 +                    else
 14.1177 +                        return result.setScale(result.scale() + precisionDiff);
 14.1178 +                }
 14.1179 +            }
 14.1180 +        }
 14.1181 +
 14.1182 +        long padding = (long)lhs.scale - augend.scale;
 14.1183 +        if (padding != 0) {        // scales differ; alignment needed
 14.1184 +            BigDecimal arg[] = preAlign(lhs, augend, padding, mc);
 14.1185 +            matchScale(arg);
 14.1186 +            lhs    = arg[0];
 14.1187 +            augend = arg[1];
 14.1188 +        }
 14.1189 +
 14.1190 +        BigDecimal d = new BigDecimal(lhs.inflate().add(augend.inflate()),
 14.1191 +                                      lhs.scale);
 14.1192 +        return doRound(d, mc);
 14.1193 +    }
 14.1194 +
 14.1195 +    /**
 14.1196 +     * Returns an array of length two, the sum of whose entries is
 14.1197 +     * equal to the rounded sum of the {@code BigDecimal} arguments.
 14.1198 +     *
 14.1199 +     * <p>If the digit positions of the arguments have a sufficient
 14.1200 +     * gap between them, the value smaller in magnitude can be
 14.1201 +     * condensed into a {@literal "sticky bit"} and the end result will
 14.1202 +     * round the same way <em>if</em> the precision of the final
 14.1203 +     * result does not include the high order digit of the small
 14.1204 +     * magnitude operand.
 14.1205 +     *
 14.1206 +     * <p>Note that while strictly speaking this is an optimization,
 14.1207 +     * it makes a much wider range of additions practical.
 14.1208 +     *
 14.1209 +     * <p>This corresponds to a pre-shift operation in a fixed
 14.1210 +     * precision floating-point adder; this method is complicated by
 14.1211 +     * variable precision of the result as determined by the
 14.1212 +     * MathContext.  A more nuanced operation could implement a
 14.1213 +     * {@literal "right shift"} on the smaller magnitude operand so
 14.1214 +     * that the number of digits of the smaller operand could be
 14.1215 +     * reduced even though the significands partially overlapped.
 14.1216 +     */
 14.1217 +    private BigDecimal[] preAlign(BigDecimal lhs, BigDecimal augend,
 14.1218 +                                  long padding, MathContext mc) {
 14.1219 +        assert padding != 0;
 14.1220 +        BigDecimal big;
 14.1221 +        BigDecimal small;
 14.1222 +
 14.1223 +        if (padding < 0) {     // lhs is big;   augend is small
 14.1224 +            big   = lhs;
 14.1225 +            small = augend;
 14.1226 +        } else {               // lhs is small; augend is big
 14.1227 +            big   = augend;
 14.1228 +            small = lhs;
 14.1229 +        }
 14.1230 +
 14.1231 +        /*
 14.1232 +         * This is the estimated scale of an ulp of the result; it
 14.1233 +         * assumes that the result doesn't have a carry-out on a true
 14.1234 +         * add (e.g. 999 + 1 => 1000) or any subtractive cancellation
 14.1235 +         * on borrowing (e.g. 100 - 1.2 => 98.8)
 14.1236 +         */
 14.1237 +        long estResultUlpScale = (long)big.scale - big.precision() + mc.precision;
 14.1238 +
 14.1239 +        /*
 14.1240 +         * The low-order digit position of big is big.scale().  This
 14.1241 +         * is true regardless of whether big has a positive or
 14.1242 +         * negative scale.  The high-order digit position of small is
 14.1243 +         * small.scale - (small.precision() - 1).  To do the full
 14.1244 +         * condensation, the digit positions of big and small must be
 14.1245 +         * disjoint *and* the digit positions of small should not be
 14.1246 +         * directly visible in the result.
 14.1247 +         */
 14.1248 +        long smallHighDigitPos = (long)small.scale - small.precision() + 1;
 14.1249 +        if (smallHighDigitPos > big.scale + 2 &&         // big and small disjoint
 14.1250 +            smallHighDigitPos > estResultUlpScale + 2) { // small digits not visible
 14.1251 +            small = BigDecimal.valueOf(small.signum(),
 14.1252 +                                       this.checkScale(Math.max(big.scale, estResultUlpScale) + 3));
 14.1253 +        }
 14.1254 +
 14.1255 +        // Since addition is symmetric, preserving input order in
 14.1256 +        // returned operands doesn't matter
 14.1257 +        BigDecimal[] result = {big, small};
 14.1258 +        return result;
 14.1259 +    }
 14.1260 +
 14.1261 +    /**
 14.1262 +     * Returns a {@code BigDecimal} whose value is {@code (this -
 14.1263 +     * subtrahend)}, and whose scale is {@code max(this.scale(),
 14.1264 +     * subtrahend.scale())}.
 14.1265 +     *
 14.1266 +     * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
 14.1267 +     * @return {@code this - subtrahend}
 14.1268 +     */
 14.1269 +    public BigDecimal subtract(BigDecimal subtrahend) {
 14.1270 +        return add(subtrahend.negate());
 14.1271 +    }
 14.1272 +
 14.1273 +    /**
 14.1274 +     * Returns a {@code BigDecimal} whose value is {@code (this - subtrahend)},
 14.1275 +     * with rounding according to the context settings.
 14.1276 +     *
 14.1277 +     * If {@code subtrahend} is zero then this, rounded if necessary, is used as the
 14.1278 +     * result.  If this is zero then the result is {@code subtrahend.negate(mc)}.
 14.1279 +     *
 14.1280 +     * @param  subtrahend value to be subtracted from this {@code BigDecimal}.
 14.1281 +     * @param  mc the context to use.
 14.1282 +     * @return {@code this - subtrahend}, rounded as necessary.
 14.1283 +     * @throws ArithmeticException if the result is inexact but the
 14.1284 +     *         rounding mode is {@code UNNECESSARY}.
 14.1285 +     * @since  1.5
 14.1286 +     */
 14.1287 +    public BigDecimal subtract(BigDecimal subtrahend, MathContext mc) {
 14.1288 +        BigDecimal nsubtrahend = subtrahend.negate();
 14.1289 +        if (mc.precision == 0)
 14.1290 +            return add(nsubtrahend);
 14.1291 +        // share the special rounding code in add()
 14.1292 +        return add(nsubtrahend, mc);
 14.1293 +    }
 14.1294 +
 14.1295 +    /**
 14.1296 +     * Returns a {@code BigDecimal} whose value is <tt>(this &times;
 14.1297 +     * multiplicand)</tt>, and whose scale is {@code (this.scale() +
 14.1298 +     * multiplicand.scale())}.
 14.1299 +     *
 14.1300 +     * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
 14.1301 +     * @return {@code this * multiplicand}
 14.1302 +     */
 14.1303 +    public BigDecimal multiply(BigDecimal multiplicand) {
 14.1304 +        long x = this.intCompact;
 14.1305 +        long y = multiplicand.intCompact;
 14.1306 +        int productScale = checkScale((long)scale + multiplicand.scale);
 14.1307 +
 14.1308 +        // Might be able to do a more clever check incorporating the
 14.1309 +        // inflated check into the overflow computation.
 14.1310 +        if (x != INFLATED && y != INFLATED) {
 14.1311 +            /*
 14.1312 +             * If the product is not an overflowed value, continue
 14.1313 +             * to use the compact representation.  if either of x or y
 14.1314 +             * is INFLATED, the product should also be regarded as
 14.1315 +             * an overflow. Before using the overflow test suggested in
 14.1316 +             * "Hacker's Delight" section 2-12, we perform quick checks
 14.1317 +             * using the precision information to see whether the overflow
 14.1318 +             * would occur since division is expensive on most CPUs.
 14.1319 +             */
 14.1320 +            long product = x * y;
 14.1321 +            long prec = this.precision() + multiplicand.precision();
 14.1322 +            if (prec < 19 || (prec < 21 && (y == 0 || product / y == x)))
 14.1323 +                return BigDecimal.valueOf(product, productScale);
 14.1324 +            return new BigDecimal(BigInteger.valueOf(x).multiply(y), INFLATED,
 14.1325 +                                  productScale, 0);
 14.1326 +        }
 14.1327 +        BigInteger rb;
 14.1328 +        if (x == INFLATED && y == INFLATED)
 14.1329 +            rb = this.intVal.multiply(multiplicand.intVal);
 14.1330 +        else if (x != INFLATED)
 14.1331 +            rb = multiplicand.intVal.multiply(x);
 14.1332 +        else
 14.1333 +            rb = this.intVal.multiply(y);
 14.1334 +        return new BigDecimal(rb, INFLATED, productScale, 0);
 14.1335 +    }
 14.1336 +
 14.1337 +    /**
 14.1338 +     * Returns a {@code BigDecimal} whose value is <tt>(this &times;
 14.1339 +     * multiplicand)</tt>, with rounding according to the context settings.
 14.1340 +     *
 14.1341 +     * @param  multiplicand value to be multiplied by this {@code BigDecimal}.
 14.1342 +     * @param  mc the context to use.
 14.1343 +     * @return {@code this * multiplicand}, rounded as necessary.
 14.1344 +     * @throws ArithmeticException if the result is inexact but the
 14.1345 +     *         rounding mode is {@code UNNECESSARY}.
 14.1346 +     * @since  1.5
 14.1347 +     */
 14.1348 +    public BigDecimal multiply(BigDecimal multiplicand, MathContext mc) {
 14.1349 +        if (mc.precision == 0)
 14.1350 +            return multiply(multiplicand);
 14.1351 +        return doRound(this.multiply(multiplicand), mc);
 14.1352 +    }
 14.1353 +
 14.1354 +    /**
 14.1355 +     * Returns a {@code BigDecimal} whose value is {@code (this /
 14.1356 +     * divisor)}, and whose scale is as specified.  If rounding must
 14.1357 +     * be performed to generate a result with the specified scale, the
 14.1358 +     * specified rounding mode is applied.
 14.1359 +     *
 14.1360 +     * <p>The new {@link #divide(BigDecimal, int, RoundingMode)} method
 14.1361 +     * should be used in preference to this legacy method.
 14.1362 +     *
 14.1363 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1364 +     * @param  scale scale of the {@code BigDecimal} quotient to be returned.
 14.1365 +     * @param  roundingMode rounding mode to apply.
 14.1366 +     * @return {@code this / divisor}
 14.1367 +     * @throws ArithmeticException if {@code divisor} is zero,
 14.1368 +     *         {@code roundingMode==ROUND_UNNECESSARY} and
 14.1369 +     *         the specified scale is insufficient to represent the result
 14.1370 +     *         of the division exactly.
 14.1371 +     * @throws IllegalArgumentException if {@code roundingMode} does not
 14.1372 +     *         represent a valid rounding mode.
 14.1373 +     * @see    #ROUND_UP
 14.1374 +     * @see    #ROUND_DOWN
 14.1375 +     * @see    #ROUND_CEILING
 14.1376 +     * @see    #ROUND_FLOOR
 14.1377 +     * @see    #ROUND_HALF_UP
 14.1378 +     * @see    #ROUND_HALF_DOWN
 14.1379 +     * @see    #ROUND_HALF_EVEN
 14.1380 +     * @see    #ROUND_UNNECESSARY
 14.1381 +     */
 14.1382 +    public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode) {
 14.1383 +        /*
 14.1384 +         * IMPLEMENTATION NOTE: This method *must* return a new object
 14.1385 +         * since divideAndRound uses divide to generate a value whose
 14.1386 +         * scale is then modified.
 14.1387 +         */
 14.1388 +        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
 14.1389 +            throw new IllegalArgumentException("Invalid rounding mode");
 14.1390 +        /*
 14.1391 +         * Rescale dividend or divisor (whichever can be "upscaled" to
 14.1392 +         * produce correctly scaled quotient).
 14.1393 +         * Take care to detect out-of-range scales
 14.1394 +         */
 14.1395 +        BigDecimal dividend = this;
 14.1396 +        if (checkScale((long)scale + divisor.scale) > this.scale)
 14.1397 +            dividend = this.setScale(scale + divisor.scale, ROUND_UNNECESSARY);
 14.1398 +        else
 14.1399 +            divisor = divisor.setScale(checkScale((long)this.scale - scale),
 14.1400 +                                       ROUND_UNNECESSARY);
 14.1401 +        return divideAndRound(dividend.intCompact, dividend.intVal,
 14.1402 +                              divisor.intCompact, divisor.intVal,
 14.1403 +                              scale, roundingMode, scale);
 14.1404 +    }
 14.1405 +
 14.1406 +    /**
 14.1407 +     * Internally used for division operation. The dividend and divisor are
 14.1408 +     * passed both in {@code long} format and {@code BigInteger} format. The
 14.1409 +     * returned {@code BigDecimal} object is the quotient whose scale is set to
 14.1410 +     * the passed in scale. If the remainder is not zero, it will be rounded
 14.1411 +     * based on the passed in roundingMode. Also, if the remainder is zero and
 14.1412 +     * the last parameter, i.e. preferredScale is NOT equal to scale, the
 14.1413 +     * trailing zeros of the result is stripped to match the preferredScale.
 14.1414 +     */
 14.1415 +    private static BigDecimal divideAndRound(long ldividend, BigInteger bdividend,
 14.1416 +                                             long ldivisor,  BigInteger bdivisor,
 14.1417 +                                             int scale, int roundingMode,
 14.1418 +                                             int preferredScale) {
 14.1419 +        boolean isRemainderZero;       // record remainder is zero or not
 14.1420 +        int qsign;                     // quotient sign
 14.1421 +        long q = 0, r = 0;             // store quotient & remainder in long
 14.1422 +        MutableBigInteger mq = null;   // store quotient
 14.1423 +        MutableBigInteger mr = null;   // store remainder
 14.1424 +        MutableBigInteger mdivisor = null;
 14.1425 +        boolean isLongDivision = (ldividend != INFLATED && ldivisor != INFLATED);
 14.1426 +        if (isLongDivision) {
 14.1427 +            q = ldividend / ldivisor;
 14.1428 +            if (roundingMode == ROUND_DOWN && scale == preferredScale)
 14.1429 +                return new BigDecimal(null, q, scale, 0);
 14.1430 +            r = ldividend % ldivisor;
 14.1431 +            isRemainderZero = (r == 0);
 14.1432 +            qsign = ((ldividend < 0) == (ldivisor < 0)) ? 1 : -1;
 14.1433 +        } else {
 14.1434 +            if (bdividend == null)
 14.1435 +                bdividend = BigInteger.valueOf(ldividend);
 14.1436 +            // Descend into mutables for faster remainder checks
 14.1437 +            MutableBigInteger mdividend = new MutableBigInteger(bdividend.mag);
 14.1438 +            mq = new MutableBigInteger();
 14.1439 +            if (ldivisor != INFLATED) {
 14.1440 +                r = mdividend.divide(ldivisor, mq);
 14.1441 +                isRemainderZero = (r == 0);
 14.1442 +                qsign = (ldivisor < 0) ? -bdividend.signum : bdividend.signum;
 14.1443 +            } else {
 14.1444 +                mdivisor = new MutableBigInteger(bdivisor.mag);
 14.1445 +                mr = mdividend.divide(mdivisor, mq);
 14.1446 +                isRemainderZero = mr.isZero();
 14.1447 +                qsign = (bdividend.signum != bdivisor.signum) ? -1 : 1;
 14.1448 +            }
 14.1449 +        }
 14.1450 +        boolean increment = false;
 14.1451 +        if (!isRemainderZero) {
 14.1452 +            int cmpFracHalf;
 14.1453 +            /* Round as appropriate */
 14.1454 +            if (roundingMode == ROUND_UNNECESSARY) {  // Rounding prohibited
 14.1455 +                throw new ArithmeticException("Rounding necessary");
 14.1456 +            } else if (roundingMode == ROUND_UP) {      // Away from zero
 14.1457 +                increment = true;
 14.1458 +            } else if (roundingMode == ROUND_DOWN) {    // Towards zero
 14.1459 +                increment = false;
 14.1460 +            } else if (roundingMode == ROUND_CEILING) { // Towards +infinity
 14.1461 +                increment = (qsign > 0);
 14.1462 +            } else if (roundingMode == ROUND_FLOOR) {   // Towards -infinity
 14.1463 +                increment = (qsign < 0);
 14.1464 +            } else {
 14.1465 +                if (isLongDivision || ldivisor != INFLATED) {
 14.1466 +                    if (r <= HALF_LONG_MIN_VALUE || r > HALF_LONG_MAX_VALUE) {
 14.1467 +                        cmpFracHalf = 1;    // 2 * r can't fit into long
 14.1468 +                    } else {
 14.1469 +                        cmpFracHalf = longCompareMagnitude(2 * r, ldivisor);
 14.1470 +                    }
 14.1471 +                } else {
 14.1472 +                    cmpFracHalf = mr.compareHalf(mdivisor);
 14.1473 +                }
 14.1474 +                if (cmpFracHalf < 0)
 14.1475 +                    increment = false;     // We're closer to higher digit
 14.1476 +                else if (cmpFracHalf > 0)  // We're closer to lower digit
 14.1477 +                    increment = true;
 14.1478 +                else if (roundingMode == ROUND_HALF_UP)
 14.1479 +                    increment = true;
 14.1480 +                else if (roundingMode == ROUND_HALF_DOWN)
 14.1481 +                    increment = false;
 14.1482 +                else  // roundingMode == ROUND_HALF_EVEN, true iff quotient is odd
 14.1483 +                    increment = isLongDivision ? (q & 1L) != 0L : mq.isOdd();
 14.1484 +            }
 14.1485 +        }
 14.1486 +        BigDecimal res;
 14.1487 +        if (isLongDivision)
 14.1488 +            res = new BigDecimal(null, (increment ? q + qsign : q), scale, 0);
 14.1489 +        else {
 14.1490 +            if (increment)
 14.1491 +                mq.add(MutableBigInteger.ONE);
 14.1492 +            res = mq.toBigDecimal(qsign, scale);
 14.1493 +        }
 14.1494 +        if (isRemainderZero && preferredScale != scale)
 14.1495 +            res.stripZerosToMatchScale(preferredScale);
 14.1496 +        return res;
 14.1497 +    }
 14.1498 +
 14.1499 +    /**
 14.1500 +     * Returns a {@code BigDecimal} whose value is {@code (this /
 14.1501 +     * divisor)}, and whose scale is as specified.  If rounding must
 14.1502 +     * be performed to generate a result with the specified scale, the
 14.1503 +     * specified rounding mode is applied.
 14.1504 +     *
 14.1505 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1506 +     * @param  scale scale of the {@code BigDecimal} quotient to be returned.
 14.1507 +     * @param  roundingMode rounding mode to apply.
 14.1508 +     * @return {@code this / divisor}
 14.1509 +     * @throws ArithmeticException if {@code divisor} is zero,
 14.1510 +     *         {@code roundingMode==RoundingMode.UNNECESSARY} and
 14.1511 +     *         the specified scale is insufficient to represent the result
 14.1512 +     *         of the division exactly.
 14.1513 +     * @since 1.5
 14.1514 +     */
 14.1515 +    public BigDecimal divide(BigDecimal divisor, int scale, RoundingMode roundingMode) {
 14.1516 +        return divide(divisor, scale, roundingMode.oldMode);
 14.1517 +    }
 14.1518 +
 14.1519 +    /**
 14.1520 +     * Returns a {@code BigDecimal} whose value is {@code (this /
 14.1521 +     * divisor)}, and whose scale is {@code this.scale()}.  If
 14.1522 +     * rounding must be performed to generate a result with the given
 14.1523 +     * scale, the specified rounding mode is applied.
 14.1524 +     *
 14.1525 +     * <p>The new {@link #divide(BigDecimal, RoundingMode)} method
 14.1526 +     * should be used in preference to this legacy method.
 14.1527 +     *
 14.1528 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1529 +     * @param  roundingMode rounding mode to apply.
 14.1530 +     * @return {@code this / divisor}
 14.1531 +     * @throws ArithmeticException if {@code divisor==0}, or
 14.1532 +     *         {@code roundingMode==ROUND_UNNECESSARY} and
 14.1533 +     *         {@code this.scale()} is insufficient to represent the result
 14.1534 +     *         of the division exactly.
 14.1535 +     * @throws IllegalArgumentException if {@code roundingMode} does not
 14.1536 +     *         represent a valid rounding mode.
 14.1537 +     * @see    #ROUND_UP
 14.1538 +     * @see    #ROUND_DOWN
 14.1539 +     * @see    #ROUND_CEILING
 14.1540 +     * @see    #ROUND_FLOOR
 14.1541 +     * @see    #ROUND_HALF_UP
 14.1542 +     * @see    #ROUND_HALF_DOWN
 14.1543 +     * @see    #ROUND_HALF_EVEN
 14.1544 +     * @see    #ROUND_UNNECESSARY
 14.1545 +     */
 14.1546 +    public BigDecimal divide(BigDecimal divisor, int roundingMode) {
 14.1547 +            return this.divide(divisor, scale, roundingMode);
 14.1548 +    }
 14.1549 +
 14.1550 +    /**
 14.1551 +     * Returns a {@code BigDecimal} whose value is {@code (this /
 14.1552 +     * divisor)}, and whose scale is {@code this.scale()}.  If
 14.1553 +     * rounding must be performed to generate a result with the given
 14.1554 +     * scale, the specified rounding mode is applied.
 14.1555 +     *
 14.1556 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1557 +     * @param  roundingMode rounding mode to apply.
 14.1558 +     * @return {@code this / divisor}
 14.1559 +     * @throws ArithmeticException if {@code divisor==0}, or
 14.1560 +     *         {@code roundingMode==RoundingMode.UNNECESSARY} and
 14.1561 +     *         {@code this.scale()} is insufficient to represent the result
 14.1562 +     *         of the division exactly.
 14.1563 +     * @since 1.5
 14.1564 +     */
 14.1565 +    public BigDecimal divide(BigDecimal divisor, RoundingMode roundingMode) {
 14.1566 +        return this.divide(divisor, scale, roundingMode.oldMode);
 14.1567 +    }
 14.1568 +
 14.1569 +    /**
 14.1570 +     * Returns a {@code BigDecimal} whose value is {@code (this /
 14.1571 +     * divisor)}, and whose preferred scale is {@code (this.scale() -
 14.1572 +     * divisor.scale())}; if the exact quotient cannot be
 14.1573 +     * represented (because it has a non-terminating decimal
 14.1574 +     * expansion) an {@code ArithmeticException} is thrown.
 14.1575 +     *
 14.1576 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1577 +     * @throws ArithmeticException if the exact quotient does not have a
 14.1578 +     *         terminating decimal expansion
 14.1579 +     * @return {@code this / divisor}
 14.1580 +     * @since 1.5
 14.1581 +     * @author Joseph D. Darcy
 14.1582 +     */
 14.1583 +    public BigDecimal divide(BigDecimal divisor) {
 14.1584 +        /*
 14.1585 +         * Handle zero cases first.
 14.1586 +         */
 14.1587 +        if (divisor.signum() == 0) {   // x/0
 14.1588 +            if (this.signum() == 0)    // 0/0
 14.1589 +                throw new ArithmeticException("Division undefined");  // NaN
 14.1590 +            throw new ArithmeticException("Division by zero");
 14.1591 +        }
 14.1592 +
 14.1593 +        // Calculate preferred scale
 14.1594 +        int preferredScale = saturateLong((long)this.scale - divisor.scale);
 14.1595 +        if (this.signum() == 0)        // 0/y
 14.1596 +            return (preferredScale >= 0 &&
 14.1597 +                    preferredScale < ZERO_SCALED_BY.length) ?
 14.1598 +                ZERO_SCALED_BY[preferredScale] :
 14.1599 +                BigDecimal.valueOf(0, preferredScale);
 14.1600 +        else {
 14.1601 +            this.inflate();
 14.1602 +            divisor.inflate();
 14.1603 +            /*
 14.1604 +             * If the quotient this/divisor has a terminating decimal
 14.1605 +             * expansion, the expansion can have no more than
 14.1606 +             * (a.precision() + ceil(10*b.precision)/3) digits.
 14.1607 +             * Therefore, create a MathContext object with this
 14.1608 +             * precision and do a divide with the UNNECESSARY rounding
 14.1609 +             * mode.
 14.1610 +             */
 14.1611 +            MathContext mc = new MathContext( (int)Math.min(this.precision() +
 14.1612 +                                                            (long)Math.ceil(10.0*divisor.precision()/3.0),
 14.1613 +                                                            Integer.MAX_VALUE),
 14.1614 +                                              RoundingMode.UNNECESSARY);
 14.1615 +            BigDecimal quotient;
 14.1616 +            try {
 14.1617 +                quotient = this.divide(divisor, mc);
 14.1618 +            } catch (ArithmeticException e) {
 14.1619 +                throw new ArithmeticException("Non-terminating decimal expansion; " +
 14.1620 +                                              "no exact representable decimal result.");
 14.1621 +            }
 14.1622 +
 14.1623 +            int quotientScale = quotient.scale();
 14.1624 +
 14.1625 +            // divide(BigDecimal, mc) tries to adjust the quotient to
 14.1626 +            // the desired one by removing trailing zeros; since the
 14.1627 +            // exact divide method does not have an explicit digit
 14.1628 +            // limit, we can add zeros too.
 14.1629 +
 14.1630 +            if (preferredScale > quotientScale)
 14.1631 +                return quotient.setScale(preferredScale, ROUND_UNNECESSARY);
 14.1632 +
 14.1633 +            return quotient;
 14.1634 +        }
 14.1635 +    }
 14.1636 +
 14.1637 +    /**
 14.1638 +     * Returns a {@code BigDecimal} whose value is {@code (this /
 14.1639 +     * divisor)}, with rounding according to the context settings.
 14.1640 +     *
 14.1641 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1642 +     * @param  mc the context to use.
 14.1643 +     * @return {@code this / divisor}, rounded as necessary.
 14.1644 +     * @throws ArithmeticException if the result is inexact but the
 14.1645 +     *         rounding mode is {@code UNNECESSARY} or
 14.1646 +     *         {@code mc.precision == 0} and the quotient has a
 14.1647 +     *         non-terminating decimal expansion.
 14.1648 +     * @since  1.5
 14.1649 +     */
 14.1650 +    public BigDecimal divide(BigDecimal divisor, MathContext mc) {
 14.1651 +        int mcp = mc.precision;
 14.1652 +        if (mcp == 0)
 14.1653 +            return divide(divisor);
 14.1654 +
 14.1655 +        BigDecimal dividend = this;
 14.1656 +        long preferredScale = (long)dividend.scale - divisor.scale;
 14.1657 +        // Now calculate the answer.  We use the existing
 14.1658 +        // divide-and-round method, but as this rounds to scale we have
 14.1659 +        // to normalize the values here to achieve the desired result.
 14.1660 +        // For x/y we first handle y=0 and x=0, and then normalize x and
 14.1661 +        // y to give x' and y' with the following constraints:
 14.1662 +        //   (a) 0.1 <= x' < 1
 14.1663 +        //   (b)  x' <= y' < 10*x'
 14.1664 +        // Dividing x'/y' with the required scale set to mc.precision then
 14.1665 +        // will give a result in the range 0.1 to 1 rounded to exactly
 14.1666 +        // the right number of digits (except in the case of a result of
 14.1667 +        // 1.000... which can arise when x=y, or when rounding overflows
 14.1668 +        // The 1.000... case will reduce properly to 1.
 14.1669 +        if (divisor.signum() == 0) {      // x/0
 14.1670 +            if (dividend.signum() == 0)    // 0/0
 14.1671 +                throw new ArithmeticException("Division undefined");  // NaN
 14.1672 +            throw new ArithmeticException("Division by zero");
 14.1673 +        }
 14.1674 +        if (dividend.signum() == 0)        // 0/y
 14.1675 +            return new BigDecimal(BigInteger.ZERO, 0,
 14.1676 +                                  saturateLong(preferredScale), 1);
 14.1677 +
 14.1678 +        // Normalize dividend & divisor so that both fall into [0.1, 0.999...]
 14.1679 +        int xscale = dividend.precision();
 14.1680 +        int yscale = divisor.precision();
 14.1681 +        dividend = new BigDecimal(dividend.intVal, dividend.intCompact,
 14.1682 +                                  xscale, xscale);
 14.1683 +        divisor = new BigDecimal(divisor.intVal, divisor.intCompact,
 14.1684 +                                 yscale, yscale);
 14.1685 +        if (dividend.compareMagnitude(divisor) > 0) // satisfy constraint (b)
 14.1686 +            yscale = divisor.scale -= 1;            // [that is, divisor *= 10]
 14.1687 +
 14.1688 +        // In order to find out whether the divide generates the exact result,
 14.1689 +        // we avoid calling the above divide method. 'quotient' holds the
 14.1690 +        // return BigDecimal object whose scale will be set to 'scl'.
 14.1691 +        BigDecimal quotient;
 14.1692 +        int scl = checkScale(preferredScale + yscale - xscale + mcp);
 14.1693 +        if (checkScale((long)mcp + yscale) > xscale)
 14.1694 +            dividend = dividend.setScale(mcp + yscale, ROUND_UNNECESSARY);
 14.1695 +        else
 14.1696 +            divisor = divisor.setScale(checkScale((long)xscale - mcp),
 14.1697 +                                       ROUND_UNNECESSARY);
 14.1698 +        quotient = divideAndRound(dividend.intCompact, dividend.intVal,
 14.1699 +                                  divisor.intCompact, divisor.intVal,
 14.1700 +                                  scl, mc.roundingMode.oldMode,
 14.1701 +                                  checkScale(preferredScale));
 14.1702 +        // doRound, here, only affects 1000000000 case.
 14.1703 +        quotient = doRound(quotient, mc);
 14.1704 +
 14.1705 +        return quotient;
 14.1706 +    }
 14.1707 +
 14.1708 +    /**
 14.1709 +     * Returns a {@code BigDecimal} whose value is the integer part
 14.1710 +     * of the quotient {@code (this / divisor)} rounded down.  The
 14.1711 +     * preferred scale of the result is {@code (this.scale() -
 14.1712 +     * divisor.scale())}.
 14.1713 +     *
 14.1714 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1715 +     * @return The integer part of {@code this / divisor}.
 14.1716 +     * @throws ArithmeticException if {@code divisor==0}
 14.1717 +     * @since  1.5
 14.1718 +     */
 14.1719 +    public BigDecimal divideToIntegralValue(BigDecimal divisor) {
 14.1720 +        // Calculate preferred scale
 14.1721 +        int preferredScale = saturateLong((long)this.scale - divisor.scale);
 14.1722 +        if (this.compareMagnitude(divisor) < 0) {
 14.1723 +            // much faster when this << divisor
 14.1724 +            return BigDecimal.valueOf(0, preferredScale);
 14.1725 +        }
 14.1726 +
 14.1727 +        if(this.signum() == 0 && divisor.signum() != 0)
 14.1728 +            return this.setScale(preferredScale, ROUND_UNNECESSARY);
 14.1729 +
 14.1730 +        // Perform a divide with enough digits to round to a correct
 14.1731 +        // integer value; then remove any fractional digits
 14.1732 +
 14.1733 +        int maxDigits = (int)Math.min(this.precision() +
 14.1734 +                                      (long)Math.ceil(10.0*divisor.precision()/3.0) +
 14.1735 +                                      Math.abs((long)this.scale() - divisor.scale()) + 2,
 14.1736 +                                      Integer.MAX_VALUE);
 14.1737 +        BigDecimal quotient = this.divide(divisor, new MathContext(maxDigits,
 14.1738 +                                                                   RoundingMode.DOWN));
 14.1739 +        if (quotient.scale > 0) {
 14.1740 +            quotient = quotient.setScale(0, RoundingMode.DOWN);
 14.1741 +            quotient.stripZerosToMatchScale(preferredScale);
 14.1742 +        }
 14.1743 +
 14.1744 +        if (quotient.scale < preferredScale) {
 14.1745 +            // pad with zeros if necessary
 14.1746 +            quotient = quotient.setScale(preferredScale, ROUND_UNNECESSARY);
 14.1747 +        }
 14.1748 +        return quotient;
 14.1749 +    }
 14.1750 +
 14.1751 +    /**
 14.1752 +     * Returns a {@code BigDecimal} whose value is the integer part
 14.1753 +     * of {@code (this / divisor)}.  Since the integer part of the
 14.1754 +     * exact quotient does not depend on the rounding mode, the
 14.1755 +     * rounding mode does not affect the values returned by this
 14.1756 +     * method.  The preferred scale of the result is
 14.1757 +     * {@code (this.scale() - divisor.scale())}.  An
 14.1758 +     * {@code ArithmeticException} is thrown if the integer part of
 14.1759 +     * the exact quotient needs more than {@code mc.precision}
 14.1760 +     * digits.
 14.1761 +     *
 14.1762 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1763 +     * @param  mc the context to use.
 14.1764 +     * @return The integer part of {@code this / divisor}.
 14.1765 +     * @throws ArithmeticException if {@code divisor==0}
 14.1766 +     * @throws ArithmeticException if {@code mc.precision} {@literal >} 0 and the result
 14.1767 +     *         requires a precision of more than {@code mc.precision} digits.
 14.1768 +     * @since  1.5
 14.1769 +     * @author Joseph D. Darcy
 14.1770 +     */
 14.1771 +    public BigDecimal divideToIntegralValue(BigDecimal divisor, MathContext mc) {
 14.1772 +        if (mc.precision == 0 ||                        // exact result
 14.1773 +            (this.compareMagnitude(divisor) < 0) )      // zero result
 14.1774 +            return divideToIntegralValue(divisor);
 14.1775 +
 14.1776 +        // Calculate preferred scale
 14.1777 +        int preferredScale = saturateLong((long)this.scale - divisor.scale);
 14.1778 +
 14.1779 +        /*
 14.1780 +         * Perform a normal divide to mc.precision digits.  If the
 14.1781 +         * remainder has absolute value less than the divisor, the
 14.1782 +         * integer portion of the quotient fits into mc.precision
 14.1783 +         * digits.  Next, remove any fractional digits from the
 14.1784 +         * quotient and adjust the scale to the preferred value.
 14.1785 +         */
 14.1786 +        BigDecimal result = this.
 14.1787 +            divide(divisor, new MathContext(mc.precision, RoundingMode.DOWN));
 14.1788 +
 14.1789 +        if (result.scale() < 0) {
 14.1790 +            /*
 14.1791 +             * Result is an integer. See if quotient represents the
 14.1792 +             * full integer portion of the exact quotient; if it does,
 14.1793 +             * the computed remainder will be less than the divisor.
 14.1794 +             */
 14.1795 +            BigDecimal product = result.multiply(divisor);
 14.1796 +            // If the quotient is the full integer value,
 14.1797 +            // |dividend-product| < |divisor|.
 14.1798 +            if (this.subtract(product).compareMagnitude(divisor) >= 0) {
 14.1799 +                throw new ArithmeticException("Division impossible");
 14.1800 +            }
 14.1801 +        } else if (result.scale() > 0) {
 14.1802 +            /*
 14.1803 +             * Integer portion of quotient will fit into precision
 14.1804 +             * digits; recompute quotient to scale 0 to avoid double
 14.1805 +             * rounding and then try to adjust, if necessary.
 14.1806 +             */
 14.1807 +            result = result.setScale(0, RoundingMode.DOWN);
 14.1808 +        }
 14.1809 +        // else result.scale() == 0;
 14.1810 +
 14.1811 +        int precisionDiff;
 14.1812 +        if ((preferredScale > result.scale()) &&
 14.1813 +            (precisionDiff = mc.precision - result.precision()) > 0) {
 14.1814 +            return result.setScale(result.scale() +
 14.1815 +                                   Math.min(precisionDiff, preferredScale - result.scale) );
 14.1816 +        } else {
 14.1817 +            result.stripZerosToMatchScale(preferredScale);
 14.1818 +            return result;
 14.1819 +        }
 14.1820 +    }
 14.1821 +
 14.1822 +    /**
 14.1823 +     * Returns a {@code BigDecimal} whose value is {@code (this % divisor)}.
 14.1824 +     *
 14.1825 +     * <p>The remainder is given by
 14.1826 +     * {@code this.subtract(this.divideToIntegralValue(divisor).multiply(divisor))}.
 14.1827 +     * Note that this is not the modulo operation (the result can be
 14.1828 +     * negative).
 14.1829 +     *
 14.1830 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1831 +     * @return {@code this % divisor}.
 14.1832 +     * @throws ArithmeticException if {@code divisor==0}
 14.1833 +     * @since  1.5
 14.1834 +     */
 14.1835 +    public BigDecimal remainder(BigDecimal divisor) {
 14.1836 +        BigDecimal divrem[] = this.divideAndRemainder(divisor);
 14.1837 +        return divrem[1];
 14.1838 +    }
 14.1839 +
 14.1840 +
 14.1841 +    /**
 14.1842 +     * Returns a {@code BigDecimal} whose value is {@code (this %
 14.1843 +     * divisor)}, with rounding according to the context settings.
 14.1844 +     * The {@code MathContext} settings affect the implicit divide
 14.1845 +     * used to compute the remainder.  The remainder computation
 14.1846 +     * itself is by definition exact.  Therefore, the remainder may
 14.1847 +     * contain more than {@code mc.getPrecision()} digits.
 14.1848 +     *
 14.1849 +     * <p>The remainder is given by
 14.1850 +     * {@code this.subtract(this.divideToIntegralValue(divisor,
 14.1851 +     * mc).multiply(divisor))}.  Note that this is not the modulo
 14.1852 +     * operation (the result can be negative).
 14.1853 +     *
 14.1854 +     * @param  divisor value by which this {@code BigDecimal} is to be divided.
 14.1855 +     * @param  mc the context to use.
 14.1856 +     * @return {@code this % divisor}, rounded as necessary.
 14.1857 +     * @throws ArithmeticException if {@code divisor==0}
 14.1858 +     * @throws ArithmeticException if the result is inexact but the
 14.1859 +     *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
 14.1860 +     *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
 14.1861 +     *         require a precision of more than {@code mc.precision} digits.
 14.1862 +     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
 14.1863 +     * @since  1.5
 14.1864 +     */
 14.1865 +    public BigDecimal remainder(BigDecimal divisor, MathContext mc) {
 14.1866 +        BigDecimal divrem[] = this.divideAndRemainder(divisor, mc);
 14.1867 +        return divrem[1];
 14.1868 +    }
 14.1869 +
 14.1870 +    /**
 14.1871 +     * Returns a two-element {@code BigDecimal} array containing the
 14.1872 +     * result of {@code divideToIntegralValue} followed by the result of
 14.1873 +     * {@code remainder} on the two operands.
 14.1874 +     *
 14.1875 +     * <p>Note that if both the integer quotient and remainder are
 14.1876 +     * needed, this method is faster than using the
 14.1877 +     * {@code divideToIntegralValue} and {@code remainder} methods
 14.1878 +     * separately because the division need only be carried out once.
 14.1879 +     *
 14.1880 +     * @param  divisor value by which this {@code BigDecimal} is to be divided,
 14.1881 +     *         and the remainder computed.
 14.1882 +     * @return a two element {@code BigDecimal} array: the quotient
 14.1883 +     *         (the result of {@code divideToIntegralValue}) is the initial element
 14.1884 +     *         and the remainder is the final element.
 14.1885 +     * @throws ArithmeticException if {@code divisor==0}
 14.1886 +     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
 14.1887 +     * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
 14.1888 +     * @since  1.5
 14.1889 +     */
 14.1890 +    public BigDecimal[] divideAndRemainder(BigDecimal divisor) {
 14.1891 +        // we use the identity  x = i * y + r to determine r
 14.1892 +        BigDecimal[] result = new BigDecimal[2];
 14.1893 +
 14.1894 +        result[0] = this.divideToIntegralValue(divisor);
 14.1895 +        result[1] = this.subtract(result[0].multiply(divisor));
 14.1896 +        return result;
 14.1897 +    }
 14.1898 +
 14.1899 +    /**
 14.1900 +     * Returns a two-element {@code BigDecimal} array containing the
 14.1901 +     * result of {@code divideToIntegralValue} followed by the result of
 14.1902 +     * {@code remainder} on the two operands calculated with rounding
 14.1903 +     * according to the context settings.
 14.1904 +     *
 14.1905 +     * <p>Note that if both the integer quotient and remainder are
 14.1906 +     * needed, this method is faster than using the
 14.1907 +     * {@code divideToIntegralValue} and {@code remainder} methods
 14.1908 +     * separately because the division need only be carried out once.
 14.1909 +     *
 14.1910 +     * @param  divisor value by which this {@code BigDecimal} is to be divided,
 14.1911 +     *         and the remainder computed.
 14.1912 +     * @param  mc the context to use.
 14.1913 +     * @return a two element {@code BigDecimal} array: the quotient
 14.1914 +     *         (the result of {@code divideToIntegralValue}) is the
 14.1915 +     *         initial element and the remainder is the final element.
 14.1916 +     * @throws ArithmeticException if {@code divisor==0}
 14.1917 +     * @throws ArithmeticException if the result is inexact but the
 14.1918 +     *         rounding mode is {@code UNNECESSARY}, or {@code mc.precision}
 14.1919 +     *         {@literal >} 0 and the result of {@code this.divideToIntgralValue(divisor)} would
 14.1920 +     *         require a precision of more than {@code mc.precision} digits.
 14.1921 +     * @see    #divideToIntegralValue(java.math.BigDecimal, java.math.MathContext)
 14.1922 +     * @see    #remainder(java.math.BigDecimal, java.math.MathContext)
 14.1923 +     * @since  1.5
 14.1924 +     */
 14.1925 +    public BigDecimal[] divideAndRemainder(BigDecimal divisor, MathContext mc) {
 14.1926 +        if (mc.precision == 0)
 14.1927 +            return divideAndRemainder(divisor);
 14.1928 +
 14.1929 +        BigDecimal[] result = new BigDecimal[2];
 14.1930 +        BigDecimal lhs = this;
 14.1931 +
 14.1932 +        result[0] = lhs.divideToIntegralValue(divisor, mc);
 14.1933 +        result[1] = lhs.subtract(result[0].multiply(divisor));
 14.1934 +        return result;
 14.1935 +    }
 14.1936 +
 14.1937 +    /**
 14.1938 +     * Returns a {@code BigDecimal} whose value is
 14.1939 +     * <tt>(this<sup>n</sup>)</tt>, The power is computed exactly, to
 14.1940 +     * unlimited precision.
 14.1941 +     *
 14.1942 +     * <p>The parameter {@code n} must be in the range 0 through
 14.1943 +     * 999999999, inclusive.  {@code ZERO.pow(0)} returns {@link
 14.1944 +     * #ONE}.
 14.1945 +     *
 14.1946 +     * Note that future releases may expand the allowable exponent
 14.1947 +     * range of this method.
 14.1948 +     *
 14.1949 +     * @param  n power to raise this {@code BigDecimal} to.
 14.1950 +     * @return <tt>this<sup>n</sup></tt>
 14.1951 +     * @throws ArithmeticException if {@code n} is out of range.
 14.1952 +     * @since  1.5
 14.1953 +     */
 14.1954 +    public BigDecimal pow(int n) {
 14.1955 +        if (n < 0 || n > 999999999)
 14.1956 +            throw new ArithmeticException("Invalid operation");
 14.1957 +        // No need to calculate pow(n) if result will over/underflow.
 14.1958 +        // Don't attempt to support "supernormal" numbers.
 14.1959 +        int newScale = checkScale((long)scale * n);
 14.1960 +        this.inflate();
 14.1961 +        return new BigDecimal(intVal.pow(n), newScale);
 14.1962 +    }
 14.1963 +
 14.1964 +
 14.1965 +    /**
 14.1966 +     * Returns a {@code BigDecimal} whose value is
 14.1967 +     * <tt>(this<sup>n</sup>)</tt>.  The current implementation uses
 14.1968 +     * the core algorithm defined in ANSI standard X3.274-1996 with
 14.1969 +     * rounding according to the context settings.  In general, the
 14.1970 +     * returned numerical value is within two ulps of the exact
 14.1971 +     * numerical value for the chosen precision.  Note that future
 14.1972 +     * releases may use a different algorithm with a decreased
 14.1973 +     * allowable error bound and increased allowable exponent range.
 14.1974 +     *
 14.1975 +     * <p>The X3.274-1996 algorithm is:
 14.1976 +     *
 14.1977 +     * <ul>
 14.1978 +     * <li> An {@code ArithmeticException} exception is thrown if
 14.1979 +     *  <ul>
 14.1980 +     *    <li>{@code abs(n) > 999999999}
 14.1981 +     *    <li>{@code mc.precision == 0} and {@code n < 0}
 14.1982 +     *    <li>{@code mc.precision > 0} and {@code n} has more than
 14.1983 +     *    {@code mc.precision} decimal digits
 14.1984 +     *  </ul>
 14.1985 +     *
 14.1986 +     * <li> if {@code n} is zero, {@link #ONE} is returned even if
 14.1987 +     * {@code this} is zero, otherwise
 14.1988 +     * <ul>
 14.1989 +     *   <li> if {@code n} is positive, the result is calculated via
 14.1990 +     *   the repeated squaring technique into a single accumulator.
 14.1991 +     *   The individual multiplications with the accumulator use the
 14.1992 +     *   same math context settings as in {@code mc} except for a
 14.1993 +     *   precision increased to {@code mc.precision + elength + 1}
 14.1994 +     *   where {@code elength} is the number of decimal digits in
 14.1995 +     *   {@code n}.
 14.1996 +     *
 14.1997 +     *   <li> if {@code n} is negative, the result is calculated as if
 14.1998 +     *   {@code n} were positive; this value is then divided into one
 14.1999 +     *   using the working precision specified above.
 14.2000 +     *
 14.2001 +     *   <li> The final value from either the positive or negative case
 14.2002 +     *   is then rounded to the destination precision.
 14.2003 +     *   </ul>
 14.2004 +     * </ul>
 14.2005 +     *
 14.2006 +     * @param  n power to raise this {@code BigDecimal} to.
 14.2007 +     * @param  mc the context to use.
 14.2008 +     * @return <tt>this<sup>n</sup></tt> using the ANSI standard X3.274-1996
 14.2009 +     *         algorithm
 14.2010 +     * @throws ArithmeticException if the result is inexact but the
 14.2011 +     *         rounding mode is {@code UNNECESSARY}, or {@code n} is out
 14.2012 +     *         of range.
 14.2013 +     * @since  1.5
 14.2014 +     */
 14.2015 +    public BigDecimal pow(int n, MathContext mc) {
 14.2016 +        if (mc.precision == 0)
 14.2017 +            return pow(n);
 14.2018 +        if (n < -999999999 || n > 999999999)
 14.2019 +            throw new ArithmeticException("Invalid operation");
 14.2020 +        if (n == 0)
 14.2021 +            return ONE;                      // x**0 == 1 in X3.274
 14.2022 +        this.inflate();
 14.2023 +        BigDecimal lhs = this;
 14.2024 +        MathContext workmc = mc;           // working settings
 14.2025 +        int mag = Math.abs(n);               // magnitude of n
 14.2026 +        if (mc.precision > 0) {
 14.2027 +
 14.2028 +            int elength = longDigitLength(mag); // length of n in digits
 14.2029 +            if (elength > mc.precision)        // X3.274 rule
 14.2030 +                throw new ArithmeticException("Invalid operation");
 14.2031 +            workmc = new MathContext(mc.precision + elength + 1,
 14.2032 +                                      mc.roundingMode);
 14.2033 +        }
 14.2034 +        // ready to carry out power calculation...
 14.2035 +        BigDecimal acc = ONE;           // accumulator
 14.2036 +        boolean seenbit = false;        // set once we've seen a 1-bit
 14.2037 +        for (int i=1;;i++) {            // for each bit [top bit ignored]
 14.2038 +            mag += mag;                 // shift left 1 bit
 14.2039 +            if (mag < 0) {              // top bit is set
 14.2040 +                seenbit = true;         // OK, we're off
 14.2041 +                acc = acc.multiply(lhs, workmc); // acc=acc*x
 14.2042 +            }
 14.2043 +            if (i == 31)
 14.2044 +                break;                  // that was the last bit
 14.2045 +            if (seenbit)
 14.2046 +                acc=acc.multiply(acc, workmc);   // acc=acc*acc [square]
 14.2047 +                // else (!seenbit) no point in squaring ONE
 14.2048 +        }
 14.2049 +        // if negative n, calculate the reciprocal using working precision
 14.2050 +        if (n<0)                          // [hence mc.precision>0]
 14.2051 +            acc=ONE.divide(acc, workmc);
 14.2052 +        // round to final precision and strip zeros
 14.2053 +        return doRound(acc, mc);
 14.2054 +    }
 14.2055 +
 14.2056 +    /**
 14.2057 +     * Returns a {@code BigDecimal} whose value is the absolute value
 14.2058 +     * of this {@code BigDecimal}, and whose scale is
 14.2059 +     * {@code this.scale()}.
 14.2060 +     *
 14.2061 +     * @return {@code abs(this)}
 14.2062 +     */
 14.2063 +    public BigDecimal abs() {
 14.2064 +        return (signum() < 0 ? negate() : this);
 14.2065 +    }
 14.2066 +
 14.2067 +    /**
 14.2068 +     * Returns a {@code BigDecimal} whose value is the absolute value
 14.2069 +     * of this {@code BigDecimal}, with rounding according to the
 14.2070 +     * context settings.
 14.2071 +     *
 14.2072 +     * @param mc the context to use.
 14.2073 +     * @return {@code abs(this)}, rounded as necessary.
 14.2074 +     * @throws ArithmeticException if the result is inexact but the
 14.2075 +     *         rounding mode is {@code UNNECESSARY}.
 14.2076 +     * @since 1.5
 14.2077 +     */
 14.2078 +    public BigDecimal abs(MathContext mc) {
 14.2079 +        return (signum() < 0 ? negate(mc) : plus(mc));
 14.2080 +    }
 14.2081 +
 14.2082 +    /**
 14.2083 +     * Returns a {@code BigDecimal} whose value is {@code (-this)},
 14.2084 +     * and whose scale is {@code this.scale()}.
 14.2085 +     *
 14.2086 +     * @return {@code -this}.
 14.2087 +     */
 14.2088 +    public BigDecimal negate() {
 14.2089 +        BigDecimal result;
 14.2090 +        if (intCompact != INFLATED)
 14.2091 +            result = BigDecimal.valueOf(-intCompact, scale);
 14.2092 +        else {
 14.2093 +            result = new BigDecimal(intVal.negate(), scale);
 14.2094 +            result.precision = precision;
 14.2095 +        }
 14.2096 +        return result;
 14.2097 +    }
 14.2098 +
 14.2099 +    /**
 14.2100 +     * Returns a {@code BigDecimal} whose value is {@code (-this)},
 14.2101 +     * with rounding according to the context settings.
 14.2102 +     *
 14.2103 +     * @param mc the context to use.
 14.2104 +     * @return {@code -this}, rounded as necessary.
 14.2105 +     * @throws ArithmeticException if the result is inexact but the
 14.2106 +     *         rounding mode is {@code UNNECESSARY}.
 14.2107 +     * @since  1.5
 14.2108 +     */
 14.2109 +    public BigDecimal negate(MathContext mc) {
 14.2110 +        return negate().plus(mc);
 14.2111 +    }
 14.2112 +
 14.2113 +    /**
 14.2114 +     * Returns a {@code BigDecimal} whose value is {@code (+this)}, and whose
 14.2115 +     * scale is {@code this.scale()}.
 14.2116 +     *
 14.2117 +     * <p>This method, which simply returns this {@code BigDecimal}
 14.2118 +     * is included for symmetry with the unary minus method {@link
 14.2119 +     * #negate()}.
 14.2120 +     *
 14.2121 +     * @return {@code this}.
 14.2122 +     * @see #negate()
 14.2123 +     * @since  1.5
 14.2124 +     */
 14.2125 +    public BigDecimal plus() {
 14.2126 +        return this;
 14.2127 +    }
 14.2128 +
 14.2129 +    /**
 14.2130 +     * Returns a {@code BigDecimal} whose value is {@code (+this)},
 14.2131 +     * with rounding according to the context settings.
 14.2132 +     *
 14.2133 +     * <p>The effect of this method is identical to that of the {@link
 14.2134 +     * #round(MathContext)} method.
 14.2135 +     *
 14.2136 +     * @param mc the context to use.
 14.2137 +     * @return {@code this}, rounded as necessary.  A zero result will
 14.2138 +     *         have a scale of 0.
 14.2139 +     * @throws ArithmeticException if the result is inexact but the
 14.2140 +     *         rounding mode is {@code UNNECESSARY}.
 14.2141 +     * @see    #round(MathContext)
 14.2142 +     * @since  1.5
 14.2143 +     */
 14.2144 +    public BigDecimal plus(MathContext mc) {
 14.2145 +        if (mc.precision == 0)                 // no rounding please
 14.2146 +            return this;
 14.2147 +        return doRound(this, mc);
 14.2148 +    }
 14.2149 +
 14.2150 +    /**
 14.2151 +     * Returns the signum function of this {@code BigDecimal}.
 14.2152 +     *
 14.2153 +     * @return -1, 0, or 1 as the value of this {@code BigDecimal}
 14.2154 +     *         is negative, zero, or positive.
 14.2155 +     */
 14.2156 +    public int signum() {
 14.2157 +        return (intCompact != INFLATED)?
 14.2158 +            Long.signum(intCompact):
 14.2159 +            intVal.signum();
 14.2160 +    }
 14.2161 +
 14.2162 +    /**
 14.2163 +     * Returns the <i>scale</i> of this {@code BigDecimal}.  If zero
 14.2164 +     * or positive, the scale is the number of digits to the right of
 14.2165 +     * the decimal point.  If negative, the unscaled value of the
 14.2166 +     * number is multiplied by ten to the power of the negation of the
 14.2167 +     * scale.  For example, a scale of {@code -3} means the unscaled
 14.2168 +     * value is multiplied by 1000.
 14.2169 +     *
 14.2170 +     * @return the scale of this {@code BigDecimal}.
 14.2171 +     */
 14.2172 +    public int scale() {
 14.2173 +        return scale;
 14.2174 +    }
 14.2175 +
 14.2176 +    /**
 14.2177 +     * Returns the <i>precision</i> of this {@code BigDecimal}.  (The
 14.2178 +     * precision is the number of digits in the unscaled value.)
 14.2179 +     *
 14.2180 +     * <p>The precision of a zero value is 1.
 14.2181 +     *
 14.2182 +     * @return the precision of this {@code BigDecimal}.
 14.2183 +     * @since  1.5
 14.2184 +     */
 14.2185 +    public int precision() {
 14.2186 +        int result = precision;
 14.2187 +        if (result == 0) {
 14.2188 +            long s = intCompact;
 14.2189 +            if (s != INFLATED)
 14.2190 +                result = longDigitLength(s);
 14.2191 +            else
 14.2192 +                result = bigDigitLength(inflate());
 14.2193 +            precision = result;
 14.2194 +        }
 14.2195 +        return result;
 14.2196 +    }
 14.2197 +
 14.2198 +
 14.2199 +    /**
 14.2200 +     * Returns a {@code BigInteger} whose value is the <i>unscaled
 14.2201 +     * value</i> of this {@code BigDecimal}.  (Computes <tt>(this *
 14.2202 +     * 10<sup>this.scale()</sup>)</tt>.)
 14.2203 +     *
 14.2204 +     * @return the unscaled value of this {@code BigDecimal}.
 14.2205 +     * @since  1.2
 14.2206 +     */
 14.2207 +    public BigInteger unscaledValue() {
 14.2208 +        return this.inflate();
 14.2209 +    }
 14.2210 +
 14.2211 +    // Rounding Modes
 14.2212 +
 14.2213 +    /**
 14.2214 +     * Rounding mode to round away from zero.  Always increments the
 14.2215 +     * digit prior to a nonzero discarded fraction.  Note that this rounding
 14.2216 +     * mode never decreases the magnitude of the calculated value.
 14.2217 +     */
 14.2218 +    public final static int ROUND_UP =           0;
 14.2219 +
 14.2220 +    /**
 14.2221 +     * Rounding mode to round towards zero.  Never increments the digit
 14.2222 +     * prior to a discarded fraction (i.e., truncates).  Note that this
 14.2223 +     * rounding mode never increases the magnitude of the calculated value.
 14.2224 +     */
 14.2225 +    public final static int ROUND_DOWN =         1;
 14.2226 +
 14.2227 +    /**
 14.2228 +     * Rounding mode to round towards positive infinity.  If the
 14.2229 +     * {@code BigDecimal} is positive, behaves as for
 14.2230 +     * {@code ROUND_UP}; if negative, behaves as for
 14.2231 +     * {@code ROUND_DOWN}.  Note that this rounding mode never
 14.2232 +     * decreases the calculated value.
 14.2233 +     */
 14.2234 +    public final static int ROUND_CEILING =      2;
 14.2235 +
 14.2236 +    /**
 14.2237 +     * Rounding mode to round towards negative infinity.  If the
 14.2238 +     * {@code BigDecimal} is positive, behave as for
 14.2239 +     * {@code ROUND_DOWN}; if negative, behave as for
 14.2240 +     * {@code ROUND_UP}.  Note that this rounding mode never
 14.2241 +     * increases the calculated value.
 14.2242 +     */
 14.2243 +    public final static int ROUND_FLOOR =        3;
 14.2244 +
 14.2245 +    /**
 14.2246 +     * Rounding mode to round towards {@literal "nearest neighbor"}
 14.2247 +     * unless both neighbors are equidistant, in which case round up.
 14.2248 +     * Behaves as for {@code ROUND_UP} if the discarded fraction is
 14.2249 +     * &ge; 0.5; otherwise, behaves as for {@code ROUND_DOWN}.  Note
 14.2250 +     * that this is the rounding mode that most of us were taught in
 14.2251 +     * grade school.
 14.2252 +     */
 14.2253 +    public final static int ROUND_HALF_UP =      4;
 14.2254 +
 14.2255 +    /**
 14.2256 +     * Rounding mode to round towards {@literal "nearest neighbor"}
 14.2257 +     * unless both neighbors are equidistant, in which case round
 14.2258 +     * down.  Behaves as for {@code ROUND_UP} if the discarded
 14.2259 +     * fraction is {@literal >} 0.5; otherwise, behaves as for
 14.2260 +     * {@code ROUND_DOWN}.
 14.2261 +     */
 14.2262 +    public final static int ROUND_HALF_DOWN =    5;
 14.2263 +
 14.2264 +    /**
 14.2265 +     * Rounding mode to round towards the {@literal "nearest neighbor"}
 14.2266 +     * unless both neighbors are equidistant, in which case, round
 14.2267 +     * towards the even neighbor.  Behaves as for
 14.2268 +     * {@code ROUND_HALF_UP} if the digit to the left of the
 14.2269 +     * discarded fraction is odd; behaves as for
 14.2270 +     * {@code ROUND_HALF_DOWN} if it's even.  Note that this is the
 14.2271 +     * rounding mode that minimizes cumulative error when applied
 14.2272 +     * repeatedly over a sequence of calculations.
 14.2273 +     */
 14.2274 +    public final static int ROUND_HALF_EVEN =    6;
 14.2275 +
 14.2276 +    /**
 14.2277 +     * Rounding mode to assert that the requested operation has an exact
 14.2278 +     * result, hence no rounding is necessary.  If this rounding mode is
 14.2279 +     * specified on an operation that yields an inexact result, an
 14.2280 +     * {@code ArithmeticException} is thrown.
 14.2281 +     */
 14.2282 +    public final static int ROUND_UNNECESSARY =  7;
 14.2283 +
 14.2284 +
 14.2285 +    // Scaling/Rounding Operations
 14.2286 +
 14.2287 +    /**
 14.2288 +     * Returns a {@code BigDecimal} rounded according to the
 14.2289 +     * {@code MathContext} settings.  If the precision setting is 0 then
 14.2290 +     * no rounding takes place.
 14.2291 +     *
 14.2292 +     * <p>The effect of this method is identical to that of the
 14.2293 +     * {@link #plus(MathContext)} method.
 14.2294 +     *
 14.2295 +     * @param mc the context to use.
 14.2296 +     * @return a {@code BigDecimal} rounded according to the
 14.2297 +     *         {@code MathContext} settings.
 14.2298 +     * @throws ArithmeticException if the rounding mode is
 14.2299 +     *         {@code UNNECESSARY} and the
 14.2300 +     *         {@code BigDecimal}  operation would require rounding.
 14.2301 +     * @see    #plus(MathContext)
 14.2302 +     * @since  1.5
 14.2303 +     */
 14.2304 +    public BigDecimal round(MathContext mc) {
 14.2305 +        return plus(mc);
 14.2306 +    }
 14.2307 +
 14.2308 +    /**
 14.2309 +     * Returns a {@code BigDecimal} whose scale is the specified
 14.2310 +     * value, and whose unscaled value is determined by multiplying or
 14.2311 +     * dividing this {@code BigDecimal}'s unscaled value by the
 14.2312 +     * appropriate power of ten to maintain its overall value.  If the
 14.2313 +     * scale is reduced by the operation, the unscaled value must be
 14.2314 +     * divided (rather than multiplied), and the value may be changed;
 14.2315 +     * in this case, the specified rounding mode is applied to the
 14.2316 +     * division.
 14.2317 +     *
 14.2318 +     * <p>Note that since BigDecimal objects are immutable, calls of
 14.2319 +     * this method do <i>not</i> result in the original object being
 14.2320 +     * modified, contrary to the usual convention of having methods
 14.2321 +     * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
 14.2322 +     * Instead, {@code setScale} returns an object with the proper
 14.2323 +     * scale; the returned object may or may not be newly allocated.
 14.2324 +     *
 14.2325 +     * @param  newScale scale of the {@code BigDecimal} value to be returned.
 14.2326 +     * @param  roundingMode The rounding mode to apply.
 14.2327 +     * @return a {@code BigDecimal} whose scale is the specified value,
 14.2328 +     *         and whose unscaled value is determined by multiplying or
 14.2329 +     *         dividing this {@code BigDecimal}'s unscaled value by the
 14.2330 +     *         appropriate power of ten to maintain its overall value.
 14.2331 +     * @throws ArithmeticException if {@code roundingMode==UNNECESSARY}
 14.2332 +     *         and the specified scaling operation would require
 14.2333 +     *         rounding.
 14.2334 +     * @see    RoundingMode
 14.2335 +     * @since  1.5
 14.2336 +     */
 14.2337 +    public BigDecimal setScale(int newScale, RoundingMode roundingMode) {
 14.2338 +        return setScale(newScale, roundingMode.oldMode);
 14.2339 +    }
 14.2340 +
 14.2341 +    /**
 14.2342 +     * Returns a {@code BigDecimal} whose scale is the specified
 14.2343 +     * value, and whose unscaled value is determined by multiplying or
 14.2344 +     * dividing this {@code BigDecimal}'s unscaled value by the
 14.2345 +     * appropriate power of ten to maintain its overall value.  If the
 14.2346 +     * scale is reduced by the operation, the unscaled value must be
 14.2347 +     * divided (rather than multiplied), and the value may be changed;
 14.2348 +     * in this case, the specified rounding mode is applied to the
 14.2349 +     * division.
 14.2350 +     *
 14.2351 +     * <p>Note that since BigDecimal objects are immutable, calls of
 14.2352 +     * this method do <i>not</i> result in the original object being
 14.2353 +     * modified, contrary to the usual convention of having methods
 14.2354 +     * named <tt>set<i>X</i></tt> mutate field <i>{@code X}</i>.
 14.2355 +     * Instead, {@code setScale} returns an object with the proper
 14.2356 +     * scale; the returned object may or may not be newly allocated.
 14.2357 +     *
 14.2358 +     * <p>The new {@link #setScale(int, RoundingMode)} method should
 14.2359 +     * be used in preference to this legacy method.
 14.2360 +     *
 14.2361 +     * @param  newScale scale of the {@code BigDecimal} value to be returned.
 14.2362 +     * @param  roundingMode The rounding mode to apply.
 14.2363 +     * @return a {@code BigDecimal} whose scale is the specified value,
 14.2364 +     *         and whose unscaled value is determined by multiplying or
 14.2365 +     *         dividing this {@code BigDecimal}'s unscaled value by the
 14.2366 +     *         appropriate power of ten to maintain its overall value.
 14.2367 +     * @throws ArithmeticException if {@code roundingMode==ROUND_UNNECESSARY}
 14.2368 +     *         and the specified scaling operation would require
 14.2369 +     *         rounding.
 14.2370 +     * @throws IllegalArgumentException if {@code roundingMode} does not
 14.2371 +     *         represent a valid rounding mode.
 14.2372 +     * @see    #ROUND_UP
 14.2373 +     * @see    #ROUND_DOWN
 14.2374 +     * @see    #ROUND_CEILING
 14.2375 +     * @see    #ROUND_FLOOR
 14.2376 +     * @see    #ROUND_HALF_UP
 14.2377 +     * @see    #ROUND_HALF_DOWN
 14.2378 +     * @see    #ROUND_HALF_EVEN
 14.2379 +     * @see    #ROUND_UNNECESSARY
 14.2380 +     */
 14.2381 +    public BigDecimal setScale(int newScale, int roundingMode) {
 14.2382 +        if (roundingMode < ROUND_UP || roundingMode > ROUND_UNNECESSARY)
 14.2383 +            throw new IllegalArgumentException("Invalid rounding mode");
 14.2384 +
 14.2385 +        int oldScale = this.scale;
 14.2386 +        if (newScale == oldScale)        // easy case
 14.2387 +            return this;
 14.2388 +        if (this.signum() == 0)            // zero can have any scale
 14.2389 +            return BigDecimal.valueOf(0, newScale);
 14.2390 +
 14.2391 +        long rs = this.intCompact;
 14.2392 +        if (newScale > oldScale) {
 14.2393 +            int raise = checkScale((long)newScale - oldScale);
 14.2394 +            BigInteger rb = null;
 14.2395 +            if (rs == INFLATED ||
 14.2396 +                (rs = longMultiplyPowerTen(rs, raise)) == INFLATED)
 14.2397 +                rb = bigMultiplyPowerTen(raise);
 14.2398 +            return new BigDecimal(rb, rs, newScale,
 14.2399 +                                  (precision > 0) ? precision + raise : 0);
 14.2400 +        } else {
 14.2401 +            // newScale < oldScale -- drop some digits
 14.2402 +            // Can't predict the precision due to the effect of rounding.
 14.2403 +            int drop = checkScale((long)oldScale - newScale);
 14.2404 +            if (drop < LONG_TEN_POWERS_TABLE.length)
 14.2405 +                return divideAndRound(rs, this.intVal,
 14.2406 +                                      LONG_TEN_POWERS_TABLE[drop], null,
 14.2407 +                                      newScale, roundingMode, newScale);
 14.2408 +            else
 14.2409 +                return divideAndRound(rs, this.intVal,
 14.2410 +                                      INFLATED, bigTenToThe(drop),
 14.2411 +                                      newScale, roundingMode, newScale);
 14.2412 +        }
 14.2413 +    }
 14.2414 +
 14.2415 +    /**
 14.2416 +     * Returns a {@code BigDecimal} whose scale is the specified
 14.2417 +     * value, and whose value is numerically equal to this
 14.2418 +     * {@code BigDecimal}'s.  Throws an {@code ArithmeticException}
 14.2419 +     * if this is not possible.
 14.2420 +     *
 14.2421 +     * <p>This call is typically used to increase the scale, in which
 14.2422 +     * case it is guaranteed that there exists a {@code BigDecimal}
 14.2423 +     * of the specified scale and the correct value.  The call can
 14.2424 +     * also be used to reduce the scale if the caller knows that the
 14.2425 +     * {@code BigDecimal} has sufficiently many zeros at the end of
 14.2426 +     * its fractional part (i.e., factors of ten in its integer value)
 14.2427 +     * to allow for the rescaling without changing its value.
 14.2428 +     *
 14.2429 +     * <p>This method returns the same result as the two-argument
 14.2430 +     * versions of {@code setScale}, but saves the caller the trouble
 14.2431 +     * of specifying a rounding mode in cases where it is irrelevant.
 14.2432 +     *
 14.2433 +     * <p>Note that since {@code BigDecimal} objects are immutable,
 14.2434 +     * calls of this method do <i>not</i> result in the original
 14.2435 +     * object being modified, contrary to the usual convention of
 14.2436 +     * having methods named <tt>set<i>X</i></tt> mutate field
 14.2437 +     * <i>{@code X}</i>.  Instead, {@code setScale} returns an
 14.2438 +     * object with the proper scale; the returned object may or may
 14.2439 +     * not be newly allocated.
 14.2440 +     *
 14.2441 +     * @param  newScale scale of the {@code BigDecimal} value to be returned.
 14.2442 +     * @return a {@code BigDecimal} whose scale is the specified value, and
 14.2443 +     *         whose unscaled value is determined by multiplying or dividing
 14.2444 +     *         this {@code BigDecimal}'s unscaled value by the appropriate
 14.2445 +     *         power of ten to maintain its overall value.
 14.2446 +     * @throws ArithmeticException if the specified scaling operation would
 14.2447 +     *         require rounding.
 14.2448 +     * @see    #setScale(int, int)
 14.2449 +     * @see    #setScale(int, RoundingMode)
 14.2450 +     */
 14.2451 +    public BigDecimal setScale(int newScale) {
 14.2452 +        return setScale(newScale, ROUND_UNNECESSARY);
 14.2453 +    }
 14.2454 +
 14.2455 +    // Decimal Point Motion Operations
 14.2456 +
 14.2457 +    /**
 14.2458 +     * Returns a {@code BigDecimal} which is equivalent to this one
 14.2459 +     * with the decimal point moved {@code n} places to the left.  If
 14.2460 +     * {@code n} is non-negative, the call merely adds {@code n} to
 14.2461 +     * the scale.  If {@code n} is negative, the call is equivalent
 14.2462 +     * to {@code movePointRight(-n)}.  The {@code BigDecimal}
 14.2463 +     * returned by this call has value <tt>(this &times;
 14.2464 +     * 10<sup>-n</sup>)</tt> and scale {@code max(this.scale()+n,
 14.2465 +     * 0)}.
 14.2466 +     *
 14.2467 +     * @param  n number of places to move the decimal point to the left.
 14.2468 +     * @return a {@code BigDecimal} which is equivalent to this one with the
 14.2469 +     *         decimal point moved {@code n} places to the left.
 14.2470 +     * @throws ArithmeticException if scale overflows.
 14.2471 +     */
 14.2472 +    public BigDecimal movePointLeft(int n) {
 14.2473 +        // Cannot use movePointRight(-n) in case of n==Integer.MIN_VALUE
 14.2474 +        int newScale = checkScale((long)scale + n);
 14.2475 +        BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
 14.2476 +        return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
 14.2477 +    }
 14.2478 +
 14.2479 +    /**
 14.2480 +     * Returns a {@code BigDecimal} which is equivalent to this one
 14.2481 +     * with the decimal point moved {@code n} places to the right.
 14.2482 +     * If {@code n} is non-negative, the call merely subtracts
 14.2483 +     * {@code n} from the scale.  If {@code n} is negative, the call
 14.2484 +     * is equivalent to {@code movePointLeft(-n)}.  The
 14.2485 +     * {@code BigDecimal} returned by this call has value <tt>(this
 14.2486 +     * &times; 10<sup>n</sup>)</tt> and scale {@code max(this.scale()-n,
 14.2487 +     * 0)}.
 14.2488 +     *
 14.2489 +     * @param  n number of places to move the decimal point to the right.
 14.2490 +     * @return a {@code BigDecimal} which is equivalent to this one
 14.2491 +     *         with the decimal point moved {@code n} places to the right.
 14.2492 +     * @throws ArithmeticException if scale overflows.
 14.2493 +     */
 14.2494 +    public BigDecimal movePointRight(int n) {
 14.2495 +        // Cannot use movePointLeft(-n) in case of n==Integer.MIN_VALUE
 14.2496 +        int newScale = checkScale((long)scale - n);
 14.2497 +        BigDecimal num = new BigDecimal(intVal, intCompact, newScale, 0);
 14.2498 +        return num.scale < 0 ? num.setScale(0, ROUND_UNNECESSARY) : num;
 14.2499 +    }
 14.2500 +
 14.2501 +    /**
 14.2502 +     * Returns a BigDecimal whose numerical value is equal to
 14.2503 +     * ({@code this} * 10<sup>n</sup>).  The scale of
 14.2504 +     * the result is {@code (this.scale() - n)}.
 14.2505 +     *
 14.2506 +     * @throws ArithmeticException if the scale would be
 14.2507 +     *         outside the range of a 32-bit integer.
 14.2508 +     *
 14.2509 +     * @since 1.5
 14.2510 +     */
 14.2511 +    public BigDecimal scaleByPowerOfTen(int n) {
 14.2512 +        return new BigDecimal(intVal, intCompact,
 14.2513 +                              checkScale((long)scale - n), precision);
 14.2514 +    }
 14.2515 +
 14.2516 +    /**
 14.2517 +     * Returns a {@code BigDecimal} which is numerically equal to
 14.2518 +     * this one but with any trailing zeros removed from the
 14.2519 +     * representation.  For example, stripping the trailing zeros from
 14.2520 +     * the {@code BigDecimal} value {@code 600.0}, which has
 14.2521 +     * [{@code BigInteger}, {@code scale}] components equals to
 14.2522 +     * [6000, 1], yields {@code 6E2} with [{@code BigInteger},
 14.2523 +     * {@code scale}] components equals to [6, -2]
 14.2524 +     *
 14.2525 +     * @return a numerically equal {@code BigDecimal} with any
 14.2526 +     * trailing zeros removed.
 14.2527 +     * @since 1.5
 14.2528 +     */
 14.2529 +    public BigDecimal stripTrailingZeros() {
 14.2530 +        this.inflate();
 14.2531 +        BigDecimal result = new BigDecimal(intVal, scale);
 14.2532 +        result.stripZerosToMatchScale(Long.MIN_VALUE);
 14.2533 +        return result;
 14.2534 +    }
 14.2535 +
 14.2536 +    // Comparison Operations
 14.2537 +
 14.2538 +    /**
 14.2539 +     * Compares this {@code BigDecimal} with the specified
 14.2540 +     * {@code BigDecimal}.  Two {@code BigDecimal} objects that are
 14.2541 +     * equal in value but have a different scale (like 2.0 and 2.00)
 14.2542 +     * are considered equal by this method.  This method is provided
 14.2543 +     * in preference to individual methods for each of the six boolean
 14.2544 +     * comparison operators ({@literal <}, ==,
 14.2545 +     * {@literal >}, {@literal >=}, !=, {@literal <=}).  The
 14.2546 +     * suggested idiom for performing these comparisons is:
 14.2547 +     * {@code (x.compareTo(y)} &lt;<i>op</i>&gt; {@code 0)}, where
 14.2548 +     * &lt;<i>op</i>&gt; is one of the six comparison operators.
 14.2549 +     *
 14.2550 +     * @param  val {@code BigDecimal} to which this {@code BigDecimal} is
 14.2551 +     *         to be compared.
 14.2552 +     * @return -1, 0, or 1 as this {@code BigDecimal} is numerically
 14.2553 +     *          less than, equal to, or greater than {@code val}.
 14.2554 +     */
 14.2555 +    public int compareTo(BigDecimal val) {
 14.2556 +        // Quick path for equal scale and non-inflated case.
 14.2557 +        if (scale == val.scale) {
 14.2558 +            long xs = intCompact;
 14.2559 +            long ys = val.intCompact;
 14.2560 +            if (xs != INFLATED && ys != INFLATED)
 14.2561 +                return xs != ys ? ((xs > ys) ? 1 : -1) : 0;
 14.2562 +        }
 14.2563 +        int xsign = this.signum();
 14.2564 +        int ysign = val.signum();
 14.2565 +        if (xsign != ysign)
 14.2566 +            return (xsign > ysign) ? 1 : -1;
 14.2567 +        if (xsign == 0)
 14.2568 +            return 0;
 14.2569 +        int cmp = compareMagnitude(val);
 14.2570 +        return (xsign > 0) ? cmp : -cmp;
 14.2571 +    }
 14.2572 +
 14.2573 +    /**
 14.2574 +     * Version of compareTo that ignores sign.
 14.2575 +     */
 14.2576 +    private int compareMagnitude(BigDecimal val) {
 14.2577 +        // Match scales, avoid unnecessary inflation
 14.2578 +        long ys = val.intCompact;
 14.2579 +        long xs = this.intCompact;
 14.2580 +        if (xs == 0)
 14.2581 +            return (ys == 0) ? 0 : -1;
 14.2582 +        if (ys == 0)
 14.2583 +            return 1;
 14.2584 +
 14.2585 +        int sdiff = this.scale - val.scale;
 14.2586 +        if (sdiff != 0) {
 14.2587 +            // Avoid matching scales if the (adjusted) exponents differ
 14.2588 +            int xae = this.precision() - this.scale;   // [-1]
 14.2589 +            int yae = val.precision() - val.scale;     // [-1]
 14.2590 +            if (xae < yae)
 14.2591 +                return -1;
 14.2592 +            if (xae > yae)
 14.2593 +                return 1;
 14.2594 +            BigInteger rb = null;
 14.2595 +            if (sdiff < 0) {
 14.2596 +                if ( (xs == INFLATED ||
 14.2597 +                      (xs = longMultiplyPowerTen(xs, -sdiff)) == INFLATED) &&
 14.2598 +                     ys == INFLATED) {
 14.2599 +                    rb = bigMultiplyPowerTen(-sdiff);
 14.2600 +                    return rb.compareMagnitude(val.intVal);
 14.2601 +                }
 14.2602 +            } else { // sdiff > 0
 14.2603 +                if ( (ys == INFLATED ||
 14.2604 +                      (ys = longMultiplyPowerTen(ys, sdiff)) == INFLATED) &&
 14.2605 +                     xs == INFLATED) {
 14.2606 +                    rb = val.bigMultiplyPowerTen(sdiff);
 14.2607 +                    return this.intVal.compareMagnitude(rb);
 14.2608 +                }
 14.2609 +            }
 14.2610 +        }
 14.2611 +        if (xs != INFLATED)
 14.2612 +            return (ys != INFLATED) ? longCompareMagnitude(xs, ys) : -1;
 14.2613 +        else if (ys != INFLATED)
 14.2614 +            return 1;
 14.2615 +        else
 14.2616 +            return this.intVal.compareMagnitude(val.intVal);
 14.2617 +    }
 14.2618 +
 14.2619 +    /**
 14.2620 +     * Compares this {@code BigDecimal} with the specified
 14.2621 +     * {@code Object} for equality.  Unlike {@link
 14.2622 +     * #compareTo(BigDecimal) compareTo}, this method considers two
 14.2623 +     * {@code BigDecimal} objects equal only if they are equal in
 14.2624 +     * value and scale (thus 2.0 is not equal to 2.00 when compared by
 14.2625 +     * this method).
 14.2626 +     *
 14.2627 +     * @param  x {@code Object} to which this {@code BigDecimal} is
 14.2628 +     *         to be compared.
 14.2629 +     * @return {@code true} if and only if the specified {@code Object} is a
 14.2630 +     *         {@code BigDecimal} whose value and scale are equal to this
 14.2631 +     *         {@code BigDecimal}'s.
 14.2632 +     * @see    #compareTo(java.math.BigDecimal)
 14.2633 +     * @see    #hashCode
 14.2634 +     */
 14.2635 +    @Override
 14.2636 +    public boolean equals(Object x) {
 14.2637 +        if (!(x instanceof BigDecimal))
 14.2638 +            return false;
 14.2639 +        BigDecimal xDec = (BigDecimal) x;
 14.2640 +        if (x == this)
 14.2641 +            return true;
 14.2642 +        if (scale != xDec.scale)
 14.2643 +            return false;
 14.2644 +        long s = this.intCompact;
 14.2645 +        long xs = xDec.intCompact;
 14.2646 +        if (s != INFLATED) {
 14.2647 +            if (xs == INFLATED)
 14.2648 +                xs = compactValFor(xDec.intVal);
 14.2649 +            return xs == s;
 14.2650 +        } else if (xs != INFLATED)
 14.2651 +            return xs == compactValFor(this.intVal);
 14.2652 +
 14.2653 +        return this.inflate().equals(xDec.inflate());
 14.2654 +    }
 14.2655 +
 14.2656 +    /**
 14.2657 +     * Returns the minimum of this {@code BigDecimal} and
 14.2658 +     * {@code val}.
 14.2659 +     *
 14.2660 +     * @param  val value with which the minimum is to be computed.
 14.2661 +     * @return the {@code BigDecimal} whose value is the lesser of this
 14.2662 +     *         {@code BigDecimal} and {@code val}.  If they are equal,
 14.2663 +     *         as defined by the {@link #compareTo(BigDecimal) compareTo}
 14.2664 +     *         method, {@code this} is returned.
 14.2665 +     * @see    #compareTo(java.math.BigDecimal)
 14.2666 +     */
 14.2667 +    public BigDecimal min(BigDecimal val) {
 14.2668 +        return (compareTo(val) <= 0 ? this : val);
 14.2669 +    }
 14.2670 +
 14.2671 +    /**
 14.2672 +     * Returns the maximum of this {@code BigDecimal} and {@code val}.
 14.2673 +     *
 14.2674 +     * @param  val value with which the maximum is to be computed.
 14.2675 +     * @return the {@code BigDecimal} whose value is the greater of this
 14.2676 +     *         {@code BigDecimal} and {@code val}.  If they are equal,
 14.2677 +     *         as defined by the {@link #compareTo(BigDecimal) compareTo}
 14.2678 +     *         method, {@code this} is returned.
 14.2679 +     * @see    #compareTo(java.math.BigDecimal)
 14.2680 +     */
 14.2681 +    public BigDecimal max(BigDecimal val) {
 14.2682 +        return (compareTo(val) >= 0 ? this : val);
 14.2683 +    }
 14.2684 +
 14.2685 +    // Hash Function
 14.2686 +
 14.2687 +    /**
 14.2688 +     * Returns the hash code for this {@code BigDecimal}.  Note that
 14.2689 +     * two {@code BigDecimal} objects that are numerically equal but
 14.2690 +     * differ in scale (like 2.0 and 2.00) will generally <i>not</i>
 14.2691 +     * have the same hash code.
 14.2692 +     *
 14.2693 +     * @return hash code for this {@code BigDecimal}.
 14.2694 +     * @see #equals(Object)
 14.2695 +     */
 14.2696 +    @Override
 14.2697 +    public int hashCode() {
 14.2698 +        if (intCompact != INFLATED) {
 14.2699 +            long val2 = (intCompact < 0)? -intCompact : intCompact;
 14.2700 +            int temp = (int)( ((int)(val2 >>> 32)) * 31  +
 14.2701 +                              (val2 & LONG_MASK));
 14.2702 +            return 31*((intCompact < 0) ?-temp:temp) + scale;
 14.2703 +        } else
 14.2704 +            return 31*intVal.hashCode() + scale;
 14.2705 +    }
 14.2706 +
 14.2707 +    // Format Converters
 14.2708 +
 14.2709 +    /**
 14.2710 +     * Returns the string representation of this {@code BigDecimal},
 14.2711 +     * using scientific notation if an exponent is needed.
 14.2712 +     *
 14.2713 +     * <p>A standard canonical string form of the {@code BigDecimal}
 14.2714 +     * is created as though by the following steps: first, the
 14.2715 +     * absolute value of the unscaled value of the {@code BigDecimal}
 14.2716 +     * is converted to a string in base ten using the characters
 14.2717 +     * {@code '0'} through {@code '9'} with no leading zeros (except
 14.2718 +     * if its value is zero, in which case a single {@code '0'}
 14.2719 +     * character is used).
 14.2720 +     *
 14.2721 +     * <p>Next, an <i>adjusted exponent</i> is calculated; this is the
 14.2722 +     * negated scale, plus the number of characters in the converted
 14.2723 +     * unscaled value, less one.  That is,
 14.2724 +     * {@code -scale+(ulength-1)}, where {@code ulength} is the
 14.2725 +     * length of the absolute value of the unscaled value in decimal
 14.2726 +     * digits (its <i>precision</i>).
 14.2727 +     *
 14.2728 +     * <p>If the scale is greater than or equal to zero and the
 14.2729 +     * adjusted exponent is greater than or equal to {@code -6}, the
 14.2730 +     * number will be converted to a character form without using
 14.2731 +     * exponential notation.  In this case, if the scale is zero then
 14.2732 +     * no decimal point is added and if the scale is positive a
 14.2733 +     * decimal point will be inserted with the scale specifying the
 14.2734 +     * number of characters to the right of the decimal point.
 14.2735 +     * {@code '0'} characters are added to the left of the converted
 14.2736 +     * unscaled value as necessary.  If no character precedes the
 14.2737 +     * decimal point after this insertion then a conventional
 14.2738 +     * {@code '0'} character is prefixed.
 14.2739 +     *
 14.2740 +     * <p>Otherwise (that is, if the scale is negative, or the
 14.2741 +     * adjusted exponent is less than {@code -6}), the number will be
 14.2742 +     * converted to a character form using exponential notation.  In
 14.2743 +     * this case, if the converted {@code BigInteger} has more than
 14.2744 +     * one digit a decimal point is inserted after the first digit.
 14.2745 +     * An exponent in character form is then suffixed to the converted
 14.2746 +     * unscaled value (perhaps with inserted decimal point); this
 14.2747 +     * comprises the letter {@code 'E'} followed immediately by the
 14.2748 +     * adjusted exponent converted to a character form.  The latter is
 14.2749 +     * in base ten, using the characters {@code '0'} through
 14.2750 +     * {@code '9'} with no leading zeros, and is always prefixed by a
 14.2751 +     * sign character {@code '-'} (<tt>'&#92;u002D'</tt>) if the
 14.2752 +     * adjusted exponent is negative, {@code '+'}
 14.2753 +     * (<tt>'&#92;u002B'</tt>) otherwise).
 14.2754 +     *
 14.2755 +     * <p>Finally, the entire string is prefixed by a minus sign
 14.2756 +     * character {@code '-'} (<tt>'&#92;u002D'</tt>) if the unscaled
 14.2757 +     * value is less than zero.  No sign character is prefixed if the
 14.2758 +     * unscaled value is zero or positive.
 14.2759 +     *
 14.2760 +     * <p><b>Examples:</b>
 14.2761 +     * <p>For each representation [<i>unscaled value</i>, <i>scale</i>]
 14.2762 +     * on the left, the resulting string is shown on the right.
 14.2763 +     * <pre>
 14.2764 +     * [123,0]      "123"
 14.2765 +     * [-123,0]     "-123"
 14.2766 +     * [123,-1]     "1.23E+3"
 14.2767 +     * [123,-3]     "1.23E+5"
 14.2768 +     * [123,1]      "12.3"
 14.2769 +     * [123,5]      "0.00123"
 14.2770 +     * [123,10]     "1.23E-8"
 14.2771 +     * [-123,12]    "-1.23E-10"
 14.2772 +     * </pre>
 14.2773 +     *
 14.2774 +     * <b>Notes:</b>
 14.2775 +     * <ol>
 14.2776 +     *
 14.2777 +     * <li>There is a one-to-one mapping between the distinguishable
 14.2778 +     * {@code BigDecimal} values and the result of this conversion.
 14.2779 +     * That is, every distinguishable {@code BigDecimal} value
 14.2780 +     * (unscaled value and scale) has a unique string representation
 14.2781 +     * as a result of using {@code toString}.  If that string
 14.2782 +     * representation is converted back to a {@code BigDecimal} using
 14.2783 +     * the {@link #BigDecimal(String)} constructor, then the original
 14.2784 +     * value will be recovered.
 14.2785 +     *
 14.2786 +     * <li>The string produced for a given number is always the same;
 14.2787 +     * it is not affected by locale.  This means that it can be used
 14.2788 +     * as a canonical string representation for exchanging decimal
 14.2789 +     * data, or as a key for a Hashtable, etc.  Locale-sensitive
 14.2790 +     * number formatting and parsing is handled by the {@link
 14.2791 +     * java.text.NumberFormat} class and its subclasses.
 14.2792 +     *
 14.2793 +     * <li>The {@link #toEngineeringString} method may be used for
 14.2794 +     * presenting numbers with exponents in engineering notation, and the
 14.2795 +     * {@link #setScale(int,RoundingMode) setScale} method may be used for
 14.2796 +     * rounding a {@code BigDecimal} so it has a known number of digits after
 14.2797 +     * the decimal point.
 14.2798 +     *
 14.2799 +     * <li>The digit-to-character mapping provided by
 14.2800 +     * {@code Character.forDigit} is used.
 14.2801 +     *
 14.2802 +     * </ol>
 14.2803 +     *
 14.2804 +     * @return string representation of this {@code BigDecimal}.
 14.2805 +     * @see    Character#forDigit
 14.2806 +     * @see    #BigDecimal(java.lang.String)
 14.2807 +     */
 14.2808 +    @Override
 14.2809 +    public String toString() {
 14.2810 +        String sc = stringCache;
 14.2811 +        if (sc == null)
 14.2812 +            stringCache = sc = layoutChars(true);
 14.2813 +        return sc;
 14.2814 +    }
 14.2815 +
 14.2816 +    /**
 14.2817 +     * Returns a string representation of this {@code BigDecimal},
 14.2818 +     * using engineering notation if an exponent is needed.
 14.2819 +     *
 14.2820 +     * <p>Returns a string that represents the {@code BigDecimal} as
 14.2821 +     * described in the {@link #toString()} method, except that if
 14.2822 +     * exponential notation is used, the power of ten is adjusted to
 14.2823 +     * be a multiple of three (engineering notation) such that the
 14.2824 +     * integer part of nonzero values will be in the range 1 through
 14.2825 +     * 999.  If exponential notation is used for zero values, a
 14.2826 +     * decimal point and one or two fractional zero digits are used so
 14.2827 +     * that the scale of the zero value is preserved.  Note that
 14.2828 +     * unlike the output of {@link #toString()}, the output of this
 14.2829 +     * method is <em>not</em> guaranteed to recover the same [integer,
 14.2830 +     * scale] pair of this {@code BigDecimal} if the output string is
 14.2831 +     * converting back to a {@code BigDecimal} using the {@linkplain
 14.2832 +     * #BigDecimal(String) string constructor}.  The result of this method meets
 14.2833 +     * the weaker constraint of always producing a numerically equal
 14.2834 +     * result from applying the string constructor to the method's output.
 14.2835 +     *
 14.2836 +     * @return string representation of this {@code BigDecimal}, using
 14.2837 +     *         engineering notation if an exponent is needed.
 14.2838 +     * @since  1.5
 14.2839 +     */
 14.2840 +    public String toEngineeringString() {
 14.2841 +        return layoutChars(false);
 14.2842 +    }
 14.2843 +
 14.2844 +    /**
 14.2845 +     * Returns a string representation of this {@code BigDecimal}
 14.2846 +     * without an exponent field.  For values with a positive scale,
 14.2847 +     * the number of digits to the right of the decimal point is used
 14.2848 +     * to indicate scale.  For values with a zero or negative scale,
 14.2849 +     * the resulting string is generated as if the value were
 14.2850 +     * converted to a numerically equal value with zero scale and as
 14.2851 +     * if all the trailing zeros of the zero scale value were present
 14.2852 +     * in the result.
 14.2853 +     *
 14.2854 +     * The entire string is prefixed by a minus sign character '-'
 14.2855 +     * (<tt>'&#92;u002D'</tt>) if the unscaled value is less than
 14.2856 +     * zero. No sign character is prefixed if the unscaled value is
 14.2857 +     * zero or positive.
 14.2858 +     *
 14.2859 +     * Note that if the result of this method is passed to the
 14.2860 +     * {@linkplain #BigDecimal(String) string constructor}, only the
 14.2861 +     * numerical value of this {@code BigDecimal} will necessarily be
 14.2862 +     * recovered; the representation of the new {@code BigDecimal}
 14.2863 +     * may have a different scale.  In particular, if this
 14.2864 +     * {@code BigDecimal} has a negative scale, the string resulting
 14.2865 +     * from this method will have a scale of zero when processed by
 14.2866 +     * the string constructor.
 14.2867 +     *
 14.2868 +     * (This method behaves analogously to the {@code toString}
 14.2869 +     * method in 1.4 and earlier releases.)
 14.2870 +     *
 14.2871 +     * @return a string representation of this {@code BigDecimal}
 14.2872 +     * without an exponent field.
 14.2873 +     * @since 1.5
 14.2874 +     * @see #toString()
 14.2875 +     * @see #toEngineeringString()
 14.2876 +     */
 14.2877 +    public String toPlainString() {
 14.2878 +        BigDecimal bd = this;
 14.2879 +        if (bd.scale < 0)
 14.2880 +            bd = bd.setScale(0);
 14.2881 +        bd.inflate();
 14.2882 +        if (bd.scale == 0)      // No decimal point
 14.2883 +            return bd.intVal.toString();
 14.2884 +        return bd.getValueString(bd.signum(), bd.intVal.abs().toString(), bd.scale);
 14.2885 +    }
 14.2886 +
 14.2887 +    /* Returns a digit.digit string */
 14.2888 +    private String getValueString(int signum, String intString, int scale) {
 14.2889 +        /* Insert decimal point */
 14.2890 +        StringBuilder buf;
 14.2891 +        int insertionPoint = intString.length() - scale;
 14.2892 +        if (insertionPoint == 0) {  /* Point goes right before intVal */
 14.2893 +            return (signum<0 ? "-0." : "0.") + intString;
 14.2894 +        } else if (insertionPoint > 0) { /* Point goes inside intVal */
 14.2895 +            buf = new StringBuilder(intString);
 14.2896 +            buf.insert(insertionPoint, '.');
 14.2897 +            if (signum < 0)
 14.2898 +                buf.insert(0, '-');
 14.2899 +        } else { /* We must insert zeros between point and intVal */
 14.2900 +            buf = new StringBuilder(3-insertionPoint + intString.length());
 14.2901 +            buf.append(signum<0 ? "-0." : "0.");
 14.2902 +            for (int i=0; i<-insertionPoint; i++)
 14.2903 +                buf.append('0');
 14.2904 +            buf.append(intString);
 14.2905 +        }
 14.2906 +        return buf.toString();
 14.2907 +    }
 14.2908 +
 14.2909 +    /**
 14.2910 +     * Converts this {@code BigDecimal} to a {@code BigInteger}.
 14.2911 +     * This conversion is analogous to the
 14.2912 +     * <i>narrowing primitive conversion</i> from {@code double} to
 14.2913 +     * {@code long} as defined in section 5.1.3 of
 14.2914 +     * <cite>The Java&trade; Language Specification</cite>:
 14.2915 +     * any fractional part of this
 14.2916 +     * {@code BigDecimal} will be discarded.  Note that this
 14.2917 +     * conversion can lose information about the precision of the
 14.2918 +     * {@code BigDecimal} value.
 14.2919 +     * <p>
 14.2920 +     * To have an exception thrown if the conversion is inexact (in
 14.2921 +     * other words if a nonzero fractional part is discarded), use the
 14.2922 +     * {@link #toBigIntegerExact()} method.
 14.2923 +     *
 14.2924 +     * @return this {@code BigDecimal} converted to a {@code BigInteger}.
 14.2925 +     */
 14.2926 +    public BigInteger toBigInteger() {
 14.2927 +        // force to an integer, quietly
 14.2928 +        return this.setScale(0, ROUND_DOWN).inflate();
 14.2929 +    }
 14.2930 +
 14.2931 +    /**
 14.2932 +     * Converts this {@code BigDecimal} to a {@code BigInteger},
 14.2933 +     * checking for lost information.  An exception is thrown if this
 14.2934 +     * {@code BigDecimal} has a nonzero fractional part.
 14.2935 +     *
 14.2936 +     * @return this {@code BigDecimal} converted to a {@code BigInteger}.
 14.2937 +     * @throws ArithmeticException if {@code this} has a nonzero
 14.2938 +     *         fractional part.
 14.2939 +     * @since  1.5
 14.2940 +     */
 14.2941 +    public BigInteger toBigIntegerExact() {
 14.2942 +        // round to an integer, with Exception if decimal part non-0
 14.2943 +        return this.setScale(0, ROUND_UNNECESSARY).inflate();
 14.2944 +    }
 14.2945 +
 14.2946 +    /**
 14.2947 +     * Converts this {@code BigDecimal} to a {@code long}.
 14.2948 +     * This conversion is analogous to the
 14.2949 +     * <i>narrowing primitive conversion</i> from {@code double} to
 14.2950 +     * {@code short} as defined in section 5.1.3 of
 14.2951 +     * <cite>The Java&trade; Language Specification</cite>:
 14.2952 +     * any fractional part of this
 14.2953 +     * {@code BigDecimal} will be discarded, and if the resulting
 14.2954 +     * "{@code BigInteger}" is too big to fit in a
 14.2955 +     * {@code long}, only the low-order 64 bits are returned.
 14.2956 +     * Note that this conversion can lose information about the
 14.2957 +     * overall magnitude and precision of this {@code BigDecimal} value as well
 14.2958 +     * as return a result with the opposite sign.
 14.2959 +     *
 14.2960 +     * @return this {@code BigDecimal} converted to a {@code long}.
 14.2961 +     */
 14.2962 +    public long longValue(){
 14.2963 +        return (intCompact != INFLATED && scale == 0) ?
 14.2964 +            intCompact:
 14.2965 +            toBigInteger().longValue();
 14.2966 +    }
 14.2967 +
 14.2968 +    /**
 14.2969 +     * Converts this {@code BigDecimal} to a {@code long}, checking
 14.2970 +     * for lost information.  If this {@code BigDecimal} has a
 14.2971 +     * nonzero fractional part or is out of the possible range for a
 14.2972 +     * {@code long} result then an {@code ArithmeticException} is
 14.2973 +     * thrown.
 14.2974 +     *
 14.2975 +     * @return this {@code BigDecimal} converted to a {@code long}.
 14.2976 +     * @throws ArithmeticException if {@code this} has a nonzero
 14.2977 +     *         fractional part, or will not fit in a {@code long}.
 14.2978 +     * @since  1.5
 14.2979 +     */
 14.2980 +    public long longValueExact() {
 14.2981 +        if (intCompact != INFLATED && scale == 0)
 14.2982 +            return intCompact;
 14.2983 +        // If more than 19 digits in integer part it cannot possibly fit
 14.2984 +        if ((precision() - scale) > 19) // [OK for negative scale too]
 14.2985 +            throw new java.lang.ArithmeticException("Overflow");
 14.2986 +        // Fastpath zero and < 1.0 numbers (the latter can be very slow
 14.2987 +        // to round if very small)
 14.2988 +        if (this.signum() == 0)
 14.2989 +            return 0;
 14.2990 +        if ((this.precision() - this.scale) <= 0)
 14.2991 +            throw new ArithmeticException("Rounding necessary");
 14.2992 +        // round to an integer, with Exception if decimal part non-0
 14.2993 +        BigDecimal num = this.setScale(0, ROUND_UNNECESSARY);
 14.2994 +        if (num.precision() >= 19) // need to check carefully
 14.2995 +            LongOverflow.check(num);
 14.2996 +        return num.inflate().longValue();
 14.2997 +    }
 14.2998 +
 14.2999 +    private static class LongOverflow {
 14.3000 +        /** BigInteger equal to Long.MIN_VALUE. */
 14.3001 +        private static final BigInteger LONGMIN = BigInteger.valueOf(Long.MIN_VALUE);
 14.3002 +
 14.3003 +        /** BigInteger equal to Long.MAX_VALUE. */
 14.3004 +        private static final BigInteger LONGMAX = BigInteger.valueOf(Long.MAX_VALUE);
 14.3005 +
 14.3006 +        public static void check(BigDecimal num) {
 14.3007 +            num.inflate();
 14.3008 +            if ((num.intVal.compareTo(LONGMIN) < 0) ||
 14.3009 +                (num.intVal.compareTo(LONGMAX) > 0))
 14.3010 +                throw new java.lang.ArithmeticException("Overflow");
 14.3011 +        }
 14.3012 +    }
 14.3013 +
 14.3014 +    /**
 14.3015 +     * Converts this {@code BigDecimal} to an {@code int}.
 14.3016 +     * This conversion is analogous to the
 14.3017 +     * <i>narrowing primitive conversion</i> from {@code double} to
 14.3018 +     * {@code short} as defined in section 5.1.3 of
 14.3019 +     * <cite>The Java&trade; Language Specification</cite>:
 14.3020 +     * any fractional part of this
 14.3021 +     * {@code BigDecimal} will be discarded, and if the resulting
 14.3022 +     * "{@code BigInteger}" is too big to fit in an
 14.3023 +     * {@code int}, only the low-order 32 bits are returned.
 14.3024 +     * Note that this conversion can lose information about the
 14.3025 +     * overall magnitude and precision of this {@code BigDecimal}
 14.3026 +     * value as well as return a result with the opposite sign.
 14.3027 +     *
 14.3028 +     * @return this {@code BigDecimal} converted to an {@code int}.
 14.3029 +     */
 14.3030 +    public int intValue() {
 14.3031 +        return  (intCompact != INFLATED && scale == 0) ?
 14.3032 +            (int)intCompact :
 14.3033 +            toBigInteger().intValue();
 14.3034 +    }
 14.3035 +
 14.3036 +    /**
 14.3037 +     * Converts this {@code BigDecimal} to an {@code int}, checking
 14.3038 +     * for lost information.  If this {@code BigDecimal} has a
 14.3039 +     * nonzero fractional part or is out of the possible range for an
 14.3040 +     * {@code int} result then an {@code ArithmeticException} is
 14.3041 +     * thrown.
 14.3042 +     *
 14.3043 +     * @return this {@code BigDecimal} converted to an {@code int}.
 14.3044 +     * @throws ArithmeticException if {@code this} has a nonzero
 14.3045 +     *         fractional part, or will not fit in an {@code int}.
 14.3046 +     * @since  1.5
 14.3047 +     */
 14.3048 +    public int intValueExact() {
 14.3049 +       long num;
 14.3050 +       num = this.longValueExact();     // will check decimal part
 14.3051 +       if ((int)num != num)
 14.3052 +           throw new java.lang.ArithmeticException("Overflow");
 14.3053 +       return (int)num;
 14.3054 +    }
 14.3055 +
 14.3056 +    /**
 14.3057 +     * Converts this {@code BigDecimal} to a {@code short}, checking
 14.3058 +     * for lost information.  If this {@code BigDecimal} has a
 14.3059 +     * nonzero fractional part or is out of the possible range for a
 14.3060 +     * {@code short} result then an {@code ArithmeticException} is
 14.3061 +     * thrown.
 14.3062 +     *
 14.3063 +     * @return this {@code BigDecimal} converted to a {@code short}.
 14.3064 +     * @throws ArithmeticException if {@code this} has a nonzero
 14.3065 +     *         fractional part, or will not fit in a {@code short}.
 14.3066 +     * @since  1.5
 14.3067 +     */
 14.3068 +    public short shortValueExact() {
 14.3069 +       long num;
 14.3070 +       num = this.longValueExact();     // will check decimal part
 14.3071 +       if ((short)num != num)
 14.3072 +           throw new java.lang.ArithmeticException("Overflow");
 14.3073 +       return (short)num;
 14.3074 +    }
 14.3075 +
 14.3076 +    /**
 14.3077 +     * Converts this {@code BigDecimal} to a {@code byte}, checking
 14.3078 +     * for lost information.  If this {@code BigDecimal} has a
 14.3079 +     * nonzero fractional part or is out of the possible range for a
 14.3080 +     * {@code byte} result then an {@code ArithmeticException} is
 14.3081 +     * thrown.
 14.3082 +     *
 14.3083 +     * @return this {@code BigDecimal} converted to a {@code byte}.
 14.3084 +     * @throws ArithmeticException if {@code this} has a nonzero
 14.3085 +     *         fractional part, or will not fit in a {@code byte}.
 14.3086 +     * @since  1.5
 14.3087 +     */
 14.3088 +    public byte byteValueExact() {
 14.3089 +       long num;
 14.3090 +       num = this.longValueExact();     // will check decimal part
 14.3091 +       if ((byte)num != num)
 14.3092 +           throw new java.lang.ArithmeticException("Overflow");
 14.3093 +       return (byte)num;
 14.3094 +    }
 14.3095 +
 14.3096 +    /**
 14.3097 +     * Converts this {@code BigDecimal} to a {@code float}.
 14.3098 +     * This conversion is similar to the
 14.3099 +     * <i>narrowing primitive conversion</i> from {@code double} to
 14.3100 +     * {@code float} as defined in section 5.1.3 of
 14.3101 +     * <cite>The Java&trade; Language Specification</cite>:
 14.3102 +     * if this {@code BigDecimal} has too great a
 14.3103 +     * magnitude to represent as a {@code float}, it will be
 14.3104 +     * converted to {@link Float#NEGATIVE_INFINITY} or {@link
 14.3105 +     * Float#POSITIVE_INFINITY} as appropriate.  Note that even when
 14.3106 +     * the return value is finite, this conversion can lose
 14.3107 +     * information about the precision of the {@code BigDecimal}
 14.3108 +     * value.
 14.3109 +     *
 14.3110 +     * @return this {@code BigDecimal} converted to a {@code float}.
 14.3111 +     */
 14.3112 +    public float floatValue(){
 14.3113 +        if (scale == 0 && intCompact != INFLATED)
 14.3114 +                return (float)intCompact;
 14.3115 +        // Somewhat inefficient, but guaranteed to work.
 14.3116 +        return Float.parseFloat(this.toString());
 14.3117 +    }
 14.3118 +
 14.3119 +    /**
 14.3120 +     * Converts this {@code BigDecimal} to a {@code double}.
 14.3121 +     * This conversion is similar to the
 14.3122 +     * <i>narrowing primitive conversion</i> from {@code double} to
 14.3123 +     * {@code float} as defined in section 5.1.3 of
 14.3124 +     * <cite>The Java&trade; Language Specification</cite>:
 14.3125 +     * if this {@code BigDecimal} has too great a
 14.3126 +     * magnitude represent as a {@code double}, it will be
 14.3127 +     * converted to {@link Double#NEGATIVE_INFINITY} or {@link
 14.3128 +     * Double#POSITIVE_INFINITY} as appropriate.  Note that even when
 14.3129 +     * the return value is finite, this conversion can lose
 14.3130 +     * information about the precision of the {@code BigDecimal}
 14.3131 +     * value.
 14.3132 +     *
 14.3133 +     * @return this {@code BigDecimal} converted to a {@code double}.
 14.3134 +     */
 14.3135 +    public double doubleValue(){
 14.3136 +        if (scale == 0 && intCompact != INFLATED)
 14.3137 +            return (double)intCompact;
 14.3138 +        // Somewhat inefficient, but guaranteed to work.
 14.3139 +        return Double.parseDouble(this.toString());
 14.3140 +    }
 14.3141 +
 14.3142 +    /**
 14.3143 +     * Returns the size of an ulp, a unit in the last place, of this
 14.3144 +     * {@code BigDecimal}.  An ulp of a nonzero {@code BigDecimal}
 14.3145 +     * value is the positive distance between this value and the
 14.3146 +     * {@code BigDecimal} value next larger in magnitude with the
 14.3147 +     * same number of digits.  An ulp of a zero value is numerically
 14.3148 +     * equal to 1 with the scale of {@code this}.  The result is
 14.3149 +     * stored with the same scale as {@code this} so the result
 14.3150 +     * for zero and nonzero values is equal to {@code [1,
 14.3151 +     * this.scale()]}.
 14.3152 +     *
 14.3153 +     * @return the size of an ulp of {@code this}
 14.3154 +     * @since 1.5
 14.3155 +     */
 14.3156 +    public BigDecimal ulp() {
 14.3157 +        return BigDecimal.valueOf(1, this.scale());
 14.3158 +    }
 14.3159 +
 14.3160 +
 14.3161 +    // Private class to build a string representation for BigDecimal object.
 14.3162 +    // "StringBuilderHelper" is constructed as a thread local variable so it is
 14.3163 +    // thread safe. The StringBuilder field acts as a buffer to hold the temporary
 14.3164 +    // representation of BigDecimal. The cmpCharArray holds all the characters for
 14.3165 +    // the compact representation of BigDecimal (except for '-' sign' if it is
 14.3166 +    // negative) if its intCompact field is not INFLATED. It is shared by all
 14.3167 +    // calls to toString() and its variants in that particular thread.
 14.3168 +    static class StringBuilderHelper {
 14.3169 +        final StringBuilder sb;    // Placeholder for BigDecimal string
 14.3170 +        final char[] cmpCharArray; // character array to place the intCompact
 14.3171 +
 14.3172 +        StringBuilderHelper() {
 14.3173 +            sb = new StringBuilder();
 14.3174 +            // All non negative longs can be made to fit into 19 character array.
 14.3175 +            cmpCharArray = new char[19];
 14.3176 +        }
 14.3177 +
 14.3178 +        // Accessors.
 14.3179 +        StringBuilder getStringBuilder() {
 14.3180 +            sb.setLength(0);
 14.3181 +            return sb;
 14.3182 +        }
 14.3183 +
 14.3184 +        char[] getCompactCharArray() {
 14.3185 +            return cmpCharArray;
 14.3186 +        }
 14.3187 +
 14.3188 +        /**
 14.3189 +         * Places characters representing the intCompact in {@code long} into
 14.3190 +         * cmpCharArray and returns the offset to the array where the
 14.3191 +         * representation starts.
 14.3192 +         *
 14.3193 +         * @param intCompact the number to put into the cmpCharArray.
 14.3194 +         * @return offset to the array where the representation starts.
 14.3195 +         * Note: intCompact must be greater or equal to zero.
 14.3196 +         */
 14.3197 +        int putIntCompact(long intCompact) {
 14.3198 +            assert intCompact >= 0;
 14.3199 +
 14.3200 +            long q;
 14.3201 +            int r;
 14.3202 +            // since we start from the least significant digit, charPos points to
 14.3203 +            // the last character in cmpCharArray.
 14.3204 +            int charPos = cmpCharArray.length;
 14.3205 +
 14.3206 +            // Get 2 digits/iteration using longs until quotient fits into an int
 14.3207 +            while (intCompact > Integer.MAX_VALUE) {
 14.3208 +                q = intCompact / 100;
 14.3209 +                r = (int)(intCompact - q * 100);
 14.3210 +                intCompact = q;
 14.3211 +                cmpCharArray[--charPos] = DIGIT_ONES[r];
 14.3212 +                cmpCharArray[--charPos] = DIGIT_TENS[r];
 14.3213 +            }
 14.3214 +
 14.3215 +            // Get 2 digits/iteration using ints when i2 >= 100
 14.3216 +            int q2;
 14.3217 +            int i2 = (int)intCompact;
 14.3218 +            while (i2 >= 100) {
 14.3219 +                q2 = i2 / 100;
 14.3220 +                r  = i2 - q2 * 100;
 14.3221 +                i2 = q2;
 14.3222 +                cmpCharArray[--charPos] = DIGIT_ONES[r];
 14.3223 +                cmpCharArray[--charPos] = DIGIT_TENS[r];
 14.3224 +            }
 14.3225 +
 14.3226 +            cmpCharArray[--charPos] = DIGIT_ONES[i2];
 14.3227 +            if (i2 >= 10)
 14.3228 +                cmpCharArray[--charPos] = DIGIT_TENS[i2];
 14.3229 +
 14.3230 +            return charPos;
 14.3231 +        }
 14.3232 +
 14.3233 +        final static char[] DIGIT_TENS = {
 14.3234 +            '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
 14.3235 +            '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
 14.3236 +            '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
 14.3237 +            '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
 14.3238 +            '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
 14.3239 +            '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
 14.3240 +            '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
 14.3241 +            '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
 14.3242 +            '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
 14.3243 +            '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
 14.3244 +        };
 14.3245 +
 14.3246 +        final static char[] DIGIT_ONES = {
 14.3247 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3248 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3249 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3250 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3251 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3252 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3253 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3254 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3255 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3256 +            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
 14.3257 +        };
 14.3258 +    }
 14.3259 +
 14.3260 +    /**
 14.3261 +     * Lay out this {@code BigDecimal} into a {@code char[]} array.
 14.3262 +     * The Java 1.2 equivalent to this was called {@code getValueString}.
 14.3263 +     *
 14.3264 +     * @param  sci {@code true} for Scientific exponential notation;
 14.3265 +     *          {@code false} for Engineering
 14.3266 +     * @return string with canonical string representation of this
 14.3267 +     *         {@code BigDecimal}
 14.3268 +     */
 14.3269 +    private String layoutChars(boolean sci) {
 14.3270 +        if (scale == 0)                      // zero scale is trivial
 14.3271 +            return (intCompact != INFLATED) ?
 14.3272 +                Long.toString(intCompact):
 14.3273 +                intVal.toString();
 14.3274 +
 14.3275 +        StringBuilderHelper sbHelper = threadLocalStringBuilderHelper.get();
 14.3276 +        char[] coeff;
 14.3277 +        int offset;  // offset is the starting index for coeff array
 14.3278 +        // Get the significand as an absolute value
 14.3279 +        if (intCompact != INFLATED) {
 14.3280 +            offset = sbHelper.putIntCompact(Math.abs(intCompact));
 14.3281 +            coeff  = sbHelper.getCompactCharArray();
 14.3282 +        } else {
 14.3283 +            offset = 0;
 14.3284 +            coeff  = intVal.abs().toString().toCharArray();
 14.3285 +        }
 14.3286 +
 14.3287 +        // Construct a buffer, with sufficient capacity for all cases.
 14.3288 +        // If E-notation is needed, length will be: +1 if negative, +1
 14.3289 +        // if '.' needed, +2 for "E+", + up to 10 for adjusted exponent.
 14.3290 +        // Otherwise it could have +1 if negative, plus leading "0.00000"
 14.3291 +        StringBuilder buf = sbHelper.getStringBuilder();
 14.3292 +        if (signum() < 0)             // prefix '-' if negative
 14.3293 +            buf.append('-');
 14.3294 +        int coeffLen = coeff.length - offset;
 14.3295 +        long adjusted = -(long)scale + (coeffLen -1);
 14.3296 +        if ((scale >= 0) && (adjusted >= -6)) { // plain number
 14.3297 +            int pad = scale - coeffLen;         // count of padding zeros
 14.3298 +            if (pad >= 0) {                     // 0.xxx form
 14.3299 +                buf.append('0');
 14.3300 +                buf.append('.');
 14.3301 +                for (; pad>0; pad--) {
 14.3302 +                    buf.append('0');
 14.3303 +                }
 14.3304 +                buf.append(coeff, offset, coeffLen);
 14.3305 +            } else {                         // xx.xx form
 14.3306 +                buf.append(coeff, offset, -pad);
 14.3307 +                buf.append('.');
 14.3308 +                buf.append(coeff, -pad + offset, scale);
 14.3309 +            }
 14.3310 +        } else { // E-notation is needed
 14.3311 +            if (sci) {                       // Scientific notation
 14.3312 +                buf.append(coeff[offset]);   // first character
 14.3313 +                if (coeffLen > 1) {          // more to come
 14.3314 +                    buf.append('.');
 14.3315 +                    buf.append(coeff, offset + 1, coeffLen - 1);
 14.3316 +                }
 14.3317 +            } else {                         // Engineering notation
 14.3318 +                int sig = (int)(adjusted % 3);
 14.3319 +                if (sig < 0)
 14.3320 +                    sig += 3;                // [adjusted was negative]
 14.3321 +                adjusted -= sig;             // now a multiple of 3
 14.3322 +                sig++;
 14.3323 +                if (signum() == 0) {
 14.3324 +                    switch (sig) {
 14.3325 +                    case 1:
 14.3326 +                        buf.append('0'); // exponent is a multiple of three
 14.3327 +                        break;
 14.3328 +                    case 2:
 14.3329 +                        buf.append("0.00");
 14.3330 +                        adjusted += 3;
 14.3331 +                        break;
 14.3332 +                    case 3:
 14.3333 +                        buf.append("0.0");
 14.3334 +                        adjusted += 3;
 14.3335 +                        break;
 14.3336 +                    default:
 14.3337 +                        throw new AssertionError("Unexpected sig value " + sig);
 14.3338 +                    }
 14.3339 +                } else if (sig >= coeffLen) {   // significand all in integer
 14.3340 +                    buf.append(coeff, offset, coeffLen);
 14.3341 +                    // may need some zeros, too
 14.3342 +                    for (int i = sig - coeffLen; i > 0; i--)
 14.3343 +                        buf.append('0');
 14.3344 +                } else {                     // xx.xxE form
 14.3345 +                    buf.append(coeff, offset, sig);
 14.3346 +                    buf.append('.');
 14.3347 +                    buf.append(coeff, offset + sig, coeffLen - sig);
 14.3348 +                }
 14.3349 +            }
 14.3350 +            if (adjusted != 0) {             // [!sci could have made 0]
 14.3351 +                buf.append('E');
 14.3352 +                if (adjusted > 0)            // force sign for positive
 14.3353 +                    buf.append('+');
 14.3354 +                buf.append(adjusted);
 14.3355 +            }
 14.3356 +        }
 14.3357 +        return buf.toString();
 14.3358 +    }
 14.3359 +
 14.3360 +    /**
 14.3361 +     * Return 10 to the power n, as a {@code BigInteger}.
 14.3362 +     *
 14.3363 +     * @param  n the power of ten to be returned (>=0)
 14.3364 +     * @return a {@code BigInteger} with the value (10<sup>n</sup>)
 14.3365 +     */
 14.3366 +    private static BigInteger bigTenToThe(int n) {
 14.3367 +        if (n < 0)
 14.3368 +            return BigInteger.ZERO;
 14.3369 +
 14.3370 +        if (n < BIG_TEN_POWERS_TABLE_MAX) {
 14.3371 +            BigInteger[] pows = BIG_TEN_POWERS_TABLE;
 14.3372 +            if (n < pows.length)
 14.3373 +                return pows[n];
 14.3374 +            else
 14.3375 +                return expandBigIntegerTenPowers(n);
 14.3376 +        }
 14.3377 +        // BigInteger.pow is slow, so make 10**n by constructing a
 14.3378 +        // BigInteger from a character string (still not very fast)
 14.3379 +        char tenpow[] = new char[n + 1];
 14.3380 +        tenpow[0] = '1';
 14.3381 +        for (int i = 1; i <= n; i++)
 14.3382 +            tenpow[i] = '0';
 14.3383 +        return new BigInteger(tenpow);
 14.3384 +    }
 14.3385 +
 14.3386 +    /**
 14.3387 +     * Expand the BIG_TEN_POWERS_TABLE array to contain at least 10**n.
 14.3388 +     *
 14.3389 +     * @param n the power of ten to be returned (>=0)
 14.3390 +     * @return a {@code BigDecimal} with the value (10<sup>n</sup>) and
 14.3391 +     *         in the meantime, the BIG_TEN_POWERS_TABLE array gets
 14.3392 +     *         expanded to the size greater than n.
 14.3393 +     */
 14.3394 +    private static BigInteger expandBigIntegerTenPowers(int n) {
 14.3395 +        synchronized(BigDecimal.class) {
 14.3396 +            BigInteger[] pows = BIG_TEN_POWERS_TABLE;
 14.3397 +            int curLen = pows.length;
 14.3398 +            // The following comparison and the above synchronized statement is
 14.3399 +            // to prevent multiple threads from expanding the same array.
 14.3400 +            if (curLen <= n) {
 14.3401 +                int newLen = curLen << 1;
 14.3402 +                while (newLen <= n)
 14.3403 +                    newLen <<= 1;
 14.3404 +                pows = Arrays.copyOf(pows, newLen);
 14.3405 +                for (int i = curLen; i < newLen; i++)
 14.3406 +                    pows[i] = pows[i - 1].multiply(BigInteger.TEN);
 14.3407 +                // Based on the following facts:
 14.3408 +                // 1. pows is a private local varible;
 14.3409 +                // 2. the following store is a volatile store.
 14.3410 +                // the newly created array elements can be safely published.
 14.3411 +                BIG_TEN_POWERS_TABLE = pows;
 14.3412 +            }
 14.3413 +            return pows[n];
 14.3414 +        }
 14.3415 +    }
 14.3416 +
 14.3417 +    private static final long[] LONG_TEN_POWERS_TABLE = {
 14.3418 +        1,                     // 0 / 10^0
 14.3419 +        10,                    // 1 / 10^1
 14.3420 +        100,                   // 2 / 10^2
 14.3421 +        1000,                  // 3 / 10^3
 14.3422 +        10000,                 // 4 / 10^4
 14.3423 +        100000,                // 5 / 10^5
 14.3424 +        1000000,               // 6 / 10^6
 14.3425 +        10000000,              // 7 / 10^7
 14.3426 +        100000000,             // 8 / 10^8
 14.3427 +        1000000000,            // 9 / 10^9
 14.3428 +        10000000000L,          // 10 / 10^10
 14.3429 +        100000000000L,         // 11 / 10^11
 14.3430 +        1000000000000L,        // 12 / 10^12
 14.3431 +        10000000000000L,       // 13 / 10^13
 14.3432 +        100000000000000L,      // 14 / 10^14
 14.3433 +        1000000000000000L,     // 15 / 10^15
 14.3434 +        10000000000000000L,    // 16 / 10^16
 14.3435 +        100000000000000000L,   // 17 / 10^17
 14.3436 +        1000000000000000000L   // 18 / 10^18
 14.3437 +    };
 14.3438 +
 14.3439 +    private static volatile BigInteger BIG_TEN_POWERS_TABLE[] = {BigInteger.ONE,
 14.3440 +        BigInteger.valueOf(10),       BigInteger.valueOf(100),
 14.3441 +        BigInteger.valueOf(1000),     BigInteger.valueOf(10000),
 14.3442 +        BigInteger.valueOf(100000),   BigInteger.valueOf(1000000),
 14.3443 +        BigInteger.valueOf(10000000), BigInteger.valueOf(100000000),
 14.3444 +        BigInteger.valueOf(1000000000),
 14.3445 +        BigInteger.valueOf(10000000000L),
 14.3446 +        BigInteger.valueOf(100000000000L),
 14.3447 +        BigInteger.valueOf(1000000000000L),
 14.3448 +        BigInteger.valueOf(10000000000000L),
 14.3449 +        BigInteger.valueOf(100000000000000L),
 14.3450 +        BigInteger.valueOf(1000000000000000L),
 14.3451 +        BigInteger.valueOf(10000000000000000L),
 14.3452 +        BigInteger.valueOf(100000000000000000L),
 14.3453 +        BigInteger.valueOf(1000000000000000000L)
 14.3454 +    };
 14.3455 +
 14.3456 +    private static final int BIG_TEN_POWERS_TABLE_INITLEN =
 14.3457 +        BIG_TEN_POWERS_TABLE.length;
 14.3458 +    private static final int BIG_TEN_POWERS_TABLE_MAX =
 14.3459 +        16 * BIG_TEN_POWERS_TABLE_INITLEN;
 14.3460 +
 14.3461 +    private static final long THRESHOLDS_TABLE[] = {
 14.3462 +        Long.MAX_VALUE,                     // 0
 14.3463 +        Long.MAX_VALUE/10L,                 // 1
 14.3464 +        Long.MAX_VALUE/100L,                // 2
 14.3465 +        Long.MAX_VALUE/1000L,               // 3
 14.3466 +        Long.MAX_VALUE/10000L,              // 4
 14.3467 +        Long.MAX_VALUE/100000L,             // 5
 14.3468 +        Long.MAX_VALUE/1000000L,            // 6
 14.3469 +        Long.MAX_VALUE/10000000L,           // 7
 14.3470 +        Long.MAX_VALUE/100000000L,          // 8
 14.3471 +        Long.MAX_VALUE/1000000000L,         // 9
 14.3472 +        Long.MAX_VALUE/10000000000L,        // 10
 14.3473 +        Long.MAX_VALUE/100000000000L,       // 11
 14.3474 +        Long.MAX_VALUE/1000000000000L,      // 12
 14.3475 +        Long.MAX_VALUE/10000000000000L,     // 13
 14.3476 +        Long.MAX_VALUE/100000000000000L,    // 14
 14.3477 +        Long.MAX_VALUE/1000000000000000L,   // 15
 14.3478 +        Long.MAX_VALUE/10000000000000000L,  // 16
 14.3479 +        Long.MAX_VALUE/100000000000000000L, // 17
 14.3480 +        Long.MAX_VALUE/1000000000000000000L // 18
 14.3481 +    };
 14.3482 +
 14.3483 +    /**
 14.3484 +     * Compute val * 10 ^ n; return this product if it is
 14.3485 +     * representable as a long, INFLATED otherwise.
 14.3486 +     */
 14.3487 +    private static long longMultiplyPowerTen(long val, int n) {
 14.3488 +        if (val == 0 || n <= 0)
 14.3489 +            return val;
 14.3490 +        long[] tab = LONG_TEN_POWERS_TABLE;
 14.3491 +        long[] bounds = THRESHOLDS_TABLE;
 14.3492 +        if (n < tab.length && n < bounds.length) {
 14.3493 +            long tenpower = tab[n];
 14.3494 +            if (val == 1)
 14.3495 +                return tenpower;
 14.3496 +            if (Math.abs(val) <= bounds[n])
 14.3497 +                return val * tenpower;
 14.3498 +        }
 14.3499 +        return INFLATED;
 14.3500 +    }
 14.3501 +
 14.3502 +    /**
 14.3503 +     * Compute this * 10 ^ n.
 14.3504 +     * Needed mainly to allow special casing to trap zero value
 14.3505 +     */
 14.3506 +    private BigInteger bigMultiplyPowerTen(int n) {
 14.3507 +        if (n <= 0)
 14.3508 +            return this.inflate();
 14.3509 +
 14.3510 +        if (intCompact != INFLATED)
 14.3511 +            return bigTenToThe(n).multiply(intCompact);
 14.3512 +        else
 14.3513 +            return intVal.multiply(bigTenToThe(n));
 14.3514 +    }
 14.3515 +
 14.3516 +    /**
 14.3517 +     * Assign appropriate BigInteger to intVal field if intVal is
 14.3518 +     * null, i.e. the compact representation is in use.
 14.3519 +     */
 14.3520 +    private BigInteger inflate() {
 14.3521 +        if (intVal == null)
 14.3522 +            intVal = BigInteger.valueOf(intCompact);
 14.3523 +        return intVal;
 14.3524 +    }
 14.3525 +
 14.3526 +    /**
 14.3527 +     * Match the scales of two {@code BigDecimal}s to align their
 14.3528 +     * least significant digits.
 14.3529 +     *
 14.3530 +     * <p>If the scales of val[0] and val[1] differ, rescale
 14.3531 +     * (non-destructively) the lower-scaled {@code BigDecimal} so
 14.3532 +     * they match.  That is, the lower-scaled reference will be
 14.3533 +     * replaced by a reference to a new object with the same scale as
 14.3534 +     * the other {@code BigDecimal}.
 14.3535 +     *
 14.3536 +     * @param  val array of two elements referring to the two
 14.3537 +     *         {@code BigDecimal}s to be aligned.
 14.3538 +     */
 14.3539 +    private static void matchScale(BigDecimal[] val) {
 14.3540 +        if (val[0].scale == val[1].scale) {
 14.3541 +            return;
 14.3542 +        } else if (val[0].scale < val[1].scale) {
 14.3543 +            val[0] = val[0].setScale(val[1].scale, ROUND_UNNECESSARY);
 14.3544 +        } else if (val[1].scale < val[0].scale) {
 14.3545 +            val[1] = val[1].setScale(val[0].scale, ROUND_UNNECESSARY);
 14.3546 +        }
 14.3547 +    }
 14.3548 +
 14.3549 +    /**
 14.3550 +     * Reconstitute the {@code BigDecimal} instance from a stream (that is,
 14.3551 +     * deserialize it).
 14.3552 +     *
 14.3553 +     * @param s the stream being read.
 14.3554 +     */
 14.3555 +    private void readObject(java.io.ObjectInputStream s)
 14.3556 +        throws java.io.IOException, ClassNotFoundException {
 14.3557 +        // Read in all fields
 14.3558 +        s.defaultReadObject();
 14.3559 +        // validate possibly bad fields
 14.3560 +        if (intVal == null) {
 14.3561 +            String message = "BigDecimal: null intVal in stream";
 14.3562 +            throw new java.io.StreamCorruptedException(message);
 14.3563 +        // [all values of scale are now allowed]
 14.3564 +        }
 14.3565 +        intCompact = compactValFor(intVal);
 14.3566 +    }
 14.3567 +
 14.3568 +   /**
 14.3569 +    * Serialize this {@code BigDecimal} to the stream in question
 14.3570 +    *
 14.3571 +    * @param s the stream to serialize to.
 14.3572 +    */
 14.3573 +   private void writeObject(java.io.ObjectOutputStream s)
 14.3574 +       throws java.io.IOException {
 14.3575 +       // Must inflate to maintain compatible serial form.
 14.3576 +       this.inflate();
 14.3577 +
 14.3578 +       // Write proper fields
 14.3579 +       s.defaultWriteObject();
 14.3580 +   }
 14.3581 +
 14.3582 +
 14.3583 +    /**
 14.3584 +     * Returns the length of the absolute value of a {@code long}, in decimal
 14.3585 +     * digits.
 14.3586 +     *
 14.3587 +     * @param x the {@code long}
 14.3588 +     * @return the length of the unscaled value, in deciaml digits.
 14.3589 +     */
 14.3590 +    private static int longDigitLength(long x) {
 14.3591 +        /*
 14.3592 +         * As described in "Bit Twiddling Hacks" by Sean Anderson,
 14.3593 +         * (http://graphics.stanford.edu/~seander/bithacks.html)
 14.3594 +         * integer log 10 of x is within 1 of
 14.3595 +         * (1233/4096)* (1 + integer log 2 of x).
 14.3596 +         * The fraction 1233/4096 approximates log10(2). So we first
 14.3597 +         * do a version of log2 (a variant of Long class with
 14.3598 +         * pre-checks and opposite directionality) and then scale and
 14.3599 +         * check against powers table. This is a little simpler in
 14.3600 +         * present context than the version in Hacker's Delight sec
 14.3601 +         * 11-4.  Adding one to bit length allows comparing downward
 14.3602 +         * from the LONG_TEN_POWERS_TABLE that we need anyway.
 14.3603 +         */
 14.3604 +        assert x != INFLATED;
 14.3605 +        if (x < 0)
 14.3606 +            x = -x;
 14.3607 +        if (x < 10) // must screen for 0, might as well 10
 14.3608 +            return 1;
 14.3609 +        int n = 64; // not 63, to avoid needing to add 1 later
 14.3610 +        int y = (int)(x >>> 32);
 14.3611 +        if (y == 0) { n -= 32; y = (int)x; }
 14.3612 +        if (y >>> 16 == 0) { n -= 16; y <<= 16; }
 14.3613 +        if (y >>> 24 == 0) { n -=  8; y <<=  8; }
 14.3614 +        if (y >>> 28 == 0) { n -=  4; y <<=  4; }
 14.3615 +        if (y >>> 30 == 0) { n -=  2; y <<=  2; }
 14.3616 +        int r = (((y >>> 31) + n) * 1233) >>> 12;
 14.3617 +        long[] tab = LONG_TEN_POWERS_TABLE;
 14.3618 +        // if r >= length, must have max possible digits for long
 14.3619 +        return (r >= tab.length || x < tab[r])? r : r+1;
 14.3620 +    }
 14.3621 +
 14.3622 +    /**
 14.3623 +     * Returns the length of the absolute value of a BigInteger, in
 14.3624 +     * decimal digits.
 14.3625 +     *
 14.3626 +     * @param b the BigInteger
 14.3627 +     * @return the length of the unscaled value, in decimal digits
 14.3628 +     */
 14.3629 +    private static int bigDigitLength(BigInteger b) {
 14.3630 +        /*
 14.3631 +         * Same idea as the long version, but we need a better
 14.3632 +         * approximation of log10(2). Using 646456993/2^31
 14.3633 +         * is accurate up to max possible reported bitLength.
 14.3634 +         */
 14.3635 +        if (b.signum == 0)
 14.3636 +            return 1;
 14.3637 +        int r = (int)((((long)b.bitLength() + 1) * 646456993) >>> 31);
 14.3638 +        return b.compareMagnitude(bigTenToThe(r)) < 0? r : r+1;
 14.3639 +    }
 14.3640 +
 14.3641 +
 14.3642 +    /**
 14.3643 +     * Remove insignificant trailing zeros from this
 14.3644 +     * {@code BigDecimal} until the preferred scale is reached or no
 14.3645 +     * more zeros can be removed.  If the preferred scale is less than
 14.3646 +     * Integer.MIN_VALUE, all the trailing zeros will be removed.
 14.3647 +     *
 14.3648 +     * {@code BigInteger} assistance could help, here?
 14.3649 +     *
 14.3650 +     * <p>WARNING: This method should only be called on new objects as
 14.3651 +     * it mutates the value fields.
 14.3652 +     *
 14.3653 +     * @return this {@code BigDecimal} with a scale possibly reduced
 14.3654 +     * to be closed to the preferred scale.
 14.3655 +     */
 14.3656 +    private BigDecimal stripZerosToMatchScale(long preferredScale) {
 14.3657 +        this.inflate();
 14.3658 +        BigInteger qr[];                // quotient-remainder pair
 14.3659 +        while ( intVal.compareMagnitude(BigInteger.TEN) >= 0 &&
 14.3660 +                scale > preferredScale) {
 14.3661 +            if (intVal.testBit(0))
 14.3662 +                break;                  // odd number cannot end in 0
 14.3663 +            qr = intVal.divideAndRemainder(BigInteger.TEN);
 14.3664 +            if (qr[1].signum() != 0)
 14.3665 +                break;                  // non-0 remainder
 14.3666 +            intVal=qr[0];
 14.3667 +            scale = checkScale((long)scale-1);  // could Overflow
 14.3668 +            if (precision > 0)          // adjust precision if known
 14.3669 +              precision--;
 14.3670 +        }
 14.3671 +        if (intVal != null)
 14.3672 +            intCompact = compactValFor(intVal);
 14.3673 +        return this;
 14.3674 +    }
 14.3675 +
 14.3676 +    /**
 14.3677 +     * Check a scale for Underflow or Overflow.  If this BigDecimal is
 14.3678 +     * nonzero, throw an exception if the scale is outof range. If this
 14.3679 +     * is zero, saturate the scale to the extreme value of the right
 14.3680 +     * sign if the scale is out of range.
 14.3681 +     *
 14.3682 +     * @param val The new scale.
 14.3683 +     * @throws ArithmeticException (overflow or underflow) if the new
 14.3684 +     *         scale is out of range.
 14.3685 +     * @return validated scale as an int.
 14.3686 +     */
 14.3687 +    private int checkScale(long val) {
 14.3688 +        int asInt = (int)val;
 14.3689 +        if (asInt != val) {
 14.3690 +            asInt = val>Integer.MAX_VALUE ? Integer.MAX_VALUE : Integer.MIN_VALUE;
 14.3691 +            BigInteger b;
 14.3692 +            if (intCompact != 0 &&
 14.3693 +                ((b = intVal) == null || b.signum() != 0))
 14.3694 +                throw new ArithmeticException(asInt>0 ? "Underflow":"Overflow");
 14.3695 +        }
 14.3696 +        return asInt;
 14.3697 +    }
 14.3698 +
 14.3699 +    /**
 14.3700 +     * Round an operand; used only if digits &gt; 0.  Does not change
 14.3701 +     * {@code this}; if rounding is needed a new {@code BigDecimal}
 14.3702 +     * is created and returned.
 14.3703 +     *
 14.3704 +     * @param mc the context to use.
 14.3705 +     * @throws ArithmeticException if the result is inexact but the
 14.3706 +     *         rounding mode is {@code UNNECESSARY}.
 14.3707 +     */
 14.3708 +    private BigDecimal roundOp(MathContext mc) {
 14.3709 +        BigDecimal rounded = doRound(this, mc);
 14.3710 +        return rounded;
 14.3711 +    }
 14.3712 +
 14.3713 +    /** Round this BigDecimal according to the MathContext settings;
 14.3714 +     *  used only if precision {@literal >} 0.
 14.3715 +     *
 14.3716 +     * <p>WARNING: This method should only be called on new objects as
 14.3717 +     * it mutates the value fields.
 14.3718 +     *
 14.3719 +     * @param mc the context to use.
 14.3720 +     * @throws ArithmeticException if the rounding mode is
 14.3721 +     *         {@code RoundingMode.UNNECESSARY} and the
 14.3722 +     *         {@code BigDecimal} operation would require rounding.
 14.3723 +     */
 14.3724 +    private void roundThis(MathContext mc) {
 14.3725 +        BigDecimal rounded = doRound(this, mc);
 14.3726 +        if (rounded == this)                 // wasn't rounded
 14.3727 +            return;
 14.3728 +        this.intVal     = rounded.intVal;
 14.3729 +        this.intCompact = rounded.intCompact;
 14.3730 +        this.scale      = rounded.scale;
 14.3731 +        this.precision  = rounded.precision;
 14.3732 +    }
 14.3733 +
 14.3734 +    /**
 14.3735 +     * Returns a {@code BigDecimal} rounded according to the
 14.3736 +     * MathContext settings; used only if {@code mc.precision > 0}.
 14.3737 +     * Does not change {@code this}; if rounding is needed a new
 14.3738 +     * {@code BigDecimal} is created and returned.
 14.3739 +     *
 14.3740 +     * @param mc the context to use.
 14.3741 +     * @return a {@code BigDecimal} rounded according to the MathContext
 14.3742 +     *         settings.  May return this, if no rounding needed.
 14.3743 +     * @throws ArithmeticException if the rounding mode is
 14.3744 +     *         {@code RoundingMode.UNNECESSARY} and the
 14.3745 +     *         result is inexact.
 14.3746 +     */
 14.3747 +    private static BigDecimal doRound(BigDecimal d, MathContext mc) {
 14.3748 +        int mcp = mc.precision;
 14.3749 +        int drop;
 14.3750 +        // This might (rarely) iterate to cover the 999=>1000 case
 14.3751 +        while ((drop = d.precision() - mcp) > 0) {
 14.3752 +            int newScale = d.checkScale((long)d.scale - drop);
 14.3753 +            int mode = mc.roundingMode.oldMode;
 14.3754 +            if (drop < LONG_TEN_POWERS_TABLE.length)
 14.3755 +                d = divideAndRound(d.intCompact, d.intVal,
 14.3756 +                                   LONG_TEN_POWERS_TABLE[drop], null,
 14.3757 +                                   newScale, mode, newScale);
 14.3758 +            else
 14.3759 +                d = divideAndRound(d.intCompact, d.intVal,
 14.3760 +                                   INFLATED, bigTenToThe(drop),
 14.3761 +                                   newScale, mode, newScale);
 14.3762 +        }
 14.3763 +        return d;
 14.3764 +    }
 14.3765 +
 14.3766 +    /**
 14.3767 +     * Returns the compact value for given {@code BigInteger}, or
 14.3768 +     * INFLATED if too big. Relies on internal representation of
 14.3769 +     * {@code BigInteger}.
 14.3770 +     */
 14.3771 +    private static long compactValFor(BigInteger b) {
 14.3772 +        int[] m = b.mag;
 14.3773 +        int len = m.length;
 14.3774 +        if (len == 0)
 14.3775 +            return 0;
 14.3776 +        int d = m[0];
 14.3777 +        if (len > 2 || (len == 2 && d < 0))
 14.3778 +            return INFLATED;
 14.3779 +
 14.3780 +        long u = (len == 2)?
 14.3781 +            (((long) m[1] & LONG_MASK) + (((long)d) << 32)) :
 14.3782 +            (((long)d)   & LONG_MASK);
 14.3783 +        return (b.signum < 0)? -u : u;
 14.3784 +    }
 14.3785 +
 14.3786 +    private static int longCompareMagnitude(long x, long y) {
 14.3787 +        if (x < 0)
 14.3788 +            x = -x;
 14.3789 +        if (y < 0)
 14.3790 +            y = -y;
 14.3791 +        return (x < y) ? -1 : ((x == y) ? 0 : 1);
 14.3792 +    }
 14.3793 +
 14.3794 +    private static int saturateLong(long s) {
 14.3795 +        int i = (int)s;
 14.3796 +        return (s == i) ? i : (s < 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE);
 14.3797 +    }
 14.3798 +
 14.3799 +    /*
 14.3800 +     * Internal printing routine
 14.3801 +     */
 14.3802 +    private static void print(String name, BigDecimal bd) {
 14.3803 +        System.err.format("%s:\tintCompact %d\tintVal %d\tscale %d\tprecision %d%n",
 14.3804 +                          name,
 14.3805 +                          bd.intCompact,
 14.3806 +                          bd.intVal,
 14.3807 +                          bd.scale,
 14.3808 +                          bd.precision);
 14.3809 +    }
 14.3810 +
 14.3811 +    /**
 14.3812 +     * Check internal invariants of this BigDecimal.  These invariants
 14.3813 +     * include:
 14.3814 +     *
 14.3815 +     * <ul>
 14.3816 +     *
 14.3817 +     * <li>The object must be initialized; either intCompact must not be
 14.3818 +     * INFLATED or intVal is non-null.  Both of these conditions may
 14.3819 +     * be true.
 14.3820 +     *
 14.3821 +     * <li>If both intCompact and intVal and set, their values must be
 14.3822 +     * consistent.
 14.3823 +     *
 14.3824 +     * <li>If precision is nonzero, it must have the right value.
 14.3825 +     * </ul>
 14.3826 +     *
 14.3827 +     * Note: Since this is an audit method, we are not supposed to change the
 14.3828 +     * state of this BigDecimal object.
 14.3829 +     */
 14.3830 +    private BigDecimal audit() {
 14.3831 +        if (intCompact == INFLATED) {
 14.3832 +            if (intVal == null) {
 14.3833 +                print("audit", this);
 14.3834 +                throw new AssertionError("null intVal");
 14.3835 +            }
 14.3836 +            // Check precision
 14.3837 +            if (precision > 0 && precision != bigDigitLength(intVal)) {
 14.3838 +                print("audit", this);
 14.3839 +                throw new AssertionError("precision mismatch");
 14.3840 +            }
 14.3841 +        } else {
 14.3842 +            if (intVal != null) {
 14.3843 +                long val = intVal.longValue();
 14.3844 +                if (val != intCompact) {
 14.3845 +                    print("audit", this);
 14.3846 +                    throw new AssertionError("Inconsistent state, intCompact=" +
 14.3847 +                                             intCompact + "\t intVal=" + val);
 14.3848 +                }
 14.3849 +            }
 14.3850 +            // Check precision
 14.3851 +            if (precision > 0 && precision != longDigitLength(intCompact)) {
 14.3852 +                print("audit", this);
 14.3853 +                throw new AssertionError("precision mismatch");
 14.3854 +            }
 14.3855 +        }
 14.3856 +        return this;
 14.3857 +    }
 14.3858 +}
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/rt/emul/compact/src/main/java/java/math/BigInteger.java	Sat Sep 07 13:55:09 2013 +0200
    15.3 @@ -0,0 +1,3186 @@
    15.4 +/*
    15.5 + * Copyright (c) 1996, 2007, 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 +/*
   15.30 + * Portions Copyright (c) 1995  Colin Plumb.  All rights reserved.
   15.31 + */
   15.32 +
   15.33 +package java.math;
   15.34 +
   15.35 +import java.util.Random;
   15.36 +import java.io.*;
   15.37 +
   15.38 +/**
   15.39 + * Immutable arbitrary-precision integers.  All operations behave as if
   15.40 + * BigIntegers were represented in two's-complement notation (like Java's
   15.41 + * primitive integer types).  BigInteger provides analogues to all of Java's
   15.42 + * primitive integer operators, and all relevant methods from java.lang.Math.
   15.43 + * Additionally, BigInteger provides operations for modular arithmetic, GCD
   15.44 + * calculation, primality testing, prime generation, bit manipulation,
   15.45 + * and a few other miscellaneous operations.
   15.46 + *
   15.47 + * <p>Semantics of arithmetic operations exactly mimic those of Java's integer
   15.48 + * arithmetic operators, as defined in <i>The Java Language Specification</i>.
   15.49 + * For example, division by zero throws an {@code ArithmeticException}, and
   15.50 + * division of a negative by a positive yields a negative (or zero) remainder.
   15.51 + * All of the details in the Spec concerning overflow are ignored, as
   15.52 + * BigIntegers are made as large as necessary to accommodate the results of an
   15.53 + * operation.
   15.54 + *
   15.55 + * <p>Semantics of shift operations extend those of Java's shift operators
   15.56 + * to allow for negative shift distances.  A right-shift with a negative
   15.57 + * shift distance results in a left shift, and vice-versa.  The unsigned
   15.58 + * right shift operator ({@code >>>}) is omitted, as this operation makes
   15.59 + * little sense in combination with the "infinite word size" abstraction
   15.60 + * provided by this class.
   15.61 + *
   15.62 + * <p>Semantics of bitwise logical operations exactly mimic those of Java's
   15.63 + * bitwise integer operators.  The binary operators ({@code and},
   15.64 + * {@code or}, {@code xor}) implicitly perform sign extension on the shorter
   15.65 + * of the two operands prior to performing the operation.
   15.66 + *
   15.67 + * <p>Comparison operations perform signed integer comparisons, analogous to
   15.68 + * those performed by Java's relational and equality operators.
   15.69 + *
   15.70 + * <p>Modular arithmetic operations are provided to compute residues, perform
   15.71 + * exponentiation, and compute multiplicative inverses.  These methods always
   15.72 + * return a non-negative result, between {@code 0} and {@code (modulus - 1)},
   15.73 + * inclusive.
   15.74 + *
   15.75 + * <p>Bit operations operate on a single bit of the two's-complement
   15.76 + * representation of their operand.  If necessary, the operand is sign-
   15.77 + * extended so that it contains the designated bit.  None of the single-bit
   15.78 + * operations can produce a BigInteger with a different sign from the
   15.79 + * BigInteger being operated on, as they affect only a single bit, and the
   15.80 + * "infinite word size" abstraction provided by this class ensures that there
   15.81 + * are infinitely many "virtual sign bits" preceding each BigInteger.
   15.82 + *
   15.83 + * <p>For the sake of brevity and clarity, pseudo-code is used throughout the
   15.84 + * descriptions of BigInteger methods.  The pseudo-code expression
   15.85 + * {@code (i + j)} is shorthand for "a BigInteger whose value is
   15.86 + * that of the BigInteger {@code i} plus that of the BigInteger {@code j}."
   15.87 + * The pseudo-code expression {@code (i == j)} is shorthand for
   15.88 + * "{@code true} if and only if the BigInteger {@code i} represents the same
   15.89 + * value as the BigInteger {@code j}."  Other pseudo-code expressions are
   15.90 + * interpreted similarly.
   15.91 + *
   15.92 + * <p>All methods and constructors in this class throw
   15.93 + * {@code NullPointerException} when passed
   15.94 + * a null object reference for any input parameter.
   15.95 + *
   15.96 + * @see     BigDecimal
   15.97 + * @author  Josh Bloch
   15.98 + * @author  Michael McCloskey
   15.99 + * @since JDK1.1
  15.100 + */
  15.101 +
  15.102 +public class BigInteger extends Number implements Comparable<BigInteger> {
  15.103 +    /**
  15.104 +     * The signum of this BigInteger: -1 for negative, 0 for zero, or
  15.105 +     * 1 for positive.  Note that the BigInteger zero <i>must</i> have
  15.106 +     * a signum of 0.  This is necessary to ensures that there is exactly one
  15.107 +     * representation for each BigInteger value.
  15.108 +     *
  15.109 +     * @serial
  15.110 +     */
  15.111 +    final int signum;
  15.112 +
  15.113 +    /**
  15.114 +     * The magnitude of this BigInteger, in <i>big-endian</i> order: the
  15.115 +     * zeroth element of this array is the most-significant int of the
  15.116 +     * magnitude.  The magnitude must be "minimal" in that the most-significant
  15.117 +     * int ({@code mag[0]}) must be non-zero.  This is necessary to
  15.118 +     * ensure that there is exactly one representation for each BigInteger
  15.119 +     * value.  Note that this implies that the BigInteger zero has a
  15.120 +     * zero-length mag array.
  15.121 +     */
  15.122 +    final int[] mag;
  15.123 +
  15.124 +    // These "redundant fields" are initialized with recognizable nonsense
  15.125 +    // values, and cached the first time they are needed (or never, if they
  15.126 +    // aren't needed).
  15.127 +
  15.128 +     /**
  15.129 +     * One plus the bitCount of this BigInteger. Zeros means unitialized.
  15.130 +     *
  15.131 +     * @serial
  15.132 +     * @see #bitCount
  15.133 +     * @deprecated Deprecated since logical value is offset from stored
  15.134 +     * value and correction factor is applied in accessor method.
  15.135 +     */
  15.136 +    @Deprecated
  15.137 +    private int bitCount;
  15.138 +
  15.139 +    /**
  15.140 +     * One plus the bitLength of this BigInteger. Zeros means unitialized.
  15.141 +     * (either value is acceptable).
  15.142 +     *
  15.143 +     * @serial
  15.144 +     * @see #bitLength()
  15.145 +     * @deprecated Deprecated since logical value is offset from stored
  15.146 +     * value and correction factor is applied in accessor method.
  15.147 +     */
  15.148 +    @Deprecated
  15.149 +    private int bitLength;
  15.150 +
  15.151 +    /**
  15.152 +     * Two plus the lowest set bit of this BigInteger, as returned by
  15.153 +     * getLowestSetBit().
  15.154 +     *
  15.155 +     * @serial
  15.156 +     * @see #getLowestSetBit
  15.157 +     * @deprecated Deprecated since logical value is offset from stored
  15.158 +     * value and correction factor is applied in accessor method.
  15.159 +     */
  15.160 +    @Deprecated
  15.161 +    private int lowestSetBit;
  15.162 +
  15.163 +    /**
  15.164 +     * Two plus the index of the lowest-order int in the magnitude of this
  15.165 +     * BigInteger that contains a nonzero int, or -2 (either value is acceptable).
  15.166 +     * The least significant int has int-number 0, the next int in order of
  15.167 +     * increasing significance has int-number 1, and so forth.
  15.168 +     * @deprecated Deprecated since logical value is offset from stored
  15.169 +     * value and correction factor is applied in accessor method.
  15.170 +     */
  15.171 +    @Deprecated
  15.172 +    private int firstNonzeroIntNum;
  15.173 +
  15.174 +    /**
  15.175 +     * This mask is used to obtain the value of an int as if it were unsigned.
  15.176 +     */
  15.177 +    final static long LONG_MASK = 0xffffffffL;
  15.178 +
  15.179 +    //Constructors
  15.180 +
  15.181 +    /**
  15.182 +     * Translates a byte array containing the two's-complement binary
  15.183 +     * representation of a BigInteger into a BigInteger.  The input array is
  15.184 +     * assumed to be in <i>big-endian</i> byte-order: the most significant
  15.185 +     * byte is in the zeroth element.
  15.186 +     *
  15.187 +     * @param  val big-endian two's-complement binary representation of
  15.188 +     *         BigInteger.
  15.189 +     * @throws NumberFormatException {@code val} is zero bytes long.
  15.190 +     */
  15.191 +    public BigInteger(byte[] val) {
  15.192 +        if (val.length == 0)
  15.193 +            throw new NumberFormatException("Zero length BigInteger");
  15.194 +
  15.195 +        if (val[0] < 0) {
  15.196 +            mag = makePositive(val);
  15.197 +            signum = -1;
  15.198 +        } else {
  15.199 +            mag = stripLeadingZeroBytes(val);
  15.200 +            signum = (mag.length == 0 ? 0 : 1);
  15.201 +        }
  15.202 +    }
  15.203 +
  15.204 +    /**
  15.205 +     * This private constructor translates an int array containing the
  15.206 +     * two's-complement binary representation of a BigInteger into a
  15.207 +     * BigInteger. The input array is assumed to be in <i>big-endian</i>
  15.208 +     * int-order: the most significant int is in the zeroth element.
  15.209 +     */
  15.210 +    private BigInteger(int[] val) {
  15.211 +        if (val.length == 0)
  15.212 +            throw new NumberFormatException("Zero length BigInteger");
  15.213 +
  15.214 +        if (val[0] < 0) {
  15.215 +            mag = makePositive(val);
  15.216 +            signum = -1;
  15.217 +        } else {
  15.218 +            mag = trustedStripLeadingZeroInts(val);
  15.219 +            signum = (mag.length == 0 ? 0 : 1);
  15.220 +        }
  15.221 +    }
  15.222 +
  15.223 +    /**
  15.224 +     * Translates the sign-magnitude representation of a BigInteger into a
  15.225 +     * BigInteger.  The sign is represented as an integer signum value: -1 for
  15.226 +     * negative, 0 for zero, or 1 for positive.  The magnitude is a byte array
  15.227 +     * in <i>big-endian</i> byte-order: the most significant byte is in the
  15.228 +     * zeroth element.  A zero-length magnitude array is permissible, and will
  15.229 +     * result in a BigInteger value of 0, whether signum is -1, 0 or 1.
  15.230 +     *
  15.231 +     * @param  signum signum of the number (-1 for negative, 0 for zero, 1
  15.232 +     *         for positive).
  15.233 +     * @param  magnitude big-endian binary representation of the magnitude of
  15.234 +     *         the number.
  15.235 +     * @throws NumberFormatException {@code signum} is not one of the three
  15.236 +     *         legal values (-1, 0, and 1), or {@code signum} is 0 and
  15.237 +     *         {@code magnitude} contains one or more non-zero bytes.
  15.238 +     */
  15.239 +    public BigInteger(int signum, byte[] magnitude) {
  15.240 +        this.mag = stripLeadingZeroBytes(magnitude);
  15.241 +
  15.242 +        if (signum < -1 || signum > 1)
  15.243 +            throw(new NumberFormatException("Invalid signum value"));
  15.244 +
  15.245 +        if (this.mag.length==0) {
  15.246 +            this.signum = 0;
  15.247 +        } else {
  15.248 +            if (signum == 0)
  15.249 +                throw(new NumberFormatException("signum-magnitude mismatch"));
  15.250 +            this.signum = signum;
  15.251 +        }
  15.252 +    }
  15.253 +
  15.254 +    /**
  15.255 +     * A constructor for internal use that translates the sign-magnitude
  15.256 +     * representation of a BigInteger into a BigInteger. It checks the
  15.257 +     * arguments and copies the magnitude so this constructor would be
  15.258 +     * safe for external use.
  15.259 +     */
  15.260 +    private BigInteger(int signum, int[] magnitude) {
  15.261 +        this.mag = stripLeadingZeroInts(magnitude);
  15.262 +
  15.263 +        if (signum < -1 || signum > 1)
  15.264 +            throw(new NumberFormatException("Invalid signum value"));
  15.265 +
  15.266 +        if (this.mag.length==0) {
  15.267 +            this.signum = 0;
  15.268 +        } else {
  15.269 +            if (signum == 0)
  15.270 +                throw(new NumberFormatException("signum-magnitude mismatch"));
  15.271 +            this.signum = signum;
  15.272 +        }
  15.273 +    }
  15.274 +
  15.275 +    /**
  15.276 +     * Translates the String representation of a BigInteger in the
  15.277 +     * specified radix into a BigInteger.  The String representation
  15.278 +     * consists of an optional minus or plus sign followed by a
  15.279 +     * sequence of one or more digits in the specified radix.  The
  15.280 +     * character-to-digit mapping is provided by {@code
  15.281 +     * Character.digit}.  The String may not contain any extraneous
  15.282 +     * characters (whitespace, for example).
  15.283 +     *
  15.284 +     * @param val String representation of BigInteger.
  15.285 +     * @param radix radix to be used in interpreting {@code val}.
  15.286 +     * @throws NumberFormatException {@code val} is not a valid representation
  15.287 +     *         of a BigInteger in the specified radix, or {@code radix} is
  15.288 +     *         outside the range from {@link Character#MIN_RADIX} to
  15.289 +     *         {@link Character#MAX_RADIX}, inclusive.
  15.290 +     * @see    Character#digit
  15.291 +     */
  15.292 +    public BigInteger(String val, int radix) {
  15.293 +        int cursor = 0, numDigits;
  15.294 +        final int len = val.length();
  15.295 +
  15.296 +        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
  15.297 +            throw new NumberFormatException("Radix out of range");
  15.298 +        if (len == 0)
  15.299 +            throw new NumberFormatException("Zero length BigInteger");
  15.300 +
  15.301 +        // Check for at most one leading sign
  15.302 +        int sign = 1;
  15.303 +        int index1 = val.lastIndexOf('-');
  15.304 +        int index2 = val.lastIndexOf('+');
  15.305 +        if ((index1 + index2) <= -1) {
  15.306 +            // No leading sign character or at most one leading sign character
  15.307 +            if (index1 == 0 || index2 == 0) {
  15.308 +                cursor = 1;
  15.309 +                if (len == 1)
  15.310 +                    throw new NumberFormatException("Zero length BigInteger");
  15.311 +            }
  15.312 +            if (index1 == 0)
  15.313 +                sign = -1;
  15.314 +        } else
  15.315 +            throw new NumberFormatException("Illegal embedded sign character");
  15.316 +
  15.317 +        // Skip leading zeros and compute number of digits in magnitude
  15.318 +        while (cursor < len &&
  15.319 +               Character.digit(val.charAt(cursor), radix) == 0)
  15.320 +            cursor++;
  15.321 +        if (cursor == len) {
  15.322 +            signum = 0;
  15.323 +            mag = ZERO.mag;
  15.324 +            return;
  15.325 +        }
  15.326 +
  15.327 +        numDigits = len - cursor;
  15.328 +        signum = sign;
  15.329 +
  15.330 +        // Pre-allocate array of expected size. May be too large but can
  15.331 +        // never be too small. Typically exact.
  15.332 +        int numBits = (int)(((numDigits * bitsPerDigit[radix]) >>> 10) + 1);
  15.333 +        int numWords = (numBits + 31) >>> 5;
  15.334 +        int[] magnitude = new int[numWords];
  15.335 +
  15.336 +        // Process first (potentially short) digit group
  15.337 +        int firstGroupLen = numDigits % digitsPerInt[radix];
  15.338 +        if (firstGroupLen == 0)
  15.339 +            firstGroupLen = digitsPerInt[radix];
  15.340 +        String group = val.substring(cursor, cursor += firstGroupLen);
  15.341 +        magnitude[numWords - 1] = Integer.parseInt(group, radix);
  15.342 +        if (magnitude[numWords - 1] < 0)
  15.343 +            throw new NumberFormatException("Illegal digit");
  15.344 +
  15.345 +        // Process remaining digit groups
  15.346 +        int superRadix = intRadix[radix];
  15.347 +        int groupVal = 0;
  15.348 +        while (cursor < len) {
  15.349 +            group = val.substring(cursor, cursor += digitsPerInt[radix]);
  15.350 +            groupVal = Integer.parseInt(group, radix);
  15.351 +            if (groupVal < 0)
  15.352 +                throw new NumberFormatException("Illegal digit");
  15.353 +            destructiveMulAdd(magnitude, superRadix, groupVal);
  15.354 +        }
  15.355 +        // Required for cases where the array was overallocated.
  15.356 +        mag = trustedStripLeadingZeroInts(magnitude);
  15.357 +    }
  15.358 +
  15.359 +    // Constructs a new BigInteger using a char array with radix=10
  15.360 +    BigInteger(char[] val) {
  15.361 +        int cursor = 0, numDigits;
  15.362 +        int len = val.length;
  15.363 +
  15.364 +        // Check for leading minus sign
  15.365 +        int sign = 1;
  15.366 +        if (val[0] == '-') {
  15.367 +            if (len == 1)
  15.368 +                throw new NumberFormatException("Zero length BigInteger");
  15.369 +            sign = -1;
  15.370 +            cursor = 1;
  15.371 +        } else if (val[0] == '+') {
  15.372 +            if (len == 1)
  15.373 +                throw new NumberFormatException("Zero length BigInteger");
  15.374 +            cursor = 1;
  15.375 +        }
  15.376 +
  15.377 +        // Skip leading zeros and compute number of digits in magnitude
  15.378 +        while (cursor < len && Character.digit(val[cursor], 10) == 0)
  15.379 +            cursor++;
  15.380 +        if (cursor == len) {
  15.381 +            signum = 0;
  15.382 +            mag = ZERO.mag;
  15.383 +            return;
  15.384 +        }
  15.385 +
  15.386 +        numDigits = len - cursor;
  15.387 +        signum = sign;
  15.388 +
  15.389 +        // Pre-allocate array of expected size
  15.390 +        int numWords;
  15.391 +        if (len < 10) {
  15.392 +            numWords = 1;
  15.393 +        } else {
  15.394 +            int numBits = (int)(((numDigits * bitsPerDigit[10]) >>> 10) + 1);
  15.395 +            numWords = (numBits + 31) >>> 5;
  15.396 +        }
  15.397 +        int[] magnitude = new int[numWords];
  15.398 +
  15.399 +        // Process first (potentially short) digit group
  15.400 +        int firstGroupLen = numDigits % digitsPerInt[10];
  15.401 +        if (firstGroupLen == 0)
  15.402 +            firstGroupLen = digitsPerInt[10];
  15.403 +        magnitude[numWords - 1] = parseInt(val, cursor,  cursor += firstGroupLen);
  15.404 +
  15.405 +        // Process remaining digit groups
  15.406 +        while (cursor < len) {
  15.407 +            int groupVal = parseInt(val, cursor, cursor += digitsPerInt[10]);
  15.408 +            destructiveMulAdd(magnitude, intRadix[10], groupVal);
  15.409 +        }
  15.410 +        mag = trustedStripLeadingZeroInts(magnitude);
  15.411 +    }
  15.412 +
  15.413 +    // Create an integer with the digits between the two indexes
  15.414 +    // Assumes start < end. The result may be negative, but it
  15.415 +    // is to be treated as an unsigned value.
  15.416 +    private int parseInt(char[] source, int start, int end) {
  15.417 +        int result = Character.digit(source[start++], 10);
  15.418 +        if (result == -1)
  15.419 +            throw new NumberFormatException(new String(source));
  15.420 +
  15.421 +        for (int index = start; index<end; index++) {
  15.422 +            int nextVal = Character.digit(source[index], 10);
  15.423 +            if (nextVal == -1)
  15.424 +                throw new NumberFormatException(new String(source));
  15.425 +            result = 10*result + nextVal;
  15.426 +        }
  15.427 +
  15.428 +        return result;
  15.429 +    }
  15.430 +
  15.431 +    // bitsPerDigit in the given radix times 1024
  15.432 +    // Rounded up to avoid underallocation.
  15.433 +    private static long bitsPerDigit[] = { 0, 0,
  15.434 +        1024, 1624, 2048, 2378, 2648, 2875, 3072, 3247, 3402, 3543, 3672,
  15.435 +        3790, 3899, 4001, 4096, 4186, 4271, 4350, 4426, 4498, 4567, 4633,
  15.436 +        4696, 4756, 4814, 4870, 4923, 4975, 5025, 5074, 5120, 5166, 5210,
  15.437 +                                           5253, 5295};
  15.438 +
  15.439 +    // Multiply x array times word y in place, and add word z
  15.440 +    private static void destructiveMulAdd(int[] x, int y, int z) {
  15.441 +        // Perform the multiplication word by word
  15.442 +        long ylong = y & LONG_MASK;
  15.443 +        long zlong = z & LONG_MASK;
  15.444 +        int len = x.length;
  15.445 +
  15.446 +        long product = 0;
  15.447 +        long carry = 0;
  15.448 +        for (int i = len-1; i >= 0; i--) {
  15.449 +            product = ylong * (x[i] & LONG_MASK) + carry;
  15.450 +            x[i] = (int)product;
  15.451 +            carry = product >>> 32;
  15.452 +        }
  15.453 +
  15.454 +        // Perform the addition
  15.455 +        long sum = (x[len-1] & LONG_MASK) + zlong;
  15.456 +        x[len-1] = (int)sum;
  15.457 +        carry = sum >>> 32;
  15.458 +        for (int i = len-2; i >= 0; i--) {
  15.459 +            sum = (x[i] & LONG_MASK) + carry;
  15.460 +            x[i] = (int)sum;
  15.461 +            carry = sum >>> 32;
  15.462 +        }
  15.463 +    }
  15.464 +
  15.465 +    /**
  15.466 +     * Translates the decimal String representation of a BigInteger into a
  15.467 +     * BigInteger.  The String representation consists of an optional minus
  15.468 +     * sign followed by a sequence of one or more decimal digits.  The
  15.469 +     * character-to-digit mapping is provided by {@code Character.digit}.
  15.470 +     * The String may not contain any extraneous characters (whitespace, for
  15.471 +     * example).
  15.472 +     *
  15.473 +     * @param val decimal String representation of BigInteger.
  15.474 +     * @throws NumberFormatException {@code val} is not a valid representation
  15.475 +     *         of a BigInteger.
  15.476 +     * @see    Character#digit
  15.477 +     */
  15.478 +    public BigInteger(String val) {
  15.479 +        this(val, 10);
  15.480 +    }
  15.481 +
  15.482 +    /**
  15.483 +     * Constructs a randomly generated BigInteger, uniformly distributed over
  15.484 +     * the range 0 to (2<sup>{@code numBits}</sup> - 1), inclusive.
  15.485 +     * The uniformity of the distribution assumes that a fair source of random
  15.486 +     * bits is provided in {@code rnd}.  Note that this constructor always
  15.487 +     * constructs a non-negative BigInteger.
  15.488 +     *
  15.489 +     * @param  numBits maximum bitLength of the new BigInteger.
  15.490 +     * @param  rnd source of randomness to be used in computing the new
  15.491 +     *         BigInteger.
  15.492 +     * @throws IllegalArgumentException {@code numBits} is negative.
  15.493 +     * @see #bitLength()
  15.494 +     */
  15.495 +    public BigInteger(int numBits, Random rnd) {
  15.496 +        this(1, randomBits(numBits, rnd));
  15.497 +    }
  15.498 +
  15.499 +    private static byte[] randomBits(int numBits, Random rnd) {
  15.500 +        if (numBits < 0)
  15.501 +            throw new IllegalArgumentException("numBits must be non-negative");
  15.502 +        int numBytes = (int)(((long)numBits+7)/8); // avoid overflow
  15.503 +        byte[] randomBits = new byte[numBytes];
  15.504 +
  15.505 +        // Generate random bytes and mask out any excess bits
  15.506 +        if (numBytes > 0) {
  15.507 +            rnd.nextBytes(randomBits);
  15.508 +            int excessBits = 8*numBytes - numBits;
  15.509 +            randomBits[0] &= (1 << (8-excessBits)) - 1;
  15.510 +        }
  15.511 +        return randomBits;
  15.512 +    }
  15.513 +
  15.514 +    /**
  15.515 +     * Constructs a randomly generated positive BigInteger that is probably
  15.516 +     * prime, with the specified bitLength.
  15.517 +     *
  15.518 +     * <p>It is recommended that the {@link #probablePrime probablePrime}
  15.519 +     * method be used in preference to this constructor unless there
  15.520 +     * is a compelling need to specify a certainty.
  15.521 +     *
  15.522 +     * @param  bitLength bitLength of the returned BigInteger.
  15.523 +     * @param  certainty a measure of the uncertainty that the caller is
  15.524 +     *         willing to tolerate.  The probability that the new BigInteger
  15.525 +     *         represents a prime number will exceed
  15.526 +     *         (1 - 1/2<sup>{@code certainty}</sup>).  The execution time of
  15.527 +     *         this constructor is proportional to the value of this parameter.
  15.528 +     * @param  rnd source of random bits used to select candidates to be
  15.529 +     *         tested for primality.
  15.530 +     * @throws ArithmeticException {@code bitLength < 2}.
  15.531 +     * @see    #bitLength()
  15.532 +     */
  15.533 +    public BigInteger(int bitLength, int certainty, Random rnd) {
  15.534 +        BigInteger prime;
  15.535 +
  15.536 +        if (bitLength < 2)
  15.537 +            throw new ArithmeticException("bitLength < 2");
  15.538 +        // The cutoff of 95 was chosen empirically for best performance
  15.539 +        prime = (bitLength < 95 ? smallPrime(bitLength, certainty, rnd)
  15.540 +                                : largePrime(bitLength, certainty, rnd));
  15.541 +        signum = 1;
  15.542 +        mag = prime.mag;
  15.543 +    }
  15.544 +
  15.545 +    // Minimum size in bits that the requested prime number has
  15.546 +    // before we use the large prime number generating algorithms
  15.547 +    private static final int SMALL_PRIME_THRESHOLD = 95;
  15.548 +
  15.549 +    // Certainty required to meet the spec of probablePrime
  15.550 +    private static final int DEFAULT_PRIME_CERTAINTY = 100;
  15.551 +
  15.552 +    /**
  15.553 +     * Returns a positive BigInteger that is probably prime, with the
  15.554 +     * specified bitLength. The probability that a BigInteger returned
  15.555 +     * by this method is composite does not exceed 2<sup>-100</sup>.
  15.556 +     *
  15.557 +     * @param  bitLength bitLength of the returned BigInteger.
  15.558 +     * @param  rnd source of random bits used to select candidates to be
  15.559 +     *         tested for primality.
  15.560 +     * @return a BigInteger of {@code bitLength} bits that is probably prime
  15.561 +     * @throws ArithmeticException {@code bitLength < 2}.
  15.562 +     * @see    #bitLength()
  15.563 +     * @since 1.4
  15.564 +     */
  15.565 +    public static BigInteger probablePrime(int bitLength, Random rnd) {
  15.566 +        if (bitLength < 2)
  15.567 +            throw new ArithmeticException("bitLength < 2");
  15.568 +
  15.569 +        // The cutoff of 95 was chosen empirically for best performance
  15.570 +        return (bitLength < SMALL_PRIME_THRESHOLD ?
  15.571 +                smallPrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd) :
  15.572 +                largePrime(bitLength, DEFAULT_PRIME_CERTAINTY, rnd));
  15.573 +    }
  15.574 +
  15.575 +    /**
  15.576 +     * Find a random number of the specified bitLength that is probably prime.
  15.577 +     * This method is used for smaller primes, its performance degrades on
  15.578 +     * larger bitlengths.
  15.579 +     *
  15.580 +     * This method assumes bitLength > 1.
  15.581 +     */
  15.582 +    private static BigInteger smallPrime(int bitLength, int certainty, Random rnd) {
  15.583 +        int magLen = (bitLength + 31) >>> 5;
  15.584 +        int temp[] = new int[magLen];
  15.585 +        int highBit = 1 << ((bitLength+31) & 0x1f);  // High bit of high int
  15.586 +        int highMask = (highBit << 1) - 1;  // Bits to keep in high int
  15.587 +
  15.588 +        while(true) {
  15.589 +            // Construct a candidate
  15.590 +            for (int i=0; i<magLen; i++)
  15.591 +                temp[i] = rnd.nextInt();
  15.592 +            temp[0] = (temp[0] & highMask) | highBit;  // Ensure exact length
  15.593 +            if (bitLength > 2)
  15.594 +                temp[magLen-1] |= 1;  // Make odd if bitlen > 2
  15.595 +
  15.596 +            BigInteger p = new BigInteger(temp, 1);
  15.597 +
  15.598 +            // Do cheap "pre-test" if applicable
  15.599 +            if (bitLength > 6) {
  15.600 +                long r = p.remainder(SMALL_PRIME_PRODUCT).longValue();
  15.601 +                if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) ||
  15.602 +                    (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||
  15.603 +                    (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0))
  15.604 +                    continue; // Candidate is composite; try another
  15.605 +            }
  15.606 +
  15.607 +            // All candidates of bitLength 2 and 3 are prime by this point
  15.608 +            if (bitLength < 4)
  15.609 +                return p;
  15.610 +
  15.611 +            // Do expensive test if we survive pre-test (or it's inapplicable)
  15.612 +            if (p.primeToCertainty(certainty, rnd))
  15.613 +                return p;
  15.614 +        }
  15.615 +    }
  15.616 +
  15.617 +    private static final BigInteger SMALL_PRIME_PRODUCT
  15.618 +                       = valueOf(3L*5*7*11*13*17*19*23*29*31*37*41);
  15.619 +
  15.620 +    /**
  15.621 +     * Find a random number of the specified bitLength that is probably prime.
  15.622 +     * This method is more appropriate for larger bitlengths since it uses
  15.623 +     * a sieve to eliminate most composites before using a more expensive
  15.624 +     * test.
  15.625 +     */
  15.626 +    private static BigInteger largePrime(int bitLength, int certainty, Random rnd) {
  15.627 +        BigInteger p;
  15.628 +        p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
  15.629 +        p.mag[p.mag.length-1] &= 0xfffffffe;
  15.630 +
  15.631 +        // Use a sieve length likely to contain the next prime number
  15.632 +        int searchLen = (bitLength / 20) * 64;
  15.633 +        BitSieve searchSieve = new BitSieve(p, searchLen);
  15.634 +        BigInteger candidate = searchSieve.retrieve(p, certainty, rnd);
  15.635 +
  15.636 +        while ((candidate == null) || (candidate.bitLength() != bitLength)) {
  15.637 +            p = p.add(BigInteger.valueOf(2*searchLen));
  15.638 +            if (p.bitLength() != bitLength)
  15.639 +                p = new BigInteger(bitLength, rnd).setBit(bitLength-1);
  15.640 +            p.mag[p.mag.length-1] &= 0xfffffffe;
  15.641 +            searchSieve = new BitSieve(p, searchLen);
  15.642 +            candidate = searchSieve.retrieve(p, certainty, rnd);
  15.643 +        }
  15.644 +        return candidate;
  15.645 +    }
  15.646 +
  15.647 +   /**
  15.648 +    * Returns the first integer greater than this {@code BigInteger} that
  15.649 +    * is probably prime.  The probability that the number returned by this
  15.650 +    * method is composite does not exceed 2<sup>-100</sup>. This method will
  15.651 +    * never skip over a prime when searching: if it returns {@code p}, there
  15.652 +    * is no prime {@code q} such that {@code this < q < p}.
  15.653 +    *
  15.654 +    * @return the first integer greater than this {@code BigInteger} that
  15.655 +    *         is probably prime.
  15.656 +    * @throws ArithmeticException {@code this < 0}.
  15.657 +    * @since 1.5
  15.658 +    */
  15.659 +    public BigInteger nextProbablePrime() {
  15.660 +        if (this.signum < 0)
  15.661 +            throw new ArithmeticException("start < 0: " + this);
  15.662 +
  15.663 +        // Handle trivial cases
  15.664 +        if ((this.signum == 0) || this.equals(ONE))
  15.665 +            return TWO;
  15.666 +
  15.667 +        BigInteger result = this.add(ONE);
  15.668 +
  15.669 +        // Fastpath for small numbers
  15.670 +        if (result.bitLength() < SMALL_PRIME_THRESHOLD) {
  15.671 +
  15.672 +            // Ensure an odd number
  15.673 +            if (!result.testBit(0))
  15.674 +                result = result.add(ONE);
  15.675 +
  15.676 +            while(true) {
  15.677 +                // Do cheap "pre-test" if applicable
  15.678 +                if (result.bitLength() > 6) {
  15.679 +                    long r = result.remainder(SMALL_PRIME_PRODUCT).longValue();
  15.680 +                    if ((r%3==0)  || (r%5==0)  || (r%7==0)  || (r%11==0) ||
  15.681 +                        (r%13==0) || (r%17==0) || (r%19==0) || (r%23==0) ||
  15.682 +                        (r%29==0) || (r%31==0) || (r%37==0) || (r%41==0)) {
  15.683 +                        result = result.add(TWO);
  15.684 +                        continue; // Candidate is composite; try another
  15.685 +                    }
  15.686 +                }
  15.687 +
  15.688 +                // All candidates of bitLength 2 and 3 are prime by this point
  15.689 +                if (result.bitLength() < 4)
  15.690 +                    return result;
  15.691 +
  15.692 +                // The expensive test
  15.693 +                if (result.primeToCertainty(DEFAULT_PRIME_CERTAINTY, null))
  15.694 +                    return result;
  15.695 +
  15.696 +                result = result.add(TWO);
  15.697 +            }
  15.698 +        }
  15.699 +
  15.700 +        // Start at previous even number
  15.701 +        if (result.testBit(0))
  15.702 +            result = result.subtract(ONE);
  15.703 +
  15.704 +        // Looking for the next large prime
  15.705 +        int searchLen = (result.bitLength() / 20) * 64;
  15.706 +
  15.707 +        while(true) {
  15.708 +           BitSieve searchSieve = new BitSieve(result, searchLen);
  15.709 +           BigInteger candidate = searchSieve.retrieve(result,
  15.710 +                                                 DEFAULT_PRIME_CERTAINTY, null);
  15.711 +           if (candidate != null)
  15.712 +               return candidate;
  15.713 +           result = result.add(BigInteger.valueOf(2 * searchLen));
  15.714 +        }
  15.715 +    }
  15.716 +
  15.717 +    /**
  15.718 +     * Returns {@code true} if this BigInteger is probably prime,
  15.719 +     * {@code false} if it's definitely composite.
  15.720 +     *
  15.721 +     * This method assumes bitLength > 2.
  15.722 +     *
  15.723 +     * @param  certainty a measure of the uncertainty that the caller is
  15.724 +     *         willing to tolerate: if the call returns {@code true}
  15.725 +     *         the probability that this BigInteger is prime exceeds
  15.726 +     *         {@code (1 - 1/2<sup>certainty</sup>)}.  The execution time of
  15.727 +     *         this method is proportional to the value of this parameter.
  15.728 +     * @return {@code true} if this BigInteger is probably prime,
  15.729 +     *         {@code false} if it's definitely composite.
  15.730 +     */
  15.731 +    boolean primeToCertainty(int certainty, Random random) {
  15.732 +        int rounds = 0;
  15.733 +        int n = (Math.min(certainty, Integer.MAX_VALUE-1)+1)/2;
  15.734 +
  15.735 +        // The relationship between the certainty and the number of rounds
  15.736 +        // we perform is given in the draft standard ANSI X9.80, "PRIME
  15.737 +        // NUMBER GENERATION, PRIMALITY TESTING, AND PRIMALITY CERTIFICATES".
  15.738 +        int sizeInBits = this.bitLength();
  15.739 +        if (sizeInBits < 100) {
  15.740 +            rounds = 50;
  15.741 +            rounds = n < rounds ? n : rounds;
  15.742 +            return passesMillerRabin(rounds, random);
  15.743 +        }
  15.744 +
  15.745 +        if (sizeInBits < 256) {
  15.746 +            rounds = 27;
  15.747 +        } else if (sizeInBits < 512) {
  15.748 +            rounds = 15;
  15.749 +        } else if (sizeInBits < 768) {
  15.750 +            rounds = 8;
  15.751 +        } else if (sizeInBits < 1024) {
  15.752 +            rounds = 4;
  15.753 +        } else {
  15.754 +            rounds = 2;
  15.755 +        }
  15.756 +        rounds = n < rounds ? n : rounds;
  15.757 +
  15.758 +        return passesMillerRabin(rounds, random) && passesLucasLehmer();
  15.759 +    }
  15.760 +
  15.761 +    /**
  15.762 +     * Returns true iff this BigInteger is a Lucas-Lehmer probable prime.
  15.763 +     *
  15.764 +     * The following assumptions are made:
  15.765 +     * This BigInteger is a positive, odd number.
  15.766 +     */
  15.767 +    private boolean passesLucasLehmer() {
  15.768 +        BigInteger thisPlusOne = this.add(ONE);
  15.769 +
  15.770 +        // Step 1
  15.771 +        int d = 5;
  15.772 +        while (jacobiSymbol(d, this) != -1) {
  15.773 +            // 5, -7, 9, -11, ...
  15.774 +            d = (d<0) ? Math.abs(d)+2 : -(d+2);
  15.775 +        }
  15.776 +
  15.777 +        // Step 2
  15.778 +        BigInteger u = lucasLehmerSequence(d, thisPlusOne, this);
  15.779 +
  15.780 +        // Step 3
  15.781 +        return u.mod(this).equals(ZERO);
  15.782 +    }
  15.783 +
  15.784 +    /**
  15.785 +     * Computes Jacobi(p,n).
  15.786 +     * Assumes n positive, odd, n>=3.
  15.787 +     */
  15.788 +    private static int jacobiSymbol(int p, BigInteger n) {
  15.789 +        if (p == 0)
  15.790 +            return 0;
  15.791 +
  15.792 +        // Algorithm and comments adapted from Colin Plumb's C library.
  15.793 +        int j = 1;
  15.794 +        int u = n.mag[n.mag.length-1];
  15.795 +
  15.796 +        // Make p positive
  15.797 +        if (p < 0) {
  15.798 +            p = -p;
  15.799 +            int n8 = u & 7;
  15.800 +            if ((n8 == 3) || (n8 == 7))
  15.801 +                j = -j; // 3 (011) or 7 (111) mod 8
  15.802 +        }
  15.803 +
  15.804 +        // Get rid of factors of 2 in p
  15.805 +        while ((p & 3) == 0)
  15.806 +            p >>= 2;
  15.807 +        if ((p & 1) == 0) {
  15.808 +            p >>= 1;
  15.809 +            if (((u ^ (u>>1)) & 2) != 0)
  15.810 +                j = -j; // 3 (011) or 5 (101) mod 8
  15.811 +        }
  15.812 +        if (p == 1)
  15.813 +            return j;
  15.814 +        // Then, apply quadratic reciprocity
  15.815 +        if ((p & u & 2) != 0)   // p = u = 3 (mod 4)?
  15.816 +            j = -j;
  15.817 +        // And reduce u mod p
  15.818 +        u = n.mod(BigInteger.valueOf(p)).intValue();
  15.819 +
  15.820 +        // Now compute Jacobi(u,p), u < p
  15.821 +        while (u != 0) {
  15.822 +            while ((u & 3) == 0)
  15.823 +                u >>= 2;
  15.824 +            if ((u & 1) == 0) {
  15.825 +                u >>= 1;
  15.826 +                if (((p ^ (p>>1)) & 2) != 0)
  15.827 +                    j = -j;     // 3 (011) or 5 (101) mod 8
  15.828 +            }
  15.829 +            if (u == 1)
  15.830 +                return j;
  15.831 +            // Now both u and p are odd, so use quadratic reciprocity
  15.832 +            assert (u < p);
  15.833 +            int t = u; u = p; p = t;
  15.834 +            if ((u & p & 2) != 0) // u = p = 3 (mod 4)?
  15.835 +                j = -j;
  15.836 +            // Now u >= p, so it can be reduced
  15.837 +            u %= p;
  15.838 +        }
  15.839 +        return 0;
  15.840 +    }
  15.841 +
  15.842 +    private static BigInteger lucasLehmerSequence(int z, BigInteger k, BigInteger n) {
  15.843 +        BigInteger d = BigInteger.valueOf(z);
  15.844 +        BigInteger u = ONE; BigInteger u2;
  15.845 +        BigInteger v = ONE; BigInteger v2;
  15.846 +
  15.847 +        for (int i=k.bitLength()-2; i>=0; i--) {
  15.848 +            u2 = u.multiply(v).mod(n);
  15.849 +
  15.850 +            v2 = v.square().add(d.multiply(u.square())).mod(n);
  15.851 +            if (v2.testBit(0))
  15.852 +                v2 = v2.subtract(n);
  15.853 +
  15.854 +            v2 = v2.shiftRight(1);
  15.855 +
  15.856 +            u = u2; v = v2;
  15.857 +            if (k.testBit(i)) {
  15.858 +                u2 = u.add(v).mod(n);
  15.859 +                if (u2.testBit(0))
  15.860 +                    u2 = u2.subtract(n);
  15.861 +
  15.862 +                u2 = u2.shiftRight(1);
  15.863 +                v2 = v.add(d.multiply(u)).mod(n);
  15.864 +                if (v2.testBit(0))
  15.865 +                    v2 = v2.subtract(n);
  15.866 +                v2 = v2.shiftRight(1);
  15.867 +
  15.868 +                u = u2; v = v2;
  15.869 +            }
  15.870 +        }
  15.871 +        return u;
  15.872 +    }
  15.873 +
  15.874 +    private static volatile Random staticRandom;
  15.875 +
  15.876 +    private static Random getSecureRandom() {
  15.877 +        if (staticRandom == null) {
  15.878 +            staticRandom = new java.security.SecureRandom();
  15.879 +        }
  15.880 +        return staticRandom;
  15.881 +    }
  15.882 +
  15.883 +    /**
  15.884 +     * Returns true iff this BigInteger passes the specified number of
  15.885 +     * Miller-Rabin tests. This test is taken from the DSA spec (NIST FIPS
  15.886 +     * 186-2).
  15.887 +     *
  15.888 +     * The following assumptions are made:
  15.889 +     * This BigInteger is a positive, odd number greater than 2.
  15.890 +     * iterations<=50.
  15.891 +     */
  15.892 +    private boolean passesMillerRabin(int iterations, Random rnd) {
  15.893 +        // Find a and m such that m is odd and this == 1 + 2**a * m
  15.894 +        BigInteger thisMinusOne = this.subtract(ONE);
  15.895 +        BigInteger m = thisMinusOne;
  15.896 +        int a = m.getLowestSetBit();
  15.897 +        m = m.shiftRight(a);
  15.898 +
  15.899 +        // Do the tests
  15.900 +        if (rnd == null) {
  15.901 +            rnd = getSecureRandom();
  15.902 +        }
  15.903 +        for (int i=0; i<iterations; i++) {
  15.904 +            // Generate a uniform random on (1, this)
  15.905 +            BigInteger b;
  15.906 +            do {
  15.907 +                b = new BigInteger(this.bitLength(), rnd);
  15.908 +            } while (b.compareTo(ONE) <= 0 || b.compareTo(this) >= 0);
  15.909 +
  15.910 +            int j = 0;
  15.911 +            BigInteger z = b.modPow(m, this);
  15.912 +            while(!((j==0 && z.equals(ONE)) || z.equals(thisMinusOne))) {
  15.913 +                if (j>0 && z.equals(ONE) || ++j==a)
  15.914 +                    return false;
  15.915 +                z = z.modPow(TWO, this);
  15.916 +            }
  15.917 +        }
  15.918 +        return true;
  15.919 +    }
  15.920 +
  15.921 +    /**
  15.922 +     * This internal constructor differs from its public cousin
  15.923 +     * with the arguments reversed in two ways: it assumes that its
  15.924 +     * arguments are correct, and it doesn't copy the magnitude array.
  15.925 +     */
  15.926 +    BigInteger(int[] magnitude, int signum) {
  15.927 +        this.signum = (magnitude.length==0 ? 0 : signum);
  15.928 +        this.mag = magnitude;
  15.929 +    }
  15.930 +
  15.931 +    /**
  15.932 +     * This private constructor is for internal use and assumes that its
  15.933 +     * arguments are correct.
  15.934 +     */
  15.935 +    private BigInteger(byte[] magnitude, int signum) {
  15.936 +        this.signum = (magnitude.length==0 ? 0 : signum);
  15.937 +        this.mag = stripLeadingZeroBytes(magnitude);
  15.938 +    }
  15.939 +
  15.940 +    //Static Factory Methods
  15.941 +
  15.942 +    /**
  15.943 +     * Returns a BigInteger whose value is equal to that of the
  15.944 +     * specified {@code long}.  This "static factory method" is
  15.945 +     * provided in preference to a ({@code long}) constructor
  15.946 +     * because it allows for reuse of frequently used BigIntegers.
  15.947 +     *
  15.948 +     * @param  val value of the BigInteger to return.
  15.949 +     * @return a BigInteger with the specified value.
  15.950 +     */
  15.951 +    public static BigInteger valueOf(long val) {
  15.952 +        // If -MAX_CONSTANT < val < MAX_CONSTANT, return stashed constant
  15.953 +        if (val == 0)
  15.954 +            return ZERO;
  15.955 +        if (val > 0 && val <= MAX_CONSTANT)
  15.956 +            return posConst[(int) val];
  15.957 +        else if (val < 0 && val >= -MAX_CONSTANT)
  15.958 +            return negConst[(int) -val];
  15.959 +
  15.960 +        return new BigInteger(val);
  15.961 +    }
  15.962 +
  15.963 +    /**
  15.964 +     * Constructs a BigInteger with the specified value, which may not be zero.
  15.965 +     */
  15.966 +    private BigInteger(long val) {
  15.967 +        if (val < 0) {
  15.968 +            val = -val;
  15.969 +            signum = -1;
  15.970 +        } else {
  15.971 +            signum = 1;
  15.972 +        }
  15.973 +
  15.974 +        int highWord = (int)(val >>> 32);
  15.975 +        if (highWord==0) {
  15.976 +            mag = new int[1];
  15.977 +            mag[0] = (int)val;
  15.978 +        } else {
  15.979 +            mag = new int[2];
  15.980 +            mag[0] = highWord;
  15.981 +            mag[1] = (int)val;
  15.982 +        }
  15.983 +    }
  15.984 +
  15.985 +    /**
  15.986 +     * Returns a BigInteger with the given two's complement representation.
  15.987 +     * Assumes that the input array will not be modified (the returned
  15.988 +     * BigInteger will reference the input array if feasible).
  15.989 +     */
  15.990 +    private static BigInteger valueOf(int val[]) {
  15.991 +        return (val[0]>0 ? new BigInteger(val, 1) : new BigInteger(val));
  15.992 +    }
  15.993 +
  15.994 +    // Constants
  15.995 +
  15.996 +    /**
  15.997 +     * Initialize static constant array when class is loaded.
  15.998 +     */
  15.999 +    private final static int MAX_CONSTANT = 16;
 15.1000 +    private static BigInteger posConst[] = new BigInteger[MAX_CONSTANT+1];
 15.1001 +    private static BigInteger negConst[] = new BigInteger[MAX_CONSTANT+1];
 15.1002 +    static {
 15.1003 +        for (int i = 1; i <= MAX_CONSTANT; i++) {
 15.1004 +            int[] magnitude = new int[1];
 15.1005 +            magnitude[0] = i;
 15.1006 +            posConst[i] = new BigInteger(magnitude,  1);
 15.1007 +            negConst[i] = new BigInteger(magnitude, -1);
 15.1008 +        }
 15.1009 +    }
 15.1010 +
 15.1011 +    /**
 15.1012 +     * The BigInteger constant zero.
 15.1013 +     *
 15.1014 +     * @since   1.2
 15.1015 +     */
 15.1016 +    public static final BigInteger ZERO = new BigInteger(new int[0], 0);
 15.1017 +
 15.1018 +    /**
 15.1019 +     * The BigInteger constant one.
 15.1020 +     *
 15.1021 +     * @since   1.2
 15.1022 +     */
 15.1023 +    public static final BigInteger ONE = valueOf(1);
 15.1024 +
 15.1025 +    /**
 15.1026 +     * The BigInteger constant two.  (Not exported.)
 15.1027 +     */
 15.1028 +    private static final BigInteger TWO = valueOf(2);
 15.1029 +
 15.1030 +    /**
 15.1031 +     * The BigInteger constant ten.
 15.1032 +     *
 15.1033 +     * @since   1.5
 15.1034 +     */
 15.1035 +    public static final BigInteger TEN = valueOf(10);
 15.1036 +
 15.1037 +    // Arithmetic Operations
 15.1038 +
 15.1039 +    /**
 15.1040 +     * Returns a BigInteger whose value is {@code (this + val)}.
 15.1041 +     *
 15.1042 +     * @param  val value to be added to this BigInteger.
 15.1043 +     * @return {@code this + val}
 15.1044 +     */
 15.1045 +    public BigInteger add(BigInteger val) {
 15.1046 +        if (val.signum == 0)
 15.1047 +            return this;
 15.1048 +        if (signum == 0)
 15.1049 +            return val;
 15.1050 +        if (val.signum == signum)
 15.1051 +            return new BigInteger(add(mag, val.mag), signum);
 15.1052 +
 15.1053 +        int cmp = compareMagnitude(val);
 15.1054 +        if (cmp == 0)
 15.1055 +            return ZERO;
 15.1056 +        int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
 15.1057 +                           : subtract(val.mag, mag));
 15.1058 +        resultMag = trustedStripLeadingZeroInts(resultMag);
 15.1059 +
 15.1060 +        return new BigInteger(resultMag, cmp == signum ? 1 : -1);
 15.1061 +    }
 15.1062 +
 15.1063 +    /**
 15.1064 +     * Adds the contents of the int arrays x and y. This method allocates
 15.1065 +     * a new int array to hold the answer and returns a reference to that
 15.1066 +     * array.
 15.1067 +     */
 15.1068 +    private static int[] add(int[] x, int[] y) {
 15.1069 +        // If x is shorter, swap the two arrays
 15.1070 +        if (x.length < y.length) {
 15.1071 +            int[] tmp = x;
 15.1072 +            x = y;
 15.1073 +            y = tmp;
 15.1074 +        }
 15.1075 +
 15.1076 +        int xIndex = x.length;
 15.1077 +        int yIndex = y.length;
 15.1078 +        int result[] = new int[xIndex];
 15.1079 +        long sum = 0;
 15.1080 +
 15.1081 +        // Add common parts of both numbers
 15.1082 +        while(yIndex > 0) {
 15.1083 +            sum = (x[--xIndex] & LONG_MASK) +
 15.1084 +                  (y[--yIndex] & LONG_MASK) + (sum >>> 32);
 15.1085 +            result[xIndex] = (int)sum;
 15.1086 +        }
 15.1087 +
 15.1088 +        // Copy remainder of longer number while carry propagation is required
 15.1089 +        boolean carry = (sum >>> 32 != 0);
 15.1090 +        while (xIndex > 0 && carry)
 15.1091 +            carry = ((result[--xIndex] = x[xIndex] + 1) == 0);
 15.1092 +
 15.1093 +        // Copy remainder of longer number
 15.1094 +        while (xIndex > 0)
 15.1095 +            result[--xIndex] = x[xIndex];
 15.1096 +
 15.1097 +        // Grow result if necessary
 15.1098 +        if (carry) {
 15.1099 +            int bigger[] = new int[result.length + 1];
 15.1100 +            System.arraycopy(result, 0, bigger, 1, result.length);
 15.1101 +            bigger[0] = 0x01;
 15.1102 +            return bigger;
 15.1103 +        }
 15.1104 +        return result;
 15.1105 +    }
 15.1106 +
 15.1107 +    /**
 15.1108 +     * Returns a BigInteger whose value is {@code (this - val)}.
 15.1109 +     *
 15.1110 +     * @param  val value to be subtracted from this BigInteger.
 15.1111 +     * @return {@code this - val}
 15.1112 +     */
 15.1113 +    public BigInteger subtract(BigInteger val) {
 15.1114 +        if (val.signum == 0)
 15.1115 +            return this;
 15.1116 +        if (signum == 0)
 15.1117 +            return val.negate();
 15.1118 +        if (val.signum != signum)
 15.1119 +            return new BigInteger(add(mag, val.mag), signum);
 15.1120 +
 15.1121 +        int cmp = compareMagnitude(val);
 15.1122 +        if (cmp == 0)
 15.1123 +            return ZERO;
 15.1124 +        int[] resultMag = (cmp > 0 ? subtract(mag, val.mag)
 15.1125 +                           : subtract(val.mag, mag));
 15.1126 +        resultMag = trustedStripLeadingZeroInts(resultMag);
 15.1127 +        return new BigInteger(resultMag, cmp == signum ? 1 : -1);
 15.1128 +    }
 15.1129 +
 15.1130 +    /**
 15.1131 +     * Subtracts the contents of the second int arrays (little) from the
 15.1132 +     * first (big).  The first int array (big) must represent a larger number
 15.1133 +     * than the second.  This method allocates the space necessary to hold the
 15.1134 +     * answer.
 15.1135 +     */
 15.1136 +    private static int[] subtract(int[] big, int[] little) {
 15.1137 +        int bigIndex = big.length;
 15.1138 +        int result[] = new int[bigIndex];
 15.1139 +        int littleIndex = little.length;
 15.1140 +        long difference = 0;
 15.1141 +
 15.1142 +        // Subtract common parts of both numbers
 15.1143 +        while(littleIndex > 0) {
 15.1144 +            difference = (big[--bigIndex] & LONG_MASK) -
 15.1145 +                         (little[--littleIndex] & LONG_MASK) +
 15.1146 +                         (difference >> 32);
 15.1147 +            result[bigIndex] = (int)difference;
 15.1148 +        }
 15.1149 +
 15.1150 +        // Subtract remainder of longer number while borrow propagates
 15.1151 +        boolean borrow = (difference >> 32 != 0);
 15.1152 +        while (bigIndex > 0 && borrow)
 15.1153 +            borrow = ((result[--bigIndex] = big[bigIndex] - 1) == -1);
 15.1154 +
 15.1155 +        // Copy remainder of longer number
 15.1156 +        while (bigIndex > 0)
 15.1157 +            result[--bigIndex] = big[bigIndex];
 15.1158 +
 15.1159 +        return result;
 15.1160 +    }
 15.1161 +
 15.1162 +    /**
 15.1163 +     * Returns a BigInteger whose value is {@code (this * val)}.
 15.1164 +     *
 15.1165 +     * @param  val value to be multiplied by this BigInteger.
 15.1166 +     * @return {@code this * val}
 15.1167 +     */
 15.1168 +    public BigInteger multiply(BigInteger val) {
 15.1169 +        if (val.signum == 0 || signum == 0)
 15.1170 +            return ZERO;
 15.1171 +
 15.1172 +        int[] result = multiplyToLen(mag, mag.length,
 15.1173 +                                     val.mag, val.mag.length, null);
 15.1174 +        result = trustedStripLeadingZeroInts(result);
 15.1175 +        return new BigInteger(result, signum == val.signum ? 1 : -1);
 15.1176 +    }
 15.1177 +
 15.1178 +    /**
 15.1179 +     * Package private methods used by BigDecimal code to multiply a BigInteger
 15.1180 +     * with a long. Assumes v is not equal to INFLATED.
 15.1181 +     */
 15.1182 +    BigInteger multiply(long v) {
 15.1183 +        if (v == 0 || signum == 0)
 15.1184 +          return ZERO;
 15.1185 +        if (v == BigDecimal.INFLATED)
 15.1186 +            return multiply(BigInteger.valueOf(v));
 15.1187 +        int rsign = (v > 0 ? signum : -signum);
 15.1188 +        if (v < 0)
 15.1189 +            v = -v;
 15.1190 +        long dh = v >>> 32;      // higher order bits
 15.1191 +        long dl = v & LONG_MASK; // lower order bits
 15.1192 +
 15.1193 +        int xlen = mag.length;
 15.1194 +        int[] value = mag;
 15.1195 +        int[] rmag = (dh == 0L) ? (new int[xlen + 1]) : (new int[xlen + 2]);
 15.1196 +        long carry = 0;
 15.1197 +        int rstart = rmag.length - 1;
 15.1198 +        for (int i = xlen - 1; i >= 0; i--) {
 15.1199 +            long product = (value[i] & LONG_MASK) * dl + carry;
 15.1200 +            rmag[rstart--] = (int)product;
 15.1201 +            carry = product >>> 32;
 15.1202 +        }
 15.1203 +        rmag[rstart] = (int)carry;
 15.1204 +        if (dh != 0L) {
 15.1205 +            carry = 0;
 15.1206 +            rstart = rmag.length - 2;
 15.1207 +            for (int i = xlen - 1; i >= 0; i--) {
 15.1208 +                long product = (value[i] & LONG_MASK) * dh +
 15.1209 +                    (rmag[rstart] & LONG_MASK) + carry;
 15.1210 +                rmag[rstart--] = (int)product;
 15.1211 +                carry = product >>> 32;
 15.1212 +            }
 15.1213 +            rmag[0] = (int)carry;
 15.1214 +        }
 15.1215 +        if (carry == 0L)
 15.1216 +            rmag = java.util.Arrays.copyOfRange(rmag, 1, rmag.length);
 15.1217 +        return new BigInteger(rmag, rsign);
 15.1218 +    }
 15.1219 +
 15.1220 +    /**
 15.1221 +     * Multiplies int arrays x and y to the specified lengths and places
 15.1222 +     * the result into z. There will be no leading zeros in the resultant array.
 15.1223 +     */
 15.1224 +    private int[] multiplyToLen(int[] x, int xlen, int[] y, int ylen, int[] z) {
 15.1225 +        int xstart = xlen - 1;
 15.1226 +        int ystart = ylen - 1;
 15.1227 +
 15.1228 +        if (z == null || z.length < (xlen+ ylen))
 15.1229 +            z = new int[xlen+ylen];
 15.1230 +
 15.1231 +        long carry = 0;
 15.1232 +        for (int j=ystart, k=ystart+1+xstart; j>=0; j--, k--) {
 15.1233 +            long product = (y[j] & LONG_MASK) *
 15.1234 +                           (x[xstart] & LONG_MASK) + carry;
 15.1235 +            z[k] = (int)product;
 15.1236 +            carry = product >>> 32;
 15.1237 +        }
 15.1238 +        z[xstart] = (int)carry;
 15.1239 +
 15.1240 +        for (int i = xstart-1; i >= 0; i--) {
 15.1241 +            carry = 0;
 15.1242 +            for (int j=ystart, k=ystart+1+i; j>=0; j--, k--) {
 15.1243 +                long product = (y[j] & LONG_MASK) *
 15.1244 +                               (x[i] & LONG_MASK) +
 15.1245 +                               (z[k] & LONG_MASK) + carry;
 15.1246 +                z[k] = (int)product;
 15.1247 +                carry = product >>> 32;
 15.1248 +            }
 15.1249 +            z[i] = (int)carry;
 15.1250 +        }
 15.1251 +        return z;
 15.1252 +    }
 15.1253 +
 15.1254 +    /**
 15.1255 +     * Returns a BigInteger whose value is {@code (this<sup>2</sup>)}.
 15.1256 +     *
 15.1257 +     * @return {@code this<sup>2</sup>}
 15.1258 +     */
 15.1259 +    private BigInteger square() {
 15.1260 +        if (signum == 0)
 15.1261 +            return ZERO;
 15.1262 +        int[] z = squareToLen(mag, mag.length, null);
 15.1263 +        return new BigInteger(trustedStripLeadingZeroInts(z), 1);
 15.1264 +    }
 15.1265 +
 15.1266 +    /**
 15.1267 +     * Squares the contents of the int array x. The result is placed into the
 15.1268 +     * int array z.  The contents of x are not changed.
 15.1269 +     */
 15.1270 +    private static final int[] squareToLen(int[] x, int len, int[] z) {
 15.1271 +        /*
 15.1272 +         * The algorithm used here is adapted from Colin Plumb's C library.
 15.1273 +         * Technique: Consider the partial products in the multiplication
 15.1274 +         * of "abcde" by itself:
 15.1275 +         *
 15.1276 +         *               a  b  c  d  e
 15.1277 +         *            *  a  b  c  d  e
 15.1278 +         *          ==================
 15.1279 +         *              ae be ce de ee
 15.1280 +         *           ad bd cd dd de
 15.1281 +         *        ac bc cc cd ce
 15.1282 +         *     ab bb bc bd be
 15.1283 +         *  aa ab ac ad ae
 15.1284 +         *
 15.1285 +         * Note that everything above the main diagonal:
 15.1286 +         *              ae be ce de = (abcd) * e
 15.1287 +         *           ad bd cd       = (abc) * d
 15.1288 +         *        ac bc             = (ab) * c
 15.1289 +         *     ab                   = (a) * b
 15.1290 +         *
 15.1291 +         * is a copy of everything below the main diagonal:
 15.1292 +         *                       de
 15.1293 +         *                 cd ce
 15.1294 +         *           bc bd be
 15.1295 +         *     ab ac ad ae
 15.1296 +         *
 15.1297 +         * Thus, the sum is 2 * (off the diagonal) + diagonal.
 15.1298 +         *
 15.1299 +         * This is accumulated beginning with the diagonal (which
 15.1300 +         * consist of the squares of the digits of the input), which is then
 15.1301 +         * divided by two, the off-diagonal added, and multiplied by two
 15.1302 +         * again.  The low bit is simply a copy of the low bit of the
 15.1303 +         * input, so it doesn't need special care.
 15.1304 +         */
 15.1305 +        int zlen = len << 1;
 15.1306 +        if (z == null || z.length < zlen)
 15.1307 +            z = new int[zlen];
 15.1308 +
 15.1309 +        // Store the squares, right shifted one bit (i.e., divided by 2)
 15.1310 +        int lastProductLowWord = 0;
 15.1311 +        for (int j=0, i=0; j<len; j++) {
 15.1312 +            long piece = (x[j] & LONG_MASK);
 15.1313 +            long product = piece * piece;
 15.1314 +            z[i++] = (lastProductLowWord << 31) | (int)(product >>> 33);
 15.1315 +            z[i++] = (int)(product >>> 1);
 15.1316 +            lastProductLowWord = (int)product;
 15.1317 +        }
 15.1318 +
 15.1319 +        // Add in off-diagonal sums
 15.1320 +        for (int i=len, offset=1; i>0; i--, offset+=2) {
 15.1321 +            int t = x[i-1];
 15.1322 +            t = mulAdd(z, x, offset, i-1, t);
 15.1323 +            addOne(z, offset-1, i, t);
 15.1324 +        }
 15.1325 +
 15.1326 +        // Shift back up and set low bit
 15.1327 +        primitiveLeftShift(z, zlen, 1);
 15.1328 +        z[zlen-1] |= x[len-1] & 1;
 15.1329 +
 15.1330 +        return z;
 15.1331 +    }
 15.1332 +
 15.1333 +    /**
 15.1334 +     * Returns a BigInteger whose value is {@code (this / val)}.
 15.1335 +     *
 15.1336 +     * @param  val value by which this BigInteger is to be divided.
 15.1337 +     * @return {@code this / val}
 15.1338 +     * @throws ArithmeticException if {@code val} is zero.
 15.1339 +     */
 15.1340 +    public BigInteger divide(BigInteger val) {
 15.1341 +        MutableBigInteger q = new MutableBigInteger(),
 15.1342 +                          a = new MutableBigInteger(this.mag),
 15.1343 +                          b = new MutableBigInteger(val.mag);
 15.1344 +
 15.1345 +        a.divide(b, q);
 15.1346 +        return q.toBigInteger(this.signum == val.signum ? 1 : -1);
 15.1347 +    }
 15.1348 +
 15.1349 +    /**
 15.1350 +     * Returns an array of two BigIntegers containing {@code (this / val)}
 15.1351 +     * followed by {@code (this % val)}.
 15.1352 +     *
 15.1353 +     * @param  val value by which this BigInteger is to be divided, and the
 15.1354 +     *         remainder computed.
 15.1355 +     * @return an array of two BigIntegers: the quotient {@code (this / val)}
 15.1356 +     *         is the initial element, and the remainder {@code (this % val)}
 15.1357 +     *         is the final element.
 15.1358 +     * @throws ArithmeticException if {@code val} is zero.
 15.1359 +     */
 15.1360 +    public BigInteger[] divideAndRemainder(BigInteger val) {
 15.1361 +        BigInteger[] result = new BigInteger[2];
 15.1362 +        MutableBigInteger q = new MutableBigInteger(),
 15.1363 +                          a = new MutableBigInteger(this.mag),
 15.1364 +                          b = new MutableBigInteger(val.mag);
 15.1365 +        MutableBigInteger r = a.divide(b, q);
 15.1366 +        result[0] = q.toBigInteger(this.signum == val.signum ? 1 : -1);
 15.1367 +        result[1] = r.toBigInteger(this.signum);
 15.1368 +        return result;
 15.1369 +    }
 15.1370 +
 15.1371 +    /**
 15.1372 +     * Returns a BigInteger whose value is {@code (this % val)}.
 15.1373 +     *
 15.1374 +     * @param  val value by which this BigInteger is to be divided, and the
 15.1375 +     *         remainder computed.
 15.1376 +     * @return {@code this % val}
 15.1377 +     * @throws ArithmeticException if {@code val} is zero.
 15.1378 +     */
 15.1379 +    public BigInteger remainder(BigInteger val) {
 15.1380 +        MutableBigInteger q = new MutableBigInteger(),
 15.1381 +                          a = new MutableBigInteger(this.mag),
 15.1382 +                          b = new MutableBigInteger(val.mag);
 15.1383 +
 15.1384 +        return a.divide(b, q).toBigInteger(this.signum);
 15.1385 +    }
 15.1386 +
 15.1387 +    /**
 15.1388 +     * Returns a BigInteger whose value is <tt>(this<sup>exponent</sup>)</tt>.
 15.1389 +     * Note that {@code exponent} is an integer rather than a BigInteger.
 15.1390 +     *
 15.1391 +     * @param  exponent exponent to which this BigInteger is to be raised.
 15.1392 +     * @return <tt>this<sup>exponent</sup></tt>
 15.1393 +     * @throws ArithmeticException {@code exponent} is negative.  (This would
 15.1394 +     *         cause the operation to yield a non-integer value.)
 15.1395 +     */
 15.1396 +    public BigInteger pow(int exponent) {
 15.1397 +        if (exponent < 0)
 15.1398 +            throw new ArithmeticException("Negative exponent");
 15.1399 +        if (signum==0)
 15.1400 +            return (exponent==0 ? ONE : this);
 15.1401 +
 15.1402 +        // Perform exponentiation using repeated squaring trick
 15.1403 +        int newSign = (signum<0 && (exponent&1)==1 ? -1 : 1);
 15.1404 +        int[] baseToPow2 = this.mag;
 15.1405 +        int[] result = {1};
 15.1406 +
 15.1407 +        while (exponent != 0) {
 15.1408 +            if ((exponent & 1)==1) {
 15.1409 +                result = multiplyToLen(result, result.length,
 15.1410 +                                       baseToPow2, baseToPow2.length, null);
 15.1411 +                result = trustedStripLeadingZeroInts(result);
 15.1412 +            }
 15.1413 +            if ((exponent >>>= 1) != 0) {
 15.1414 +                baseToPow2 = squareToLen(baseToPow2, baseToPow2.length, null);
 15.1415 +                baseToPow2 = trustedStripLeadingZeroInts(baseToPow2);
 15.1416 +            }
 15.1417 +        }
 15.1418 +        return new BigInteger(result, newSign);
 15.1419 +    }
 15.1420 +
 15.1421 +    /**
 15.1422 +     * Returns a BigInteger whose value is the greatest common divisor of
 15.1423 +     * {@code abs(this)} and {@code abs(val)}.  Returns 0 if
 15.1424 +     * {@code this==0 && val==0}.
 15.1425 +     *
 15.1426 +     * @param  val value with which the GCD is to be computed.
 15.1427 +     * @return {@code GCD(abs(this), abs(val))}
 15.1428 +     */
 15.1429 +    public BigInteger gcd(BigInteger val) {
 15.1430 +        if (val.signum == 0)
 15.1431 +            return this.abs();
 15.1432 +        else if (this.signum == 0)
 15.1433 +            return val.abs();
 15.1434 +
 15.1435 +        MutableBigInteger a = new MutableBigInteger(this);
 15.1436 +        MutableBigInteger b = new MutableBigInteger(val);
 15.1437 +
 15.1438 +        MutableBigInteger result = a.hybridGCD(b);
 15.1439 +
 15.1440 +        return result.toBigInteger(1);
 15.1441 +    }
 15.1442 +
 15.1443 +    /**
 15.1444 +     * Package private method to return bit length for an integer.
 15.1445 +     */
 15.1446 +    static int bitLengthForInt(int n) {
 15.1447 +        return 32 - Integer.numberOfLeadingZeros(n);
 15.1448 +    }
 15.1449 +
 15.1450 +    /**
 15.1451 +     * Left shift int array a up to len by n bits. Returns the array that
 15.1452 +     * results from the shift since space may have to be reallocated.
 15.1453 +     */
 15.1454 +    private static int[] leftShift(int[] a, int len, int n) {
 15.1455 +        int nInts = n >>> 5;
 15.1456 +        int nBits = n&0x1F;
 15.1457 +        int bitsInHighWord = bitLengthForInt(a[0]);
 15.1458 +
 15.1459 +        // If shift can be done without recopy, do so
 15.1460 +        if (n <= (32-bitsInHighWord)) {
 15.1461 +            primitiveLeftShift(a, len, nBits);
 15.1462 +            return a;
 15.1463 +        } else { // Array must be resized
 15.1464 +            if (nBits <= (32-bitsInHighWord)) {
 15.1465 +                int result[] = new int[nInts+len];
 15.1466 +                for (int i=0; i<len; i++)
 15.1467 +                    result[i] = a[i];
 15.1468 +                primitiveLeftShift(result, result.length, nBits);
 15.1469 +                return result;
 15.1470 +            } else {
 15.1471 +                int result[] = new int[nInts+len+1];
 15.1472 +                for (int i=0; i<len; i++)
 15.1473 +                    result[i] = a[i];
 15.1474 +                primitiveRightShift(result, result.length, 32 - nBits);
 15.1475 +                return result;
 15.1476 +            }
 15.1477 +        }
 15.1478 +    }
 15.1479 +
 15.1480 +    // shifts a up to len right n bits assumes no leading zeros, 0<n<32
 15.1481 +    static void primitiveRightShift(int[] a, int len, int n) {
 15.1482 +        int n2 = 32 - n;
 15.1483 +        for (int i=len-1, c=a[i]; i>0; i--) {
 15.1484 +            int b = c;
 15.1485 +            c = a[i-1];
 15.1486 +            a[i] = (c << n2) | (b >>> n);
 15.1487 +        }
 15.1488 +        a[0] >>>= n;
 15.1489 +    }
 15.1490 +
 15.1491 +    // shifts a up to len left n bits assumes no leading zeros, 0<=n<32
 15.1492 +    static void primitiveLeftShift(int[] a, int len, int n) {
 15.1493 +        if (len == 0 || n == 0)
 15.1494 +            return;
 15.1495 +
 15.1496 +        int n2 = 32 - n;
 15.1497 +        for (int i=0, c=a[i], m=i+len-1; i<m; i++) {
 15.1498 +            int b = c;
 15.1499 +            c = a[i+1];
 15.1500 +            a[i] = (b << n) | (c >>> n2);
 15.1501 +        }
 15.1502 +        a[len-1] <<= n;
 15.1503 +    }
 15.1504 +
 15.1505 +    /**
 15.1506 +     * Calculate bitlength of contents of the first len elements an int array,
 15.1507 +     * assuming there are no leading zero ints.
 15.1508 +     */
 15.1509 +    private static int bitLength(int[] val, int len) {
 15.1510 +        if (len == 0)
 15.1511 +            return 0;
 15.1512 +        return ((len - 1) << 5) + bitLengthForInt(val[0]);
 15.1513 +    }
 15.1514 +
 15.1515 +    /**
 15.1516 +     * Returns a BigInteger whose value is the absolute value of this
 15.1517 +     * BigInteger.
 15.1518 +     *
 15.1519 +     * @return {@code abs(this)}
 15.1520 +     */
 15.1521 +    public BigInteger abs() {
 15.1522 +        return (signum >= 0 ? this : this.negate());
 15.1523 +    }
 15.1524 +
 15.1525 +    /**
 15.1526 +     * Returns a BigInteger whose value is {@code (-this)}.
 15.1527 +     *
 15.1528 +     * @return {@code -this}
 15.1529 +     */
 15.1530 +    public BigInteger negate() {
 15.1531 +        return new BigInteger(this.mag, -this.signum);
 15.1532 +    }
 15.1533 +
 15.1534 +    /**
 15.1535 +     * Returns the signum function of this BigInteger.
 15.1536 +     *
 15.1537 +     * @return -1, 0 or 1 as the value of this BigInteger is negative, zero or
 15.1538 +     *         positive.
 15.1539 +     */
 15.1540 +    public int signum() {
 15.1541 +        return this.signum;
 15.1542 +    }
 15.1543 +
 15.1544 +    // Modular Arithmetic Operations
 15.1545 +
 15.1546 +    /**
 15.1547 +     * Returns a BigInteger whose value is {@code (this mod m}).  This method
 15.1548 +     * differs from {@code remainder} in that it always returns a
 15.1549 +     * <i>non-negative</i> BigInteger.
 15.1550 +     *
 15.1551 +     * @param  m the modulus.
 15.1552 +     * @return {@code this mod m}
 15.1553 +     * @throws ArithmeticException {@code m} &le; 0
 15.1554 +     * @see    #remainder
 15.1555 +     */
 15.1556 +    public BigInteger mod(BigInteger m) {
 15.1557 +        if (m.signum <= 0)
 15.1558 +            throw new ArithmeticException("BigInteger: modulus not positive");
 15.1559 +
 15.1560 +        BigInteger result = this.remainder(m);
 15.1561 +        return (result.signum >= 0 ? result : result.add(m));
 15.1562 +    }
 15.1563 +
 15.1564 +    /**
 15.1565 +     * Returns a BigInteger whose value is
 15.1566 +     * <tt>(this<sup>exponent</sup> mod m)</tt>.  (Unlike {@code pow}, this
 15.1567 +     * method permits negative exponents.)
 15.1568 +     *
 15.1569 +     * @param  exponent the exponent.
 15.1570 +     * @param  m the modulus.
 15.1571 +     * @return <tt>this<sup>exponent</sup> mod m</tt>
 15.1572 +     * @throws ArithmeticException {@code m} &le; 0 or the exponent is
 15.1573 +     *         negative and this BigInteger is not <i>relatively
 15.1574 +     *         prime</i> to {@code m}.
 15.1575 +     * @see    #modInverse
 15.1576 +     */
 15.1577 +    public BigInteger modPow(BigInteger exponent, BigInteger m) {
 15.1578 +        if (m.signum <= 0)
 15.1579 +            throw new ArithmeticException("BigInteger: modulus not positive");
 15.1580 +
 15.1581 +        // Trivial cases
 15.1582 +        if (exponent.signum == 0)
 15.1583 +            return (m.equals(ONE) ? ZERO : ONE);
 15.1584 +
 15.1585 +        if (this.equals(ONE))
 15.1586 +            return (m.equals(ONE) ? ZERO : ONE);
 15.1587 +
 15.1588 +        if (this.equals(ZERO) && exponent.signum >= 0)
 15.1589 +            return ZERO;
 15.1590 +
 15.1591 +        if (this.equals(negConst[1]) && (!exponent.testBit(0)))
 15.1592 +            return (m.equals(ONE) ? ZERO : ONE);
 15.1593 +
 15.1594 +        boolean invertResult;
 15.1595 +        if ((invertResult = (exponent.signum < 0)))
 15.1596 +            exponent = exponent.negate();
 15.1597 +
 15.1598 +        BigInteger base = (this.signum < 0 || this.compareTo(m) >= 0
 15.1599 +                           ? this.mod(m) : this);
 15.1600 +        BigInteger result;
 15.1601 +        if (m.testBit(0)) { // odd modulus
 15.1602 +            result = base.oddModPow(exponent, m);
 15.1603 +        } else {
 15.1604 +            /*
 15.1605 +             * Even modulus.  Tear it into an "odd part" (m1) and power of two
 15.1606 +             * (m2), exponentiate mod m1, manually exponentiate mod m2, and
 15.1607 +             * use Chinese Remainder Theorem to combine results.
 15.1608 +             */
 15.1609 +
 15.1610 +            // Tear m apart into odd part (m1) and power of 2 (m2)
 15.1611 +            int p = m.getLowestSetBit();   // Max pow of 2 that divides m
 15.1612 +
 15.1613 +            BigInteger m1 = m.shiftRight(p);  // m/2**p
 15.1614 +            BigInteger m2 = ONE.shiftLeft(p); // 2**p
 15.1615 +
 15.1616 +            // Calculate new base from m1
 15.1617 +            BigInteger base2 = (this.signum < 0 || this.compareTo(m1) >= 0
 15.1618 +                                ? this.mod(m1) : this);
 15.1619 +
 15.1620 +            // Caculate (base ** exponent) mod m1.
 15.1621 +            BigInteger a1 = (m1.equals(ONE) ? ZERO :
 15.1622 +                             base2.oddModPow(exponent, m1));
 15.1623 +
 15.1624 +            // Calculate (this ** exponent) mod m2
 15.1625 +            BigInteger a2 = base.modPow2(exponent, p);
 15.1626 +
 15.1627 +            // Combine results using Chinese Remainder Theorem
 15.1628 +            BigInteger y1 = m2.modInverse(m1);
 15.1629 +            BigInteger y2 = m1.modInverse(m2);
 15.1630 +
 15.1631 +            result = a1.multiply(m2).multiply(y1).add
 15.1632 +                     (a2.multiply(m1).multiply(y2)).mod(m);
 15.1633 +        }
 15.1634 +
 15.1635 +        return (invertResult ? result.modInverse(m) : result);
 15.1636 +    }
 15.1637 +
 15.1638 +    static int[] bnExpModThreshTable = {7, 25, 81, 241, 673, 1793,
 15.1639 +                                                Integer.MAX_VALUE}; // Sentinel
 15.1640 +
 15.1641 +    /**
 15.1642 +     * Returns a BigInteger whose value is x to the power of y mod z.
 15.1643 +     * Assumes: z is odd && x < z.
 15.1644 +     */
 15.1645 +    private BigInteger oddModPow(BigInteger y, BigInteger z) {
 15.1646 +    /*
 15.1647 +     * The algorithm is adapted from Colin Plumb's C library.
 15.1648 +     *
 15.1649 +     * The window algorithm:
 15.1650 +     * The idea is to keep a running product of b1 = n^(high-order bits of exp)
 15.1651 +     * and then keep appending exponent bits to it.  The following patterns
 15.1652 +     * apply to a 3-bit window (k = 3):
 15.1653 +     * To append   0: square
 15.1654 +     * To append   1: square, multiply by n^1
 15.1655 +     * To append  10: square, multiply by n^1, square
 15.1656 +     * To append  11: square, square, multiply by n^3
 15.1657 +     * To append 100: square, multiply by n^1, square, square
 15.1658 +     * To append 101: square, square, square, multiply by n^5
 15.1659 +     * To append 110: square, square, multiply by n^3, square
 15.1660 +     * To append 111: square, square, square, multiply by n^7
 15.1661 +     *
 15.1662 +     * Since each pattern involves only one multiply, the longer the pattern
 15.1663 +     * the better, except that a 0 (no multiplies) can be appended directly.
 15.1664 +     * We precompute a table of odd powers of n, up to 2^k, and can then
 15.1665 +     * multiply k bits of exponent at a time.  Actually, assuming random
 15.1666 +     * exponents, there is on average one zero bit between needs to
 15.1667 +     * multiply (1/2 of the time there's none, 1/4 of the time there's 1,
 15.1668 +     * 1/8 of the time, there's 2, 1/32 of the time, there's 3, etc.), so
 15.1669 +     * you have to do one multiply per k+1 bits of exponent.
 15.1670 +     *
 15.1671 +     * The loop walks down the exponent, squaring the result buffer as
 15.1672 +     * it goes.  There is a wbits+1 bit lookahead buffer, buf, that is
 15.1673 +     * filled with the upcoming exponent bits.  (What is read after the
 15.1674 +     * end of the exponent is unimportant, but it is filled with zero here.)
 15.1675 +     * When the most-significant bit of this buffer becomes set, i.e.
 15.1676 +     * (buf & tblmask) != 0, we have to decide what pattern to multiply
 15.1677 +     * by, and when to do it.  We decide, remember to do it in future
 15.1678 +     * after a suitable number of squarings have passed (e.g. a pattern
 15.1679 +     * of "100" in the buffer requires that we multiply by n^1 immediately;
 15.1680 +     * a pattern of "110" calls for multiplying by n^3 after one more
 15.1681 +     * squaring), clear the buffer, and continue.
 15.1682 +     *
 15.1683 +     * When we start, there is one more optimization: the result buffer
 15.1684 +     * is implcitly one, so squaring it or multiplying by it can be
 15.1685 +     * optimized away.  Further, if we start with a pattern like "100"
 15.1686 +     * in the lookahead window, rather than placing n into the buffer
 15.1687 +     * and then starting to square it, we have already computed n^2
 15.1688 +     * to compute the odd-powers table, so we can place that into
 15.1689 +     * the buffer and save a squaring.
 15.1690 +     *
 15.1691 +     * This means that if you have a k-bit window, to compute n^z,
 15.1692 +     * where z is the high k bits of the exponent, 1/2 of the time
 15.1693 +     * it requires no squarings.  1/4 of the time, it requires 1
 15.1694 +     * squaring, ... 1/2^(k-1) of the time, it reqires k-2 squarings.
 15.1695 +     * And the remaining 1/2^(k-1) of the time, the top k bits are a
 15.1696 +     * 1 followed by k-1 0 bits, so it again only requires k-2
 15.1697 +     * squarings, not k-1.  The average of these is 1.  Add that
 15.1698 +     * to the one squaring we have to do to compute the table,
 15.1699 +     * and you'll see that a k-bit window saves k-2 squarings
 15.1700 +     * as well as reducing the multiplies.  (It actually doesn't
 15.1701 +     * hurt in the case k = 1, either.)
 15.1702 +     */
 15.1703 +        // Special case for exponent of one
 15.1704 +        if (y.equals(ONE))
 15.1705 +            return this;
 15.1706 +
 15.1707 +        // Special case for base of zero
 15.1708 +        if (signum==0)
 15.1709 +            return ZERO;
 15.1710 +
 15.1711 +        int[] base = mag.clone();
 15.1712 +        int[] exp = y.mag;
 15.1713 +        int[] mod = z.mag;
 15.1714 +        int modLen = mod.length;
 15.1715 +
 15.1716 +        // Select an appropriate window size
 15.1717 +        int wbits = 0;
 15.1718 +        int ebits = bitLength(exp, exp.length);
 15.1719 +        // if exponent is 65537 (0x10001), use minimum window size
 15.1720 +        if ((ebits != 17) || (exp[0] != 65537)) {
 15.1721 +            while (ebits > bnExpModThreshTable[wbits]) {
 15.1722 +                wbits++;
 15.1723 +            }
 15.1724 +        }
 15.1725 +
 15.1726 +        // Calculate appropriate table size
 15.1727 +        int tblmask = 1 << wbits;
 15.1728 +
 15.1729 +        // Allocate table for precomputed odd powers of base in Montgomery form
 15.1730 +        int[][] table = new int[tblmask][];
 15.1731 +        for (int i=0; i<tblmask; i++)
 15.1732 +            table[i] = new int[modLen];
 15.1733 +
 15.1734 +        // Compute the modular inverse
 15.1735 +        int inv = -MutableBigInteger.inverseMod32(mod[modLen-1]);
 15.1736 +
 15.1737 +        // Convert base to Montgomery form
 15.1738 +        int[] a = leftShift(base, base.length, modLen << 5);
 15.1739 +
 15.1740 +        MutableBigInteger q = new MutableBigInteger(),
 15.1741 +                          a2 = new MutableBigInteger(a),
 15.1742 +                          b2 = new MutableBigInteger(mod);
 15.1743 +
 15.1744 +        MutableBigInteger r= a2.divide(b2, q);
 15.1745 +        table[0] = r.toIntArray();
 15.1746 +
 15.1747 +        // Pad table[0] with leading zeros so its length is at least modLen
 15.1748 +        if (table[0].length < modLen) {
 15.1749 +           int offset = modLen - table[0].length;
 15.1750 +           int[] t2 = new int[modLen];
 15.1751 +           for (int i=0; i<table[0].length; i++)
 15.1752 +               t2[i+offset] = table[0][i];
 15.1753 +           table[0] = t2;
 15.1754 +        }
 15.1755 +
 15.1756 +        // Set b to the square of the base
 15.1757 +        int[] b = squareToLen(table[0], modLen, null);
 15.1758 +        b = montReduce(b, mod, modLen, inv);
 15.1759 +
 15.1760 +        // Set t to high half of b
 15.1761 +        int[] t = new int[modLen];
 15.1762 +        for(int i=0; i<modLen; i++)
 15.1763 +            t[i] = b[i];
 15.1764 +
 15.1765 +        // Fill in the table with odd powers of the base
 15.1766 +        for (int i=1; i<tblmask; i++) {
 15.1767 +            int[] prod = multiplyToLen(t, modLen, table[i-1], modLen, null);
 15.1768 +            table[i] = montReduce(prod, mod, modLen, inv);
 15.1769 +        }
 15.1770 +
 15.1771 +        // Pre load the window that slides over the exponent
 15.1772 +        int bitpos = 1 << ((ebits-1) & (32-1));
 15.1773 +
 15.1774 +        int buf = 0;
 15.1775 +        int elen = exp.length;
 15.1776 +        int eIndex = 0;
 15.1777 +        for (int i = 0; i <= wbits; i++) {
 15.1778 +            buf = (buf << 1) | (((exp[eIndex] & bitpos) != 0)?1:0);
 15.1779 +            bitpos >>>= 1;
 15.1780 +            if (bitpos == 0) {
 15.1781 +                eIndex++;
 15.1782 +                bitpos = 1 << (32-1);
 15.1783 +                elen--;
 15.1784 +            }
 15.1785 +        }
 15.1786 +
 15.1787 +        int multpos = ebits;
 15.1788 +
 15.1789 +        // The first iteration, which is hoisted out of the main loop
 15.1790 +        ebits--;
 15.1791 +        boolean isone = true;
 15.1792 +
 15.1793 +        multpos = ebits - wbits;
 15.1794 +        while ((buf & 1) == 0) {
 15.1795 +            buf >>>= 1;
 15.1796 +            multpos++;
 15.1797 +        }
 15.1798 +
 15.1799 +        int[] mult = table[buf >>> 1];
 15.1800 +
 15.1801 +        buf = 0;
 15.1802 +        if (multpos == ebits)
 15.1803 +            isone = false;
 15.1804 +
 15.1805 +        // The main loop
 15.1806 +        while(true) {
 15.1807 +            ebits--;
 15.1808 +            // Advance the window
 15.1809 +            buf <<= 1;
 15.1810 +
 15.1811 +            if (elen != 0) {
 15.1812 +                buf |= ((exp[eIndex] & bitpos) != 0) ? 1 : 0;
 15.1813 +                bitpos >>>= 1;
 15.1814 +                if (bitpos == 0) {
 15.1815 +                    eIndex++;
 15.1816 +                    bitpos = 1 << (32-1);
 15.1817 +                    elen--;
 15.1818 +                }
 15.1819 +            }
 15.1820 +
 15.1821 +            // Examine the window for pending multiplies
 15.1822 +            if ((buf & tblmask) != 0) {
 15.1823 +                multpos = ebits - wbits;
 15.1824 +                while ((buf & 1) == 0) {
 15.1825 +                    buf >>>= 1;
 15.1826 +                    multpos++;
 15.1827 +                }
 15.1828 +                mult = table[buf >>> 1];
 15.1829 +                buf = 0;
 15.1830 +            }
 15.1831 +
 15.1832 +            // Perform multiply
 15.1833 +            if (ebits == multpos) {
 15.1834 +                if (isone) {
 15.1835 +                    b = mult.clone();
 15.1836 +                    isone = false;
 15.1837 +                } else {
 15.1838 +                    t = b;
 15.1839 +                    a = multiplyToLen(t, modLen, mult, modLen, a);
 15.1840 +                    a = montReduce(a, mod, modLen, inv);
 15.1841 +                    t = a; a = b; b = t;
 15.1842 +                }
 15.1843 +            }
 15.1844 +
 15.1845 +            // Check if done
 15.1846 +            if (ebits == 0)
 15.1847 +                break;
 15.1848 +
 15.1849 +            // Square the input
 15.1850 +            if (!isone) {
 15.1851 +                t = b;
 15.1852 +                a = squareToLen(t, modLen, a);
 15.1853 +                a = montReduce(a, mod, modLen, inv);
 15.1854 +                t = a; a = b; b = t;
 15.1855 +            }
 15.1856 +        }
 15.1857 +
 15.1858 +        // Convert result out of Montgomery form and return
 15.1859 +        int[] t2 = new int[2*modLen];
 15.1860 +        for(int i=0; i<modLen; i++)
 15.1861 +            t2[i+modLen] = b[i];
 15.1862 +
 15.1863 +        b = montReduce(t2, mod, modLen, inv);
 15.1864 +
 15.1865 +        t2 = new int[modLen];
 15.1866 +        for(int i=0; i<modLen; i++)
 15.1867 +            t2[i] = b[i];
 15.1868 +
 15.1869 +        return new BigInteger(1, t2);
 15.1870 +    }
 15.1871 +
 15.1872 +    /**
 15.1873 +     * Montgomery reduce n, modulo mod.  This reduces modulo mod and divides
 15.1874 +     * by 2^(32*mlen). Adapted from Colin Plumb's C library.
 15.1875 +     */
 15.1876 +    private static int[] montReduce(int[] n, int[] mod, int mlen, int inv) {
 15.1877 +        int c=0;
 15.1878 +        int len = mlen;
 15.1879 +        int offset=0;
 15.1880 +
 15.1881 +        do {
 15.1882 +            int nEnd = n[n.length-1-offset];
 15.1883 +            int carry = mulAdd(n, mod, offset, mlen, inv * nEnd);
 15.1884 +            c += addOne(n, offset, mlen, carry);
 15.1885 +            offset++;
 15.1886 +        } while(--len > 0);
 15.1887 +
 15.1888 +        while(c>0)
 15.1889 +            c += subN(n, mod, mlen);
 15.1890 +
 15.1891 +        while (intArrayCmpToLen(n, mod, mlen) >= 0)
 15.1892 +            subN(n, mod, mlen);
 15.1893 +
 15.1894 +        return n;
 15.1895 +    }
 15.1896 +
 15.1897 +
 15.1898 +    /*
 15.1899 +     * Returns -1, 0 or +1 as big-endian unsigned int array arg1 is less than,
 15.1900 +     * equal to, or greater than arg2 up to length len.
 15.1901 +     */
 15.1902 +    private static int intArrayCmpToLen(int[] arg1, int[] arg2, int len) {
 15.1903 +        for (int i=0; i<len; i++) {
 15.1904 +            long b1 = arg1[i] & LONG_MASK;
 15.1905 +            long b2 = arg2[i] & LONG_MASK;
 15.1906 +            if (b1 < b2)
 15.1907 +                return -1;
 15.1908 +            if (b1 > b2)
 15.1909 +                return 1;
 15.1910 +        }
 15.1911 +        return 0;
 15.1912 +    }
 15.1913 +
 15.1914 +    /**
 15.1915 +     * Subtracts two numbers of same length, returning borrow.
 15.1916 +     */
 15.1917 +    private static int subN(int[] a, int[] b, int len) {
 15.1918 +        long sum = 0;
 15.1919 +
 15.1920 +        while(--len >= 0) {
 15.1921 +            sum = (a[len] & LONG_MASK) -
 15.1922 +                 (b[len] & LONG_MASK) + (sum >> 32);
 15.1923 +            a[len] = (int)sum;
 15.1924 +        }
 15.1925 +
 15.1926 +        return (int)(sum >> 32);
 15.1927 +    }
 15.1928 +
 15.1929 +    /**
 15.1930 +     * Multiply an array by one word k and add to result, return the carry
 15.1931 +     */
 15.1932 +    static int mulAdd(int[] out, int[] in, int offset, int len, int k) {
 15.1933 +        long kLong = k & LONG_MASK;
 15.1934 +        long carry = 0;
 15.1935 +
 15.1936 +        offset = out.length-offset - 1;
 15.1937 +        for (int j=len-1; j >= 0; j--) {
 15.1938 +            long product = (in[j] & LONG_MASK) * kLong +
 15.1939 +                           (out[offset] & LONG_MASK) + carry;
 15.1940 +            out[offset--] = (int)product;
 15.1941 +            carry = product >>> 32;
 15.1942 +        }
 15.1943 +        return (int)carry;
 15.1944 +    }
 15.1945 +
 15.1946 +    /**
 15.1947 +     * Add one word to the number a mlen words into a. Return the resulting
 15.1948 +     * carry.
 15.1949 +     */
 15.1950 +    static int addOne(int[] a, int offset, int mlen, int carry) {
 15.1951 +        offset = a.length-1-mlen-offset;
 15.1952 +        long t = (a[offset] & LONG_MASK) + (carry & LONG_MASK);
 15.1953 +
 15.1954 +        a[offset] = (int)t;
 15.1955 +        if ((t >>> 32) == 0)
 15.1956 +            return 0;
 15.1957 +        while (--mlen >= 0) {
 15.1958 +            if (--offset < 0) { // Carry out of number
 15.1959 +                return 1;
 15.1960 +            } else {
 15.1961 +                a[offset]++;
 15.1962 +                if (a[offset] != 0)
 15.1963 +                    return 0;
 15.1964 +            }
 15.1965 +        }
 15.1966 +        return 1;
 15.1967 +    }
 15.1968 +
 15.1969 +    /**
 15.1970 +     * Returns a BigInteger whose value is (this ** exponent) mod (2**p)
 15.1971 +     */
 15.1972 +    private BigInteger modPow2(BigInteger exponent, int p) {
 15.1973 +        /*
 15.1974 +         * Perform exponentiation using repeated squaring trick, chopping off
 15.1975 +         * high order bits as indicated by modulus.
 15.1976 +         */
 15.1977 +        BigInteger result = valueOf(1);
 15.1978 +        BigInteger baseToPow2 = this.mod2(p);
 15.1979 +        int expOffset = 0;
 15.1980 +
 15.1981 +        int limit = exponent.bitLength();
 15.1982 +
 15.1983 +        if (this.testBit(0))
 15.1984 +           limit = (p-1) < limit ? (p-1) : limit;
 15.1985 +
 15.1986 +        while (expOffset < limit) {
 15.1987 +            if (exponent.testBit(expOffset))
 15.1988 +                result = result.multiply(baseToPow2).mod2(p);
 15.1989 +            expOffset++;
 15.1990 +            if (expOffset < limit)
 15.1991 +                baseToPow2 = baseToPow2.square().mod2(p);
 15.1992 +        }
 15.1993 +
 15.1994 +        return result;
 15.1995 +    }
 15.1996 +
 15.1997 +    /**
 15.1998 +     * Returns a BigInteger whose value is this mod(2**p).
 15.1999 +     * Assumes that this {@code BigInteger >= 0} and {@code p > 0}.
 15.2000 +     */
 15.2001 +    private BigInteger mod2(int p) {
 15.2002 +        if (bitLength() <= p)
 15.2003 +            return this;
 15.2004 +
 15.2005 +        // Copy remaining ints of mag
 15.2006 +        int numInts = (p + 31) >>> 5;
 15.2007 +        int[] mag = new int[numInts];
 15.2008 +        for (int i=0; i<numInts; i++)
 15.2009 +            mag[i] = this.mag[i + (this.mag.length - numInts)];
 15.2010 +
 15.2011 +        // Mask out any excess bits
 15.2012 +        int excessBits = (numInts << 5) - p;
 15.2013 +        mag[0] &= (1L << (32-excessBits)) - 1;
 15.2014 +
 15.2015 +        return (mag[0]==0 ? new BigInteger(1, mag) : new BigInteger(mag, 1));
 15.2016 +    }
 15.2017 +
 15.2018 +    /**
 15.2019 +     * Returns a BigInteger whose value is {@code (this}<sup>-1</sup> {@code mod m)}.
 15.2020 +     *
 15.2021 +     * @param  m the modulus.
 15.2022 +     * @return {@code this}<sup>-1</sup> {@code mod m}.
 15.2023 +     * @throws ArithmeticException {@code  m} &le; 0, or this BigInteger
 15.2024 +     *         has no multiplicative inverse mod m (that is, this BigInteger
 15.2025 +     *         is not <i>relatively prime</i> to m).
 15.2026 +     */
 15.2027 +    public BigInteger modInverse(BigInteger m) {
 15.2028 +        if (m.signum != 1)
 15.2029 +            throw new ArithmeticException("BigInteger: modulus not positive");
 15.2030 +
 15.2031 +        if (m.equals(ONE))
 15.2032 +            return ZERO;
 15.2033 +
 15.2034 +        // Calculate (this mod m)
 15.2035 +        BigInteger modVal = this;
 15.2036 +        if (signum < 0 || (this.compareMagnitude(m) >= 0))
 15.2037 +            modVal = this.mod(m);
 15.2038 +
 15.2039 +        if (modVal.equals(ONE))
 15.2040 +            return ONE;
 15.2041 +
 15.2042 +        MutableBigInteger a = new MutableBigInteger(modVal);
 15.2043 +        MutableBigInteger b = new MutableBigInteger(m);
 15.2044 +
 15.2045 +        MutableBigInteger result = a.mutableModInverse(b);
 15.2046 +        return result.toBigInteger(1);
 15.2047 +    }
 15.2048 +
 15.2049 +    // Shift Operations
 15.2050 +
 15.2051 +    /**
 15.2052 +     * Returns a BigInteger whose value is {@code (this << n)}.
 15.2053 +     * The shift distance, {@code n}, may be negative, in which case
 15.2054 +     * this method performs a right shift.
 15.2055 +     * (Computes <tt>floor(this * 2<sup>n</sup>)</tt>.)
 15.2056 +     *
 15.2057 +     * @param  n shift distance, in bits.
 15.2058 +     * @return {@code this << n}
 15.2059 +     * @throws ArithmeticException if the shift distance is {@code
 15.2060 +     *         Integer.MIN_VALUE}.
 15.2061 +     * @see #shiftRight
 15.2062 +     */
 15.2063 +    public BigInteger shiftLeft(int n) {
 15.2064 +        if (signum == 0)
 15.2065 +            return ZERO;
 15.2066 +        if (n==0)
 15.2067 +            return this;
 15.2068 +        if (n<0) {
 15.2069 +            if (n == Integer.MIN_VALUE) {
 15.2070 +                throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported.");
 15.2071 +            } else {
 15.2072 +                return shiftRight(-n);
 15.2073 +            }
 15.2074 +        }
 15.2075 +
 15.2076 +        int nInts = n >>> 5;
 15.2077 +        int nBits = n & 0x1f;
 15.2078 +        int magLen = mag.length;
 15.2079 +        int newMag[] = null;
 15.2080 +
 15.2081 +        if (nBits == 0) {
 15.2082 +            newMag = new int[magLen + nInts];
 15.2083 +            for (int i=0; i<magLen; i++)
 15.2084 +                newMag[i] = mag[i];
 15.2085 +        } else {
 15.2086 +            int i = 0;
 15.2087 +            int nBits2 = 32 - nBits;
 15.2088 +            int highBits = mag[0] >>> nBits2;
 15.2089 +            if (highBits != 0) {
 15.2090 +                newMag = new int[magLen + nInts + 1];
 15.2091 +                newMag[i++] = highBits;
 15.2092 +            } else {
 15.2093 +                newMag = new int[magLen + nInts];
 15.2094 +            }
 15.2095 +            int j=0;
 15.2096 +            while (j < magLen-1)
 15.2097 +                newMag[i++] = mag[j++] << nBits | mag[j] >>> nBits2;
 15.2098 +            newMag[i] = mag[j] << nBits;
 15.2099 +        }
 15.2100 +
 15.2101 +        return new BigInteger(newMag, signum);
 15.2102 +    }
 15.2103 +
 15.2104 +    /**
 15.2105 +     * Returns a BigInteger whose value is {@code (this >> n)}.  Sign
 15.2106 +     * extension is performed.  The shift distance, {@code n}, may be
 15.2107 +     * negative, in which case this method performs a left shift.
 15.2108 +     * (Computes <tt>floor(this / 2<sup>n</sup>)</tt>.)
 15.2109 +     *
 15.2110 +     * @param  n shift distance, in bits.
 15.2111 +     * @return {@code this >> n}
 15.2112 +     * @throws ArithmeticException if the shift distance is {@code
 15.2113 +     *         Integer.MIN_VALUE}.
 15.2114 +     * @see #shiftLeft
 15.2115 +     */
 15.2116 +    public BigInteger shiftRight(int n) {
 15.2117 +        if (n==0)
 15.2118 +            return this;
 15.2119 +        if (n<0) {
 15.2120 +            if (n == Integer.MIN_VALUE) {
 15.2121 +                throw new ArithmeticException("Shift distance of Integer.MIN_VALUE not supported.");
 15.2122 +            } else {
 15.2123 +                return shiftLeft(-n);
 15.2124 +            }
 15.2125 +        }
 15.2126 +
 15.2127 +        int nInts = n >>> 5;
 15.2128 +        int nBits = n & 0x1f;
 15.2129 +        int magLen = mag.length;
 15.2130 +        int newMag[] = null;
 15.2131 +
 15.2132 +        // Special case: entire contents shifted off the end
 15.2133 +        if (nInts >= magLen)
 15.2134 +            return (signum >= 0 ? ZERO : negConst[1]);
 15.2135 +
 15.2136 +        if (nBits == 0) {
 15.2137 +            int newMagLen = magLen - nInts;
 15.2138 +            newMag = new int[newMagLen];
 15.2139 +            for (int i=0; i<newMagLen; i++)
 15.2140 +                newMag[i] = mag[i];
 15.2141 +        } else {
 15.2142 +            int i = 0;
 15.2143 +            int highBits = mag[0] >>> nBits;
 15.2144 +            if (highBits != 0) {
 15.2145 +                newMag = new int[magLen - nInts];
 15.2146 +                newMag[i++] = highBits;
 15.2147 +            } else {
 15.2148 +                newMag = new int[magLen - nInts -1];
 15.2149 +            }
 15.2150 +
 15.2151 +            int nBits2 = 32 - nBits;
 15.2152 +            int j=0;
 15.2153 +            while (j < magLen - nInts - 1)
 15.2154 +                newMag[i++] = (mag[j++] << nBits2) | (mag[j] >>> nBits);
 15.2155 +        }
 15.2156 +
 15.2157 +        if (signum < 0) {
 15.2158 +            // Find out whether any one-bits were shifted off the end.
 15.2159 +            boolean onesLost = false;
 15.2160 +            for (int i=magLen-1, j=magLen-nInts; i>=j && !onesLost; i--)
 15.2161 +                onesLost = (mag[i] != 0);
 15.2162 +            if (!onesLost && nBits != 0)
 15.2163 +                onesLost = (mag[magLen - nInts - 1] << (32 - nBits) != 0);
 15.2164 +
 15.2165 +            if (onesLost)
 15.2166 +                newMag = javaIncrement(newMag);
 15.2167 +        }
 15.2168 +
 15.2169 +        return new BigInteger(newMag, signum);
 15.2170 +    }
 15.2171 +
 15.2172 +    int[] javaIncrement(int[] val) {
 15.2173 +        int lastSum = 0;
 15.2174 +        for (int i=val.length-1;  i >= 0 && lastSum == 0; i--)
 15.2175 +            lastSum = (val[i] += 1);
 15.2176 +        if (lastSum == 0) {
 15.2177 +            val = new int[val.length+1];
 15.2178 +            val[0] = 1;
 15.2179 +        }
 15.2180 +        return val;
 15.2181 +    }
 15.2182 +
 15.2183 +    // Bitwise Operations
 15.2184 +
 15.2185 +    /**
 15.2186 +     * Returns a BigInteger whose value is {@code (this & val)}.  (This
 15.2187 +     * method returns a negative BigInteger if and only if this and val are
 15.2188 +     * both negative.)
 15.2189 +     *
 15.2190 +     * @param val value to be AND'ed with this BigInteger.
 15.2191 +     * @return {@code this & val}
 15.2192 +     */
 15.2193 +    public BigInteger and(BigInteger val) {
 15.2194 +        int[] result = new int[Math.max(intLength(), val.intLength())];
 15.2195 +        for (int i=0; i<result.length; i++)
 15.2196 +            result[i] = (getInt(result.length-i-1)
 15.2197 +                         & val.getInt(result.length-i-1));
 15.2198 +
 15.2199 +        return valueOf(result);
 15.2200 +    }
 15.2201 +
 15.2202 +    /**
 15.2203 +     * Returns a BigInteger whose value is {@code (this | val)}.  (This method
 15.2204 +     * returns a negative BigInteger if and only if either this or val is
 15.2205 +     * negative.)
 15.2206 +     *
 15.2207 +     * @param val value to be OR'ed with this BigInteger.
 15.2208 +     * @return {@code this | val}
 15.2209 +     */
 15.2210 +    public BigInteger or(BigInteger val) {
 15.2211 +        int[] result = new int[Math.max(intLength(), val.intLength())];
 15.2212 +        for (int i=0; i<result.length; i++)
 15.2213 +            result[i] = (getInt(result.length-i-1)
 15.2214 +                         | val.getInt(result.length-i-1));
 15.2215 +
 15.2216 +        return valueOf(result);
 15.2217 +    }
 15.2218 +
 15.2219 +    /**
 15.2220 +     * Returns a BigInteger whose value is {@code (this ^ val)}.  (This method
 15.2221 +     * returns a negative BigInteger if and only if exactly one of this and
 15.2222 +     * val are negative.)
 15.2223 +     *
 15.2224 +     * @param val value to be XOR'ed with this BigInteger.
 15.2225 +     * @return {@code this ^ val}
 15.2226 +     */
 15.2227 +    public BigInteger xor(BigInteger val) {
 15.2228 +        int[] result = new int[Math.max(intLength(), val.intLength())];
 15.2229 +        for (int i=0; i<result.length; i++)
 15.2230 +            result[i] = (getInt(result.length-i-1)
 15.2231 +                         ^ val.getInt(result.length-i-1));
 15.2232 +
 15.2233 +        return valueOf(result);
 15.2234 +    }
 15.2235 +
 15.2236 +    /**
 15.2237 +     * Returns a BigInteger whose value is {@code (~this)}.  (This method
 15.2238 +     * returns a negative value if and only if this BigInteger is
 15.2239 +     * non-negative.)
 15.2240 +     *
 15.2241 +     * @return {@code ~this}
 15.2242 +     */
 15.2243 +    public BigInteger not() {
 15.2244 +        int[] result = new int[intLength()];
 15.2245 +        for (int i=0; i<result.length; i++)
 15.2246 +            result[i] = ~getInt(result.length-i-1);
 15.2247 +
 15.2248 +        return valueOf(result);
 15.2249 +    }
 15.2250 +
 15.2251 +    /**
 15.2252 +     * Returns a BigInteger whose value is {@code (this & ~val)}.  This
 15.2253 +     * method, which is equivalent to {@code and(val.not())}, is provided as
 15.2254 +     * a convenience for masking operations.  (This method returns a negative
 15.2255 +     * BigInteger if and only if {@code this} is negative and {@code val} is
 15.2256 +     * positive.)
 15.2257 +     *
 15.2258 +     * @param val value to be complemented and AND'ed with this BigInteger.
 15.2259 +     * @return {@code this & ~val}
 15.2260 +     */
 15.2261 +    public BigInteger andNot(BigInteger val) {
 15.2262 +        int[] result = new int[Math.max(intLength(), val.intLength())];
 15.2263 +        for (int i=0; i<result.length; i++)
 15.2264 +            result[i] = (getInt(result.length-i-1)
 15.2265 +                         & ~val.getInt(result.length-i-1));
 15.2266 +
 15.2267 +        return valueOf(result);
 15.2268 +    }
 15.2269 +
 15.2270 +
 15.2271 +    // Single Bit Operations
 15.2272 +
 15.2273 +    /**
 15.2274 +     * Returns {@code true} if and only if the designated bit is set.
 15.2275 +     * (Computes {@code ((this & (1<<n)) != 0)}.)
 15.2276 +     *
 15.2277 +     * @param  n index of bit to test.
 15.2278 +     * @return {@code true} if and only if the designated bit is set.
 15.2279 +     * @throws ArithmeticException {@code n} is negative.
 15.2280 +     */
 15.2281 +    public boolean testBit(int n) {
 15.2282 +        if (n<0)
 15.2283 +            throw new ArithmeticException("Negative bit address");
 15.2284 +
 15.2285 +        return (getInt(n >>> 5) & (1 << (n & 31))) != 0;
 15.2286 +    }
 15.2287 +
 15.2288 +    /**
 15.2289 +     * Returns a BigInteger whose value is equivalent to this BigInteger
 15.2290 +     * with the designated bit set.  (Computes {@code (this | (1<<n))}.)
 15.2291 +     *
 15.2292 +     * @param  n index of bit to set.
 15.2293 +     * @return {@code this | (1<<n)}
 15.2294 +     * @throws ArithmeticException {@code n} is negative.
 15.2295 +     */
 15.2296 +    public BigInteger setBit(int n) {
 15.2297 +        if (n<0)
 15.2298 +            throw new ArithmeticException("Negative bit address");
 15.2299 +
 15.2300 +        int intNum = n >>> 5;
 15.2301 +        int[] result = new int[Math.max(intLength(), intNum+2)];
 15.2302 +
 15.2303 +        for (int i=0; i<result.length; i++)
 15.2304 +            result[result.length-i-1] = getInt(i);
 15.2305 +
 15.2306 +        result[result.length-intNum-1] |= (1 << (n & 31));
 15.2307 +
 15.2308 +        return valueOf(result);
 15.2309 +    }
 15.2310 +
 15.2311 +    /**
 15.2312 +     * Returns a BigInteger whose value is equivalent to this BigInteger
 15.2313 +     * with the designated bit cleared.
 15.2314 +     * (Computes {@code (this & ~(1<<n))}.)
 15.2315 +     *
 15.2316 +     * @param  n index of bit to clear.
 15.2317 +     * @return {@code this & ~(1<<n)}
 15.2318 +     * @throws ArithmeticException {@code n} is negative.
 15.2319 +     */
 15.2320 +    public BigInteger clearBit(int n) {
 15.2321 +        if (n<0)
 15.2322 +            throw new ArithmeticException("Negative bit address");
 15.2323 +
 15.2324 +        int intNum = n >>> 5;
 15.2325 +        int[] result = new int[Math.max(intLength(), ((n + 1) >>> 5) + 1)];
 15.2326 +
 15.2327 +        for (int i=0; i<result.length; i++)
 15.2328 +            result[result.length-i-1] = getInt(i);
 15.2329 +
 15.2330 +        result[result.length-intNum-1] &= ~(1 << (n & 31));
 15.2331 +
 15.2332 +        return valueOf(result);
 15.2333 +    }
 15.2334 +
 15.2335 +    /**
 15.2336 +     * Returns a BigInteger whose value is equivalent to this BigInteger
 15.2337 +     * with the designated bit flipped.
 15.2338 +     * (Computes {@code (this ^ (1<<n))}.)
 15.2339 +     *
 15.2340 +     * @param  n index of bit to flip.
 15.2341 +     * @return {@code this ^ (1<<n)}
 15.2342 +     * @throws ArithmeticException {@code n} is negative.
 15.2343 +     */
 15.2344 +    public BigInteger flipBit(int n) {
 15.2345 +        if (n<0)
 15.2346 +            throw new ArithmeticException("Negative bit address");
 15.2347 +
 15.2348 +        int intNum = n >>> 5;
 15.2349 +        int[] result = new int[Math.max(intLength(), intNum+2)];
 15.2350 +
 15.2351 +        for (int i=0; i<result.length; i++)
 15.2352 +            result[result.length-i-1] = getInt(i);
 15.2353 +
 15.2354 +        result[result.length-intNum-1] ^= (1 << (n & 31));
 15.2355 +
 15.2356 +        return valueOf(result);
 15.2357 +    }
 15.2358 +
 15.2359 +    /**
 15.2360 +     * Returns the index of the rightmost (lowest-order) one bit in this
 15.2361 +     * BigInteger (the number of zero bits to the right of the rightmost
 15.2362 +     * one bit).  Returns -1 if this BigInteger contains no one bits.
 15.2363 +     * (Computes {@code (this==0? -1 : log2(this & -this))}.)
 15.2364 +     *
 15.2365 +     * @return index of the rightmost one bit in this BigInteger.
 15.2366 +     */
 15.2367 +    public int getLowestSetBit() {
 15.2368 +        @SuppressWarnings("deprecation") int lsb = lowestSetBit - 2;
 15.2369 +        if (lsb == -2) {  // lowestSetBit not initialized yet
 15.2370 +            lsb = 0;
 15.2371 +            if (signum == 0) {
 15.2372 +                lsb -= 1;
 15.2373 +            } else {
 15.2374 +                // Search for lowest order nonzero int
 15.2375 +                int i,b;
 15.2376 +                for (i=0; (b = getInt(i))==0; i++)
 15.2377 +                    ;
 15.2378 +                lsb += (i << 5) + Integer.numberOfTrailingZeros(b);
 15.2379 +            }
 15.2380 +            lowestSetBit = lsb + 2;
 15.2381 +        }
 15.2382 +        return lsb;
 15.2383 +    }
 15.2384 +
 15.2385 +
 15.2386 +    // Miscellaneous Bit Operations
 15.2387 +
 15.2388 +    /**
 15.2389 +     * Returns the number of bits in the minimal two's-complement
 15.2390 +     * representation of this BigInteger, <i>excluding</i> a sign bit.
 15.2391 +     * For positive BigIntegers, this is equivalent to the number of bits in
 15.2392 +     * the ordinary binary representation.  (Computes
 15.2393 +     * {@code (ceil(log2(this < 0 ? -this : this+1)))}.)
 15.2394 +     *
 15.2395 +     * @return number of bits in the minimal two's-complement
 15.2396 +     *         representation of this BigInteger, <i>excluding</i> a sign bit.
 15.2397 +     */
 15.2398 +    public int bitLength() {
 15.2399 +        @SuppressWarnings("deprecation") int n = bitLength - 1;
 15.2400 +        if (n == -1) { // bitLength not initialized yet
 15.2401 +            int[] m = mag;
 15.2402 +            int len = m.length;
 15.2403 +            if (len == 0) {
 15.2404 +                n = 0; // offset by one to initialize
 15.2405 +            }  else {
 15.2406 +                // Calculate the bit length of the magnitude
 15.2407 +                int magBitLength = ((len - 1) << 5) + bitLengthForInt(mag[0]);
 15.2408 +                 if (signum < 0) {
 15.2409 +                     // Check if magnitude is a power of two
 15.2410 +                     boolean pow2 = (Integer.bitCount(mag[0]) == 1);
 15.2411 +                     for(int i=1; i< len && pow2; i++)
 15.2412 +                         pow2 = (mag[i] == 0);
 15.2413 +
 15.2414 +                     n = (pow2 ? magBitLength -1 : magBitLength);
 15.2415 +                 } else {
 15.2416 +                     n = magBitLength;
 15.2417 +                 }
 15.2418 +            }
 15.2419 +            bitLength = n + 1;
 15.2420 +        }
 15.2421 +        return n;
 15.2422 +    }
 15.2423 +
 15.2424 +    /**
 15.2425 +     * Returns the number of bits in the two's complement representation
 15.2426 +     * of this BigInteger that differ from its sign bit.  This method is
 15.2427 +     * useful when implementing bit-vector style sets atop BigIntegers.
 15.2428 +     *
 15.2429 +     * @return number of bits in the two's complement representation
 15.2430 +     *         of this BigInteger that differ from its sign bit.
 15.2431 +     */
 15.2432 +    public int bitCount() {
 15.2433 +        @SuppressWarnings("deprecation") int bc = bitCount - 1;
 15.2434 +        if (bc == -1) {  // bitCount not initialized yet
 15.2435 +            bc = 0;      // offset by one to initialize
 15.2436 +            // Count the bits in the magnitude
 15.2437 +            for (int i=0; i<mag.length; i++)
 15.2438 +                bc += Integer.bitCount(mag[i]);
 15.2439 +            if (signum < 0) {
 15.2440 +                // Count the trailing zeros in the magnitude
 15.2441 +                int magTrailingZeroCount = 0, j;
 15.2442 +                for (j=mag.length-1; mag[j]==0; j--)
 15.2443 +                    magTrailingZeroCount += 32;
 15.2444 +                magTrailingZeroCount += Integer.numberOfTrailingZeros(mag[j]);
 15.2445 +                bc += magTrailingZeroCount - 1;
 15.2446 +            }
 15.2447 +            bitCount = bc + 1;
 15.2448 +        }
 15.2449 +        return bc;
 15.2450 +    }
 15.2451 +
 15.2452 +    // Primality Testing
 15.2453 +
 15.2454 +    /**
 15.2455 +     * Returns {@code true} if this BigInteger is probably prime,
 15.2456 +     * {@code false} if it's definitely composite.  If
 15.2457 +     * {@code certainty} is &le; 0, {@code true} is
 15.2458 +     * returned.
 15.2459 +     *
 15.2460 +     * @param  certainty a measure of the uncertainty that the caller is
 15.2461 +     *         willing to tolerate: if the call returns {@code true}
 15.2462 +     *         the probability that this BigInteger is prime exceeds
 15.2463 +     *         (1 - 1/2<sup>{@code certainty}</sup>).  The execution time of
 15.2464 +     *         this method is proportional to the value of this parameter.
 15.2465 +     * @return {@code true} if this BigInteger is probably prime,
 15.2466 +     *         {@code false} if it's definitely composite.
 15.2467 +     */
 15.2468 +    public boolean isProbablePrime(int certainty) {
 15.2469 +        if (certainty <= 0)
 15.2470 +            return true;
 15.2471 +        BigInteger w = this.abs();
 15.2472 +        if (w.equals(TWO))
 15.2473 +            return true;
 15.2474 +        if (!w.testBit(0) || w.equals(ONE))
 15.2475 +            return false;
 15.2476 +
 15.2477 +        return w.primeToCertainty(certainty, null);
 15.2478 +    }
 15.2479 +
 15.2480 +    // Comparison Operations
 15.2481 +
 15.2482 +    /**
 15.2483 +     * Compares this BigInteger with the specified BigInteger.  This
 15.2484 +     * method is provided in preference to individual methods for each
 15.2485 +     * of the six boolean comparison operators ({@literal <}, ==,
 15.2486 +     * {@literal >}, {@literal >=}, !=, {@literal <=}).  The suggested
 15.2487 +     * idiom for performing these comparisons is: {@code
 15.2488 +     * (x.compareTo(y)} &lt;<i>op</i>&gt; {@code 0)}, where
 15.2489 +     * &lt;<i>op</i>&gt; is one of the six comparison operators.
 15.2490 +     *
 15.2491 +     * @param  val BigInteger to which this BigInteger is to be compared.
 15.2492 +     * @return -1, 0 or 1 as this BigInteger is numerically less than, equal
 15.2493 +     *         to, or greater than {@code val}.
 15.2494 +     */
 15.2495 +    public int compareTo(BigInteger val) {
 15.2496 +        if (signum == val.signum) {
 15.2497 +            switch (signum) {
 15.2498 +            case 1:
 15.2499 +                return compareMagnitude(val);
 15.2500 +            case -1:
 15.2501 +                return val.compareMagnitude(this);
 15.2502 +            default:
 15.2503 +                return 0;
 15.2504 +            }
 15.2505 +        }
 15.2506 +        return signum > val.signum ? 1 : -1;
 15.2507 +    }
 15.2508 +
 15.2509 +    /**
 15.2510 +     * Compares the magnitude array of this BigInteger with the specified
 15.2511 +     * BigInteger's. This is the version of compareTo ignoring sign.
 15.2512 +     *
 15.2513 +     * @param val BigInteger whose magnitude array to be compared.
 15.2514 +     * @return -1, 0 or 1 as this magnitude array is less than, equal to or
 15.2515 +     *         greater than the magnitude aray for the specified BigInteger's.
 15.2516 +     */
 15.2517 +    final int compareMagnitude(BigInteger val) {
 15.2518 +        int[] m1 = mag;
 15.2519 +        int len1 = m1.length;
 15.2520 +        int[] m2 = val.mag;
 15.2521 +        int len2 = m2.length;
 15.2522 +        if (len1 < len2)
 15.2523 +            return -1;
 15.2524 +        if (len1 > len2)
 15.2525 +            return 1;
 15.2526 +        for (int i = 0; i < len1; i++) {
 15.2527 +            int a = m1[i];
 15.2528 +            int b = m2[i];
 15.2529 +            if (a != b)
 15.2530 +                return ((a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1;
 15.2531 +        }
 15.2532 +        return 0;
 15.2533 +    }
 15.2534 +
 15.2535 +    /**
 15.2536 +     * Compares this BigInteger with the specified Object for equality.
 15.2537 +     *
 15.2538 +     * @param  x Object to which this BigInteger is to be compared.
 15.2539 +     * @return {@code true} if and only if the specified Object is a
 15.2540 +     *         BigInteger whose value is numerically equal to this BigInteger.
 15.2541 +     */
 15.2542 +    public boolean equals(Object x) {
 15.2543 +        // This test is just an optimization, which may or may not help
 15.2544 +        if (x == this)
 15.2545 +            return true;
 15.2546 +
 15.2547 +        if (!(x instanceof BigInteger))
 15.2548 +            return false;
 15.2549 +
 15.2550 +        BigInteger xInt = (BigInteger) x;
 15.2551 +        if (xInt.signum != signum)
 15.2552 +            return false;
 15.2553 +
 15.2554 +        int[] m = mag;
 15.2555 +        int len = m.length;
 15.2556 +        int[] xm = xInt.mag;
 15.2557 +        if (len != xm.length)
 15.2558 +            return false;
 15.2559 +
 15.2560 +        for (int i = 0; i < len; i++)
 15.2561 +            if (xm[i] != m[i])
 15.2562 +                return false;
 15.2563 +
 15.2564 +        return true;
 15.2565 +    }
 15.2566 +
 15.2567 +    /**
 15.2568 +     * Returns the minimum of this BigInteger and {@code val}.
 15.2569 +     *
 15.2570 +     * @param  val value with which the minimum is to be computed.
 15.2571 +     * @return the BigInteger whose value is the lesser of this BigInteger and
 15.2572 +     *         {@code val}.  If they are equal, either may be returned.
 15.2573 +     */
 15.2574 +    public BigInteger min(BigInteger val) {
 15.2575 +        return (compareTo(val)<0 ? this : val);
 15.2576 +    }
 15.2577 +
 15.2578 +    /**
 15.2579 +     * Returns the maximum of this BigInteger and {@code val}.
 15.2580 +     *
 15.2581 +     * @param  val value with which the maximum is to be computed.
 15.2582 +     * @return the BigInteger whose value is the greater of this and
 15.2583 +     *         {@code val}.  If they are equal, either may be returned.
 15.2584 +     */
 15.2585 +    public BigInteger max(BigInteger val) {
 15.2586 +        return (compareTo(val)>0 ? this : val);
 15.2587 +    }
 15.2588 +
 15.2589 +
 15.2590 +    // Hash Function
 15.2591 +
 15.2592 +    /**
 15.2593 +     * Returns the hash code for this BigInteger.
 15.2594 +     *
 15.2595 +     * @return hash code for this BigInteger.
 15.2596 +     */
 15.2597 +    public int hashCode() {
 15.2598 +        int hashCode = 0;
 15.2599 +
 15.2600 +        for (int i=0; i<mag.length; i++)
 15.2601 +            hashCode = (int)(31*hashCode + (mag[i] & LONG_MASK));
 15.2602 +
 15.2603 +        return hashCode * signum;
 15.2604 +    }
 15.2605 +
 15.2606 +    /**
 15.2607 +     * Returns the String representation of this BigInteger in the
 15.2608 +     * given radix.  If the radix is outside the range from {@link
 15.2609 +     * Character#MIN_RADIX} to {@link Character#MAX_RADIX} inclusive,
 15.2610 +     * it will default to 10 (as is the case for
 15.2611 +     * {@code Integer.toString}).  The digit-to-character mapping
 15.2612 +     * provided by {@code Character.forDigit} is used, and a minus
 15.2613 +     * sign is prepended if appropriate.  (This representation is
 15.2614 +     * compatible with the {@link #BigInteger(String, int) (String,
 15.2615 +     * int)} constructor.)
 15.2616 +     *
 15.2617 +     * @param  radix  radix of the String representation.
 15.2618 +     * @return String representation of this BigInteger in the given radix.
 15.2619 +     * @see    Integer#toString
 15.2620 +     * @see    Character#forDigit
 15.2621 +     * @see    #BigInteger(java.lang.String, int)
 15.2622 +     */
 15.2623 +    public String toString(int radix) {
 15.2624 +        if (signum == 0)
 15.2625 +            return "0";
 15.2626 +        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
 15.2627 +            radix = 10;
 15.2628 +
 15.2629 +        // Compute upper bound on number of digit groups and allocate space
 15.2630 +        int maxNumDigitGroups = (4*mag.length + 6)/7;
 15.2631 +        String digitGroup[] = new String[maxNumDigitGroups];
 15.2632 +
 15.2633 +        // Translate number to string, a digit group at a time
 15.2634 +        BigInteger tmp = this.abs();
 15.2635 +        int numGroups = 0;
 15.2636 +        while (tmp.signum != 0) {
 15.2637 +            BigInteger d = longRadix[radix];
 15.2638 +
 15.2639 +            MutableBigInteger q = new MutableBigInteger(),
 15.2640 +                              a = new MutableBigInteger(tmp.mag),
 15.2641 +                              b = new MutableBigInteger(d.mag);
 15.2642 +            MutableBigInteger r = a.divide(b, q);
 15.2643 +            BigInteger q2 = q.toBigInteger(tmp.signum * d.signum);
 15.2644 +            BigInteger r2 = r.toBigInteger(tmp.signum * d.signum);
 15.2645 +
 15.2646 +            digitGroup[numGroups++] = Long.toString(r2.longValue(), radix);
 15.2647 +            tmp = q2;
 15.2648 +        }
 15.2649 +
 15.2650 +        // Put sign (if any) and first digit group into result buffer
 15.2651 +        StringBuilder buf = new StringBuilder(numGroups*digitsPerLong[radix]+1);
 15.2652 +        if (signum<0)
 15.2653 +            buf.append('-');
 15.2654 +        buf.append(digitGroup[numGroups-1]);
 15.2655 +
 15.2656 +        // Append remaining digit groups padded with leading zeros
 15.2657 +        for (int i=numGroups-2; i>=0; i--) {
 15.2658 +            // Prepend (any) leading zeros for this digit group
 15.2659 +            int numLeadingZeros = digitsPerLong[radix]-digitGroup[i].length();
 15.2660 +            if (numLeadingZeros != 0)
 15.2661 +                buf.append(zeros[numLeadingZeros]);
 15.2662 +            buf.append(digitGroup[i]);
 15.2663 +        }
 15.2664 +        return buf.toString();
 15.2665 +    }
 15.2666 +
 15.2667 +    /* zero[i] is a string of i consecutive zeros. */
 15.2668 +    private static String zeros[] = new String[64];
 15.2669 +    static {
 15.2670 +        zeros[63] =
 15.2671 +            "000000000000000000000000000000000000000000000000000000000000000";
 15.2672 +        for (int i=0; i<63; i++)
 15.2673 +            zeros[i] = zeros[63].substring(0, i);
 15.2674 +    }
 15.2675 +
 15.2676 +    /**
 15.2677 +     * Returns the decimal String representation of this BigInteger.
 15.2678 +     * The digit-to-character mapping provided by
 15.2679 +     * {@code Character.forDigit} is used, and a minus sign is
 15.2680 +     * prepended if appropriate.  (This representation is compatible
 15.2681 +     * with the {@link #BigInteger(String) (String)} constructor, and
 15.2682 +     * allows for String concatenation with Java's + operator.)
 15.2683 +     *
 15.2684 +     * @return decimal String representation of this BigInteger.
 15.2685 +     * @see    Character#forDigit
 15.2686 +     * @see    #BigInteger(java.lang.String)
 15.2687 +     */
 15.2688 +    public String toString() {
 15.2689 +        return toString(10);
 15.2690 +    }
 15.2691 +
 15.2692 +    /**
 15.2693 +     * Returns a byte array containing the two's-complement
 15.2694 +     * representation of this BigInteger.  The byte array will be in
 15.2695 +     * <i>big-endian</i> byte-order: the most significant byte is in
 15.2696 +     * the zeroth element.  The array will contain the minimum number
 15.2697 +     * of bytes required to represent this BigInteger, including at
 15.2698 +     * least one sign bit, which is {@code (ceil((this.bitLength() +
 15.2699 +     * 1)/8))}.  (This representation is compatible with the
 15.2700 +     * {@link #BigInteger(byte[]) (byte[])} constructor.)
 15.2701 +     *
 15.2702 +     * @return a byte array containing the two's-complement representation of
 15.2703 +     *         this BigInteger.
 15.2704 +     * @see    #BigInteger(byte[])
 15.2705 +     */
 15.2706 +    public byte[] toByteArray() {
 15.2707 +        int byteLen = bitLength()/8 + 1;
 15.2708 +        byte[] byteArray = new byte[byteLen];
 15.2709 +
 15.2710 +        for (int i=byteLen-1, bytesCopied=4, nextInt=0, intIndex=0; i>=0; i--) {
 15.2711 +            if (bytesCopied == 4) {
 15.2712 +                nextInt = getInt(intIndex++);
 15.2713 +                bytesCopied = 1;
 15.2714 +            } else {
 15.2715 +                nextInt >>>= 8;
 15.2716 +                bytesCopied++;
 15.2717 +            }
 15.2718 +            byteArray[i] = (byte)nextInt;
 15.2719 +        }
 15.2720 +        return byteArray;
 15.2721 +    }
 15.2722 +
 15.2723 +    /**
 15.2724 +     * Converts this BigInteger to an {@code int}.  This
 15.2725 +     * conversion is analogous to a
 15.2726 +     * <i>narrowing primitive conversion</i> from {@code long} to
 15.2727 +     * {@code int} as defined in section 5.1.3 of
 15.2728 +     * <cite>The Java&trade; Language Specification</cite>:
 15.2729 +     * if this BigInteger is too big to fit in an
 15.2730 +     * {@code int}, only the low-order 32 bits are returned.
 15.2731 +     * Note that this conversion can lose information about the
 15.2732 +     * overall magnitude of the BigInteger value as well as return a
 15.2733 +     * result with the opposite sign.
 15.2734 +     *
 15.2735 +     * @return this BigInteger converted to an {@code int}.
 15.2736 +     */
 15.2737 +    public int intValue() {
 15.2738 +        int result = 0;
 15.2739 +        result = getInt(0);
 15.2740 +        return result;
 15.2741 +    }
 15.2742 +
 15.2743 +    /**
 15.2744 +     * Converts this BigInteger to a {@code long}.  This
 15.2745 +     * conversion is analogous to a
 15.2746 +     * <i>narrowing primitive conversion</i> from {@code long} to
 15.2747 +     * {@code int} as defined in section 5.1.3 of
 15.2748 +     * <cite>The Java&trade; Language Specification</cite>:
 15.2749 +     * if this BigInteger is too big to fit in a
 15.2750 +     * {@code long}, only the low-order 64 bits are returned.
 15.2751 +     * Note that this conversion can lose information about the
 15.2752 +     * overall magnitude of the BigInteger value as well as return a
 15.2753 +     * result with the opposite sign.
 15.2754 +     *
 15.2755 +     * @return this BigInteger converted to a {@code long}.
 15.2756 +     */
 15.2757 +    public long longValue() {
 15.2758 +        long result = 0;
 15.2759 +
 15.2760 +        for (int i=1; i>=0; i--)
 15.2761 +            result = (result << 32) + (getInt(i) & LONG_MASK);
 15.2762 +        return result;
 15.2763 +    }
 15.2764 +
 15.2765 +    /**
 15.2766 +     * Converts this BigInteger to a {@code float}.  This
 15.2767 +     * conversion is similar to the
 15.2768 +     * <i>narrowing primitive conversion</i> from {@code double} to
 15.2769 +     * {@code float} as defined in section 5.1.3 of
 15.2770 +     * <cite>The Java&trade; Language Specification</cite>:
 15.2771 +     * if this BigInteger has too great a magnitude
 15.2772 +     * to represent as a {@code float}, it will be converted to
 15.2773 +     * {@link Float#NEGATIVE_INFINITY} or {@link
 15.2774 +     * Float#POSITIVE_INFINITY} as appropriate.  Note that even when
 15.2775 +     * the return value is finite, this conversion can lose
 15.2776 +     * information about the precision of the BigInteger value.
 15.2777 +     *
 15.2778 +     * @return this BigInteger converted to a {@code float}.
 15.2779 +     */
 15.2780 +    public float floatValue() {
 15.2781 +        // Somewhat inefficient, but guaranteed to work.
 15.2782 +        return Float.parseFloat(this.toString());
 15.2783 +    }
 15.2784 +
 15.2785 +    /**
 15.2786 +     * Converts this BigInteger to a {@code double}.  This
 15.2787 +     * conversion is similar to the
 15.2788 +     * <i>narrowing primitive conversion</i> from {@code double} to
 15.2789 +     * {@code float} as defined in section 5.1.3 of
 15.2790 +     * <cite>The Java&trade; Language Specification</cite>:
 15.2791 +     * if this BigInteger has too great a magnitude
 15.2792 +     * to represent as a {@code double}, it will be converted to
 15.2793 +     * {@link Double#NEGATIVE_INFINITY} or {@link
 15.2794 +     * Double#POSITIVE_INFINITY} as appropriate.  Note that even when
 15.2795 +     * the return value is finite, this conversion can lose
 15.2796 +     * information about the precision of the BigInteger value.
 15.2797 +     *
 15.2798 +     * @return this BigInteger converted to a {@code double}.
 15.2799 +     */
 15.2800 +    public double doubleValue() {
 15.2801 +        // Somewhat inefficient, but guaranteed to work.
 15.2802 +        return Double.parseDouble(this.toString());
 15.2803 +    }
 15.2804 +
 15.2805 +    /**
 15.2806 +     * Returns a copy of the input array stripped of any leading zero bytes.
 15.2807 +     */
 15.2808 +    private static int[] stripLeadingZeroInts(int val[]) {
 15.2809 +        int vlen = val.length;
 15.2810 +        int keep;
 15.2811 +
 15.2812 +        // Find first nonzero byte
 15.2813 +        for (keep = 0; keep < vlen && val[keep] == 0; keep++)
 15.2814 +            ;
 15.2815 +        return java.util.Arrays.copyOfRange(val, keep, vlen);
 15.2816 +    }
 15.2817 +
 15.2818 +    /**
 15.2819 +     * Returns the input array stripped of any leading zero bytes.
 15.2820 +     * Since the source is trusted the copying may be skipped.
 15.2821 +     */
 15.2822 +    private static int[] trustedStripLeadingZeroInts(int val[]) {
 15.2823 +        int vlen = val.length;
 15.2824 +        int keep;
 15.2825 +
 15.2826 +        // Find first nonzero byte
 15.2827 +        for (keep = 0; keep < vlen && val[keep] == 0; keep++)
 15.2828 +            ;
 15.2829 +        return keep == 0 ? val : java.util.Arrays.copyOfRange(val, keep, vlen);
 15.2830 +    }
 15.2831 +
 15.2832 +    /**
 15.2833 +     * Returns a copy of the input array stripped of any leading zero bytes.
 15.2834 +     */
 15.2835 +    private static int[] stripLeadingZeroBytes(byte a[]) {
 15.2836 +        int byteLength = a.length;
 15.2837 +        int keep;
 15.2838 +
 15.2839 +        // Find first nonzero byte
 15.2840 +        for (keep = 0; keep < byteLength && a[keep]==0; keep++)
 15.2841 +            ;
 15.2842 +
 15.2843 +        // Allocate new array and copy relevant part of input array
 15.2844 +        int intLength = ((byteLength - keep) + 3) >>> 2;
 15.2845 +        int[] result = new int[intLength];
 15.2846 +        int b = byteLength - 1;
 15.2847 +        for (int i = intLength-1; i >= 0; i--) {
 15.2848 +            result[i] = a[b--] & 0xff;
 15.2849 +            int bytesRemaining = b - keep + 1;
 15.2850 +            int bytesToTransfer = Math.min(3, bytesRemaining);
 15.2851 +            for (int j=8; j <= (bytesToTransfer << 3); j += 8)
 15.2852 +                result[i] |= ((a[b--] & 0xff) << j);
 15.2853 +        }
 15.2854 +        return result;
 15.2855 +    }
 15.2856 +
 15.2857 +    /**
 15.2858 +     * Takes an array a representing a negative 2's-complement number and
 15.2859 +     * returns the minimal (no leading zero bytes) unsigned whose value is -a.
 15.2860 +     */
 15.2861 +    private static int[] makePositive(byte a[]) {
 15.2862 +        int keep, k;
 15.2863 +        int byteLength = a.length;
 15.2864 +
 15.2865 +        // Find first non-sign (0xff) byte of input
 15.2866 +        for (keep=0; keep<byteLength && a[keep]==-1; keep++)
 15.2867 +            ;
 15.2868 +
 15.2869 +
 15.2870 +        /* Allocate output array.  If all non-sign bytes are 0x00, we must
 15.2871 +         * allocate space for one extra output byte. */
 15.2872 +        for (k=keep; k<byteLength && a[k]==0; k++)
 15.2873 +            ;
 15.2874 +
 15.2875 +        int extraByte = (k==byteLength) ? 1 : 0;
 15.2876 +        int intLength = ((byteLength - keep + extraByte) + 3)/4;
 15.2877 +        int result[] = new int[intLength];
 15.2878 +
 15.2879 +        /* Copy one's complement of input into output, leaving extra
 15.2880 +         * byte (if it exists) == 0x00 */
 15.2881 +        int b = byteLength - 1;
 15.2882 +        for (int i = intLength-1; i >= 0; i--) {
 15.2883 +            result[i] = a[b--] & 0xff;
 15.2884 +            int numBytesToTransfer = Math.min(3, b-keep+1);
 15.2885 +            if (numBytesToTransfer < 0)
 15.2886 +                numBytesToTransfer = 0;
 15.2887 +            for (int j=8; j <= 8*numBytesToTransfer; j += 8)
 15.2888 +                result[i] |= ((a[b--] & 0xff) << j);
 15.2889 +
 15.2890 +            // Mask indicates which bits must be complemented
 15.2891 +            int mask = -1 >>> (8*(3-numBytesToTransfer));
 15.2892 +            result[i] = ~result[i] & mask;
 15.2893 +        }
 15.2894 +
 15.2895 +        // Add one to one's complement to generate two's complement
 15.2896 +        for (int i=result.length-1; i>=0; i--) {
 15.2897 +            result[i] = (int)((result[i] & LONG_MASK) + 1);
 15.2898 +            if (result[i] != 0)
 15.2899 +                break;
 15.2900 +        }
 15.2901 +
 15.2902 +        return result;
 15.2903 +    }
 15.2904 +
 15.2905 +    /**
 15.2906 +     * Takes an array a representing a negative 2's-complement number and
 15.2907 +     * returns the minimal (no leading zero ints) unsigned whose value is -a.
 15.2908 +     */
 15.2909 +    private static int[] makePositive(int a[]) {
 15.2910 +        int keep, j;
 15.2911 +
 15.2912 +        // Find first non-sign (0xffffffff) int of input
 15.2913 +        for (keep=0; keep<a.length && a[keep]==-1; keep++)
 15.2914 +            ;
 15.2915 +
 15.2916 +        /* Allocate output array.  If all non-sign ints are 0x00, we must
 15.2917 +         * allocate space for one extra output int. */
 15.2918 +        for (j=keep; j<a.length && a[j]==0; j++)
 15.2919 +            ;
 15.2920 +        int extraInt = (j==a.length ? 1 : 0);
 15.2921 +        int result[] = new int[a.length - keep + extraInt];
 15.2922 +
 15.2923 +        /* Copy one's complement of input into output, leaving extra
 15.2924 +         * int (if it exists) == 0x00 */
 15.2925 +        for (int i = keep; i<a.length; i++)
 15.2926 +            result[i - keep + extraInt] = ~a[i];
 15.2927 +
 15.2928 +        // Add one to one's complement to generate two's complement
 15.2929 +        for (int i=result.length-1; ++result[i]==0; i--)
 15.2930 +            ;
 15.2931 +
 15.2932 +        return result;
 15.2933 +    }
 15.2934 +
 15.2935 +    /*
 15.2936 +     * The following two arrays are used for fast String conversions.  Both
 15.2937 +     * are indexed by radix.  The first is the number of digits of the given
 15.2938 +     * radix that can fit in a Java long without "going negative", i.e., the
 15.2939 +     * highest integer n such that radix**n < 2**63.  The second is the
 15.2940 +     * "long radix" that tears each number into "long digits", each of which
 15.2941 +     * consists of the number of digits in the corresponding element in
 15.2942 +     * digitsPerLong (longRadix[i] = i**digitPerLong[i]).  Both arrays have
 15.2943 +     * nonsense values in their 0 and 1 elements, as radixes 0 and 1 are not
 15.2944 +     * used.
 15.2945 +     */
 15.2946 +    private static int digitsPerLong[] = {0, 0,
 15.2947 +        62, 39, 31, 27, 24, 22, 20, 19, 18, 18, 17, 17, 16, 16, 15, 15, 15, 14,
 15.2948 +        14, 14, 14, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 12};
 15.2949 +
 15.2950 +    private static BigInteger longRadix[] = {null, null,
 15.2951 +        valueOf(0x4000000000000000L), valueOf(0x383d9170b85ff80bL),
 15.2952 +        valueOf(0x4000000000000000L), valueOf(0x6765c793fa10079dL),
 15.2953 +        valueOf(0x41c21cb8e1000000L), valueOf(0x3642798750226111L),
 15.2954 +        valueOf(0x1000000000000000L), valueOf(0x12bf307ae81ffd59L),
 15.2955 +        valueOf( 0xde0b6b3a7640000L), valueOf(0x4d28cb56c33fa539L),
 15.2956 +        valueOf(0x1eca170c00000000L), valueOf(0x780c7372621bd74dL),
 15.2957 +        valueOf(0x1e39a5057d810000L), valueOf(0x5b27ac993df97701L),
 15.2958 +        valueOf(0x1000000000000000L), valueOf(0x27b95e997e21d9f1L),
 15.2959 +        valueOf(0x5da0e1e53c5c8000L), valueOf( 0xb16a458ef403f19L),
 15.2960 +        valueOf(0x16bcc41e90000000L), valueOf(0x2d04b7fdd9c0ef49L),
 15.2961 +        valueOf(0x5658597bcaa24000L), valueOf( 0x6feb266931a75b7L),
 15.2962 +        valueOf( 0xc29e98000000000L), valueOf(0x14adf4b7320334b9L),
 15.2963 +        valueOf(0x226ed36478bfa000L), valueOf(0x383d9170b85ff80bL),
 15.2964 +        valueOf(0x5a3c23e39c000000L), valueOf( 0x4e900abb53e6b71L),
 15.2965 +        valueOf( 0x7600ec618141000L), valueOf( 0xaee5720ee830681L),
 15.2966 +        valueOf(0x1000000000000000L), valueOf(0x172588ad4f5f0981L),
 15.2967 +        valueOf(0x211e44f7d02c1000L), valueOf(0x2ee56725f06e5c71L),
 15.2968 +        valueOf(0x41c21cb8e1000000L)};
 15.2969 +
 15.2970 +    /*
 15.2971 +     * These two arrays are the integer analogue of above.
 15.2972 +     */
 15.2973 +    private static int digitsPerInt[] = {0, 0, 30, 19, 15, 13, 11,
 15.2974 +        11, 10, 9, 9, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6,
 15.2975 +        6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5};
 15.2976 +
 15.2977 +    private static int intRadix[] = {0, 0,
 15.2978 +        0x40000000, 0x4546b3db, 0x40000000, 0x48c27395, 0x159fd800,
 15.2979 +        0x75db9c97, 0x40000000, 0x17179149, 0x3b9aca00, 0xcc6db61,
 15.2980 +        0x19a10000, 0x309f1021, 0x57f6c100, 0xa2f1b6f,  0x10000000,
 15.2981 +        0x18754571, 0x247dbc80, 0x3547667b, 0x4c4b4000, 0x6b5a6e1d,
 15.2982 +        0x6c20a40,  0x8d2d931,  0xb640000,  0xe8d4a51,  0x1269ae40,
 15.2983 +        0x17179149, 0x1cb91000, 0x23744899, 0x2b73a840, 0x34e63b41,
 15.2984 +        0x40000000, 0x4cfa3cc1, 0x5c13d840, 0x6d91b519, 0x39aa400
 15.2985 +    };
 15.2986 +
 15.2987 +    /**
 15.2988 +     * These routines provide access to the two's complement representation
 15.2989 +     * of BigIntegers.
 15.2990 +     */
 15.2991 +
 15.2992 +    /**
 15.2993 +     * Returns the length of the two's complement representation in ints,
 15.2994 +     * including space for at least one sign bit.
 15.2995 +     */
 15.2996 +    private int intLength() {
 15.2997 +        return (bitLength() >>> 5) + 1;
 15.2998 +    }
 15.2999 +
 15.3000 +    /* Returns sign bit */
 15.3001 +    private int signBit() {
 15.3002 +        return signum < 0 ? 1 : 0;
 15.3003 +    }
 15.3004 +
 15.3005 +    /* Returns an int of sign bits */
 15.3006 +    private int signInt() {
 15.3007 +        return signum < 0 ? -1 : 0;
 15.3008 +    }
 15.3009 +
 15.3010 +    /**
 15.3011 +     * Returns the specified int of the little-endian two's complement
 15.3012 +     * representation (int 0 is the least significant).  The int number can
 15.3013 +     * be arbitrarily high (values are logically preceded by infinitely many
 15.3014 +     * sign ints).
 15.3015 +     */
 15.3016 +    private int getInt(int n) {
 15.3017 +        if (n < 0)
 15.3018 +            return 0;
 15.3019 +        if (n >= mag.length)
 15.3020 +            return signInt();
 15.3021 +
 15.3022 +        int magInt = mag[mag.length-n-1];
 15.3023 +
 15.3024 +        return (signum >= 0 ? magInt :
 15.3025 +                (n <= firstNonzeroIntNum() ? -magInt : ~magInt));
 15.3026 +    }
 15.3027 +
 15.3028 +    /**
 15.3029 +     * Returns the index of the int that contains the first nonzero int in the
 15.3030 +     * little-endian binary representation of the magnitude (int 0 is the
 15.3031 +     * least significant). If the magnitude is zero, return value is undefined.
 15.3032 +     */
 15.3033 +     private int firstNonzeroIntNum() {
 15.3034 +         int fn = firstNonzeroIntNum - 2;
 15.3035 +         if (fn == -2) { // firstNonzeroIntNum not initialized yet
 15.3036 +             fn = 0;
 15.3037 +
 15.3038 +             // Search for the first nonzero int
 15.3039 +             int i;
 15.3040 +             int mlen = mag.length;
 15.3041 +             for (i = mlen - 1; i >= 0 && mag[i] == 0; i--)
 15.3042 +                 ;
 15.3043 +             fn = mlen - i - 1;
 15.3044 +             firstNonzeroIntNum = fn + 2; // offset by two to initialize
 15.3045 +         }
 15.3046 +         return fn;
 15.3047 +     }
 15.3048 +
 15.3049 +    /** use serialVersionUID from JDK 1.1. for interoperability */
 15.3050 +    private static final long serialVersionUID = -8287574255936472291L;
 15.3051 +
 15.3052 +    /**
 15.3053 +     * Serializable fields for BigInteger.
 15.3054 +     *
 15.3055 +     * @serialField signum  int
 15.3056 +     *              signum of this BigInteger.
 15.3057 +     * @serialField magnitude int[]
 15.3058 +     *              magnitude array of this BigInteger.
 15.3059 +     * @serialField bitCount  int
 15.3060 +     *              number of bits in this BigInteger
 15.3061 +     * @serialField bitLength int
 15.3062 +     *              the number of bits in the minimal two's-complement
 15.3063 +     *              representation of this BigInteger
 15.3064 +     * @serialField lowestSetBit int
 15.3065 +     *              lowest set bit in the twos complement representation
 15.3066 +     */
 15.3067 +    private static final ObjectStreamField[] serialPersistentFields = {
 15.3068 +        new ObjectStreamField("signum", Integer.TYPE),
 15.3069 +        new ObjectStreamField("magnitude", byte[].class),
 15.3070 +        new ObjectStreamField("bitCount", Integer.TYPE),
 15.3071 +        new ObjectStreamField("bitLength", Integer.TYPE),
 15.3072 +        new ObjectStreamField("firstNonzeroByteNum", Integer.TYPE),
 15.3073 +        new ObjectStreamField("lowestSetBit", Integer.TYPE)
 15.3074 +        };
 15.3075 +
 15.3076 +    /**
 15.3077 +     * Reconstitute the {@code BigInteger} instance from a stream (that is,
 15.3078 +     * deserialize it). The magnitude is read in as an array of bytes
 15.3079 +     * for historical reasons, but it is converted to an array of ints
 15.3080 +     * and the byte array is discarded.
 15.3081 +     * Note:
 15.3082 +     * The current convention is to initialize the cache fields, bitCount,
 15.3083 +     * bitLength and lowestSetBit, to 0 rather than some other marker value.
 15.3084 +     * Therefore, no explicit action to set these fields needs to be taken in
 15.3085 +     * readObject because those fields already have a 0 value be default since
 15.3086 +     * defaultReadObject is not being used.
 15.3087 +     */
 15.3088 +    private void readObject(java.io.ObjectInputStream s)
 15.3089 +        throws java.io.IOException, ClassNotFoundException {
 15.3090 +        /*
 15.3091 +         * In order to maintain compatibility with previous serialized forms,
 15.3092 +         * the magnitude of a BigInteger is serialized as an array of bytes.
 15.3093 +         * The magnitude field is used as a temporary store for the byte array
 15.3094 +         * that is deserialized. The cached computation fields should be
 15.3095 +         * transient but are serialized for compatibility reasons.
 15.3096 +         */
 15.3097 +
 15.3098 +        // prepare to read the alternate persistent fields
 15.3099 +        ObjectInputStream.GetField fields = s.readFields();
 15.3100 +
 15.3101 +        // Read the alternate persistent fields that we care about
 15.3102 +        int sign = fields.get("signum", -2);
 15.3103 +        byte[] magnitude = (byte[])fields.get("magnitude", null);
 15.3104 +
 15.3105 +        // Validate signum
 15.3106 +        if (sign < -1 || sign > 1) {
 15.3107 +            String message = "BigInteger: Invalid signum value";
 15.3108 +            if (fields.defaulted("signum"))
 15.3109 +                message = "BigInteger: Signum not present in stream";
 15.3110 +            throw new java.io.StreamCorruptedException(message);
 15.3111 +        }
 15.3112 +        if ((magnitude.length == 0) != (sign == 0)) {
 15.3113 +            String message = "BigInteger: signum-magnitude mismatch";
 15.3114 +            if (fields.defaulted("magnitude"))
 15.3115 +                message = "BigInteger: Magnitude not present in stream";
 15.3116 +            throw new java.io.StreamCorruptedException(message);
 15.3117 +        }
 15.3118 +
 15.3119 +        // Commit final fields via Unsafe
 15.3120 +        unsafe.putIntVolatile(this, signumOffset, sign);
 15.3121 +
 15.3122 +        // Calculate mag field from magnitude and discard magnitude
 15.3123 +        unsafe.putObjectVolatile(this, magOffset,
 15.3124 +                                 stripLeadingZeroBytes(magnitude));
 15.3125 +    }
 15.3126 +
 15.3127 +    // Support for resetting final fields while deserializing
 15.3128 +    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
 15.3129 +    private static final long signumOffset;
 15.3130 +    private static final long magOffset;
 15.3131 +    static {
 15.3132 +        try {
 15.3133 +            signumOffset = unsafe.objectFieldOffset
 15.3134 +                (BigInteger.class.getDeclaredField("signum"));
 15.3135 +            magOffset = unsafe.objectFieldOffset
 15.3136 +                (BigInteger.class.getDeclaredField("mag"));
 15.3137 +        } catch (Exception ex) {
 15.3138 +            throw new Error(ex);
 15.3139 +        }
 15.3140 +    }
 15.3141 +
 15.3142 +    /**
 15.3143 +     * Save the {@code BigInteger} instance to a stream.
 15.3144 +     * The magnitude of a BigInteger is serialized as a byte array for
 15.3145 +     * historical reasons.
 15.3146 +     *
 15.3147 +     * @serialData two necessary fields are written as well as obsolete
 15.3148 +     *             fields for compatibility with older versions.
 15.3149 +     */
 15.3150 +    private void writeObject(ObjectOutputStream s) throws IOException {
 15.3151 +        // set the values of the Serializable fields
 15.3152 +        ObjectOutputStream.PutField fields = s.putFields();
 15.3153 +        fields.put("signum", signum);
 15.3154 +        fields.put("magnitude", magSerializedForm());
 15.3155 +        // The values written for cached fields are compatible with older
 15.3156 +        // versions, but are ignored in readObject so don't otherwise matter.
 15.3157 +        fields.put("bitCount", -1);
 15.3158 +        fields.put("bitLength", -1);
 15.3159 +        fields.put("lowestSetBit", -2);
 15.3160 +        fields.put("firstNonzeroByteNum", -2);
 15.3161 +
 15.3162 +        // save them
 15.3163 +        s.writeFields();
 15.3164 +}
 15.3165 +
 15.3166 +    /**
 15.3167 +     * Returns the mag array as an array of bytes.
 15.3168 +     */
 15.3169 +    private byte[] magSerializedForm() {
 15.3170 +        int len = mag.length;
 15.3171 +
 15.3172 +        int bitLen = (len == 0 ? 0 : ((len - 1) << 5) + bitLengthForInt(mag[0]));
 15.3173 +        int byteLen = (bitLen + 7) >>> 3;
 15.3174 +        byte[] result = new byte[byteLen];
 15.3175 +
 15.3176 +        for (int i = byteLen - 1, bytesCopied = 4, intIndex = len - 1, nextInt = 0;
 15.3177 +             i>=0; i--) {
 15.3178 +            if (bytesCopied == 4) {
 15.3179 +                nextInt = mag[intIndex--];
 15.3180 +                bytesCopied = 1;
 15.3181 +            } else {
 15.3182 +                nextInt >>>= 8;
 15.3183 +                bytesCopied++;
 15.3184 +            }
 15.3185 +            result[i] = (byte)nextInt;
 15.3186 +        }
 15.3187 +        return result;
 15.3188 +    }
 15.3189 +}
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/rt/emul/compact/src/main/java/java/math/BitSieve.java	Sat Sep 07 13:55:09 2013 +0200
    16.3 @@ -0,0 +1,212 @@
    16.4 +/*
    16.5 + * Copyright (c) 1999, 2007, 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.math;
   16.30 +
   16.31 +/**
   16.32 + * A simple bit sieve used for finding prime number candidates. Allows setting
   16.33 + * and clearing of bits in a storage array. The size of the sieve is assumed to
   16.34 + * be constant to reduce overhead. All the bits of a new bitSieve are zero, and
   16.35 + * bits are removed from it by setting them.
   16.36 + *
   16.37 + * To reduce storage space and increase efficiency, no even numbers are
   16.38 + * represented in the sieve (each bit in the sieve represents an odd number).
   16.39 + * The relationship between the index of a bit and the number it represents is
   16.40 + * given by
   16.41 + * N = offset + (2*index + 1);
   16.42 + * Where N is the integer represented by a bit in the sieve, offset is some
   16.43 + * even integer offset indicating where the sieve begins, and index is the
   16.44 + * index of a bit in the sieve array.
   16.45 + *
   16.46 + * @see     BigInteger
   16.47 + * @author  Michael McCloskey
   16.48 + * @since   1.3
   16.49 + */
   16.50 +class BitSieve {
   16.51 +    /**
   16.52 +     * Stores the bits in this bitSieve.
   16.53 +     */
   16.54 +    private long bits[];
   16.55 +
   16.56 +    /**
   16.57 +     * Length is how many bits this sieve holds.
   16.58 +     */
   16.59 +    private int length;
   16.60 +
   16.61 +    /**
   16.62 +     * A small sieve used to filter out multiples of small primes in a search
   16.63 +     * sieve.
   16.64 +     */
   16.65 +    private static BitSieve smallSieve = new BitSieve();
   16.66 +
   16.67 +    /**
   16.68 +     * Construct a "small sieve" with a base of 0.  This constructor is
   16.69 +     * used internally to generate the set of "small primes" whose multiples
   16.70 +     * are excluded from sieves generated by the main (package private)
   16.71 +     * constructor, BitSieve(BigInteger base, int searchLen).  The length
   16.72 +     * of the sieve generated by this constructor was chosen for performance;
   16.73 +     * it controls a tradeoff between how much time is spent constructing
   16.74 +     * other sieves, and how much time is wasted testing composite candidates
   16.75 +     * for primality.  The length was chosen experimentally to yield good
   16.76 +     * performance.
   16.77 +     */
   16.78 +    private BitSieve() {
   16.79 +        length = 150 * 64;
   16.80 +        bits = new long[(unitIndex(length - 1) + 1)];
   16.81 +
   16.82 +        // Mark 1 as composite
   16.83 +        set(0);
   16.84 +        int nextIndex = 1;
   16.85 +        int nextPrime = 3;
   16.86 +
   16.87 +        // Find primes and remove their multiples from sieve
   16.88 +        do {
   16.89 +            sieveSingle(length, nextIndex + nextPrime, nextPrime);
   16.90 +            nextIndex = sieveSearch(length, nextIndex + 1);
   16.91 +            nextPrime = 2*nextIndex + 1;
   16.92 +        } while((nextIndex > 0) && (nextPrime < length));
   16.93 +    }
   16.94 +
   16.95 +    /**
   16.96 +     * Construct a bit sieve of searchLen bits used for finding prime number
   16.97 +     * candidates. The new sieve begins at the specified base, which must
   16.98 +     * be even.
   16.99 +     */
  16.100 +    BitSieve(BigInteger base, int searchLen) {
  16.101 +        /*
  16.102 +         * Candidates are indicated by clear bits in the sieve. As a candidates
  16.103 +         * nonprimality is calculated, a bit is set in the sieve to eliminate
  16.104 +         * it. To reduce storage space and increase efficiency, no even numbers
  16.105 +         * are represented in the sieve (each bit in the sieve represents an
  16.106 +         * odd number).
  16.107 +         */
  16.108 +        bits = new long[(unitIndex(searchLen-1) + 1)];
  16.109 +        length = searchLen;
  16.110 +        int start = 0;
  16.111 +
  16.112 +        int step = smallSieve.sieveSearch(smallSieve.length, start);
  16.113 +        int convertedStep = (step *2) + 1;
  16.114 +
  16.115 +        // Construct the large sieve at an even offset specified by base
  16.116 +        MutableBigInteger b = new MutableBigInteger(base);
  16.117 +        MutableBigInteger q = new MutableBigInteger();
  16.118 +        do {
  16.119 +            // Calculate base mod convertedStep
  16.120 +            start = b.divideOneWord(convertedStep, q);
  16.121 +
  16.122 +            // Take each multiple of step out of sieve
  16.123 +            start = convertedStep - start;
  16.124 +            if (start%2 == 0)
  16.125 +                start += convertedStep;
  16.126 +            sieveSingle(searchLen, (start-1)/2, convertedStep);
  16.127 +
  16.128 +            // Find next prime from small sieve
  16.129 +            step = smallSieve.sieveSearch(smallSieve.length, step+1);
  16.130 +            convertedStep = (step *2) + 1;
  16.131 +        } while (step > 0);
  16.132 +    }
  16.133 +
  16.134 +    /**
  16.135 +     * Given a bit index return unit index containing it.
  16.136 +     */
  16.137 +    private static int unitIndex(int bitIndex) {
  16.138 +        return bitIndex >>> 6;
  16.139 +    }
  16.140 +
  16.141 +    /**
  16.142 +     * Return a unit that masks the specified bit in its unit.
  16.143 +     */
  16.144 +    private static long bit(int bitIndex) {
  16.145 +        return 1L << (bitIndex & ((1<<6) - 1));
  16.146 +    }
  16.147 +
  16.148 +    /**
  16.149 +     * Get the value of the bit at the specified index.
  16.150 +     */
  16.151 +    private boolean get(int bitIndex) {
  16.152 +        int unitIndex = unitIndex(bitIndex);
  16.153 +        return ((bits[unitIndex] & bit(bitIndex)) != 0);
  16.154 +    }
  16.155 +
  16.156 +    /**
  16.157 +     * Set the bit at the specified index.
  16.158 +     */
  16.159 +    private void set(int bitIndex) {
  16.160 +        int unitIndex = unitIndex(bitIndex);
  16.161 +        bits[unitIndex] |= bit(bitIndex);
  16.162 +    }
  16.163 +
  16.164 +    /**
  16.165 +     * This method returns the index of the first clear bit in the search
  16.166 +     * array that occurs at or after start. It will not search past the
  16.167 +     * specified limit. It returns -1 if there is no such clear bit.
  16.168 +     */
  16.169 +    private int sieveSearch(int limit, int start) {
  16.170 +        if (start >= limit)
  16.171 +            return -1;
  16.172 +
  16.173 +        int index = start;
  16.174 +        do {
  16.175 +            if (!get(index))
  16.176 +                return index;
  16.177 +            index++;
  16.178 +        } while(index < limit-1);
  16.179 +        return -1;
  16.180 +    }
  16.181 +
  16.182 +    /**
  16.183 +     * Sieve a single set of multiples out of the sieve. Begin to remove
  16.184 +     * multiples of the specified step starting at the specified start index,
  16.185 +     * up to the specified limit.
  16.186 +     */
  16.187 +    private void sieveSingle(int limit, int start, int step) {
  16.188 +        while(start < limit) {
  16.189 +            set(start);
  16.190 +            start += step;
  16.191 +        }
  16.192 +    }
  16.193 +
  16.194 +    /**
  16.195 +     * Test probable primes in the sieve and return successful candidates.
  16.196 +     */
  16.197 +    BigInteger retrieve(BigInteger initValue, int certainty, java.util.Random random) {
  16.198 +        // Examine the sieve one long at a time to find possible primes
  16.199 +        int offset = 1;
  16.200 +        for (int i=0; i<bits.length; i++) {
  16.201 +            long nextLong = ~bits[i];
  16.202 +            for (int j=0; j<64; j++) {
  16.203 +                if ((nextLong & 1) == 1) {
  16.204 +                    BigInteger candidate = initValue.add(
  16.205 +                                           BigInteger.valueOf(offset));
  16.206 +                    if (candidate.primeToCertainty(certainty, random))
  16.207 +                        return candidate;
  16.208 +                }
  16.209 +                nextLong >>>= 1;
  16.210 +                offset+=2;
  16.211 +            }
  16.212 +        }
  16.213 +        return null;
  16.214 +    }
  16.215 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/rt/emul/compact/src/main/java/java/math/MathContext.java	Sat Sep 07 13:55:09 2013 +0200
    17.3 @@ -0,0 +1,326 @@
    17.4 +/*
    17.5 + * Copyright (c) 2003, 2007, 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 +/*
   17.30 + * Portions Copyright IBM Corporation, 1997, 2001. All Rights Reserved.
   17.31 + */
   17.32 +
   17.33 +package java.math;
   17.34 +import java.io.*;
   17.35 +
   17.36 +/**
   17.37 + * Immutable objects which encapsulate the context settings which
   17.38 + * describe certain rules for numerical operators, such as those
   17.39 + * implemented by the {@link BigDecimal} class.
   17.40 + *
   17.41 + * <p>The base-independent settings are:
   17.42 + * <ol>
   17.43 + * <li>{@code precision}:
   17.44 + * the number of digits to be used for an operation; results are
   17.45 + * rounded to this precision
   17.46 + *
   17.47 + * <li>{@code roundingMode}:
   17.48 + * a {@link RoundingMode} object which specifies the algorithm to be
   17.49 + * used for rounding.
   17.50 + * </ol>
   17.51 + *
   17.52 + * @see     BigDecimal
   17.53 + * @see     RoundingMode
   17.54 + * @author  Mike Cowlishaw
   17.55 + * @author  Joseph D. Darcy
   17.56 + * @since 1.5
   17.57 + */
   17.58 +
   17.59 +public final class MathContext implements Serializable {
   17.60 +
   17.61 +    /* ----- Constants ----- */
   17.62 +
   17.63 +    // defaults for constructors
   17.64 +    private static final int DEFAULT_DIGITS = 9;
   17.65 +    private static final RoundingMode DEFAULT_ROUNDINGMODE = RoundingMode.HALF_UP;
   17.66 +    // Smallest values for digits (Maximum is Integer.MAX_VALUE)
   17.67 +    private static final int MIN_DIGITS = 0;
   17.68 +
   17.69 +    // Serialization version
   17.70 +    private static final long serialVersionUID = 5579720004786848255L;
   17.71 +
   17.72 +    /* ----- Public Properties ----- */
   17.73 +    /**
   17.74 +     *  A {@code MathContext} object whose settings have the values
   17.75 +     *  required for unlimited precision arithmetic.
   17.76 +     *  The values of the settings are:
   17.77 +     *  <code>
   17.78 +     *  precision=0 roundingMode=HALF_UP
   17.79 +     *  </code>
   17.80 +     */
   17.81 +    public static final MathContext UNLIMITED =
   17.82 +        new MathContext(0, RoundingMode.HALF_UP);
   17.83 +
   17.84 +    /**
   17.85 +     *  A {@code MathContext} object with a precision setting
   17.86 +     *  matching the IEEE 754R Decimal32 format, 7 digits, and a
   17.87 +     *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
   17.88 +     *  IEEE 754R default.
   17.89 +     */
   17.90 +    public static final MathContext DECIMAL32 =
   17.91 +        new MathContext(7, RoundingMode.HALF_EVEN);
   17.92 +
   17.93 +    /**
   17.94 +     *  A {@code MathContext} object with a precision setting
   17.95 +     *  matching the IEEE 754R Decimal64 format, 16 digits, and a
   17.96 +     *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
   17.97 +     *  IEEE 754R default.
   17.98 +     */
   17.99 +    public static final MathContext DECIMAL64 =
  17.100 +        new MathContext(16, RoundingMode.HALF_EVEN);
  17.101 +
  17.102 +    /**
  17.103 +     *  A {@code MathContext} object with a precision setting
  17.104 +     *  matching the IEEE 754R Decimal128 format, 34 digits, and a
  17.105 +     *  rounding mode of {@link RoundingMode#HALF_EVEN HALF_EVEN}, the
  17.106 +     *  IEEE 754R default.
  17.107 +     */
  17.108 +    public static final MathContext DECIMAL128 =
  17.109 +        new MathContext(34, RoundingMode.HALF_EVEN);
  17.110 +
  17.111 +    /* ----- Shared Properties ----- */
  17.112 +    /**
  17.113 +     * The number of digits to be used for an operation.  A value of 0
  17.114 +     * indicates that unlimited precision (as many digits as are
  17.115 +     * required) will be used.  Note that leading zeros (in the
  17.116 +     * coefficient of a number) are never significant.
  17.117 +     *
  17.118 +     * <p>{@code precision} will always be non-negative.
  17.119 +     *
  17.120 +     * @serial
  17.121 +     */
  17.122 +    final int precision;
  17.123 +
  17.124 +    /**
  17.125 +     * The rounding algorithm to be used for an operation.
  17.126 +     *
  17.127 +     * @see RoundingMode
  17.128 +     * @serial
  17.129 +     */
  17.130 +    final RoundingMode roundingMode;
  17.131 +
  17.132 +    /* ----- Constructors ----- */
  17.133 +
  17.134 +    /**
  17.135 +     * Constructs a new {@code MathContext} with the specified
  17.136 +     * precision and the {@link RoundingMode#HALF_UP HALF_UP} rounding
  17.137 +     * mode.
  17.138 +     *
  17.139 +     * @param setPrecision The non-negative {@code int} precision setting.
  17.140 +     * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
  17.141 +     *         than zero.
  17.142 +     */
  17.143 +    public MathContext(int setPrecision) {
  17.144 +        this(setPrecision, DEFAULT_ROUNDINGMODE);
  17.145 +        return;
  17.146 +    }
  17.147 +
  17.148 +    /**
  17.149 +     * Constructs a new {@code MathContext} with a specified
  17.150 +     * precision and rounding mode.
  17.151 +     *
  17.152 +     * @param setPrecision The non-negative {@code int} precision setting.
  17.153 +     * @param setRoundingMode The rounding mode to use.
  17.154 +     * @throws IllegalArgumentException if the {@code setPrecision} parameter is less
  17.155 +     *         than zero.
  17.156 +     * @throws NullPointerException if the rounding mode argument is {@code null}
  17.157 +     */
  17.158 +    public MathContext(int setPrecision,
  17.159 +                       RoundingMode setRoundingMode) {
  17.160 +        if (setPrecision < MIN_DIGITS)
  17.161 +            throw new IllegalArgumentException("Digits < 0");
  17.162 +        if (setRoundingMode == null)
  17.163 +            throw new NullPointerException("null RoundingMode");
  17.164 +
  17.165 +        precision = setPrecision;
  17.166 +        roundingMode = setRoundingMode;
  17.167 +        return;
  17.168 +    }
  17.169 +
  17.170 +    /**
  17.171 +     * Constructs a new {@code MathContext} from a string.
  17.172 +     *
  17.173 +     * The string must be in the same format as that produced by the
  17.174 +     * {@link #toString} method.
  17.175 +     *
  17.176 +     * <p>An {@code IllegalArgumentException} is thrown if the precision
  17.177 +     * section of the string is out of range ({@code < 0}) or the string is
  17.178 +     * not in the format created by the {@link #toString} method.
  17.179 +     *
  17.180 +     * @param val The string to be parsed
  17.181 +     * @throws IllegalArgumentException if the precision section is out of range
  17.182 +     * or of incorrect format
  17.183 +     * @throws NullPointerException if the argument is {@code null}
  17.184 +     */
  17.185 +    public MathContext(String val) {
  17.186 +        boolean bad = false;
  17.187 +        int setPrecision;
  17.188 +        if (val == null)
  17.189 +            throw new NullPointerException("null String");
  17.190 +        try { // any error here is a string format problem
  17.191 +            if (!val.startsWith("precision=")) throw new RuntimeException();
  17.192 +            int fence = val.indexOf(' ');    // could be -1
  17.193 +            int off = 10;                     // where value starts
  17.194 +            setPrecision = Integer.parseInt(val.substring(10, fence));
  17.195 +
  17.196 +            if (!val.startsWith("roundingMode=", fence+1))
  17.197 +                throw new RuntimeException();
  17.198 +            off = fence + 1 + 13;
  17.199 +            String str = val.substring(off, val.length());
  17.200 +            roundingMode = RoundingMode.valueOf(str);
  17.201 +        } catch (RuntimeException re) {
  17.202 +            throw new IllegalArgumentException("bad string format");
  17.203 +        }
  17.204 +
  17.205 +        if (setPrecision < MIN_DIGITS)
  17.206 +            throw new IllegalArgumentException("Digits < 0");
  17.207 +        // the other parameters cannot be invalid if we got here
  17.208 +        precision = setPrecision;
  17.209 +    }
  17.210 +
  17.211 +    /**
  17.212 +     * Returns the {@code precision} setting.
  17.213 +     * This value is always non-negative.
  17.214 +     *
  17.215 +     * @return an {@code int} which is the value of the {@code precision}
  17.216 +     *         setting
  17.217 +     */
  17.218 +    public int getPrecision() {
  17.219 +        return precision;
  17.220 +    }
  17.221 +
  17.222 +    /**
  17.223 +     * Returns the roundingMode setting.
  17.224 +     * This will be one of
  17.225 +     * {@link  RoundingMode#CEILING},
  17.226 +     * {@link  RoundingMode#DOWN},
  17.227 +     * {@link  RoundingMode#FLOOR},
  17.228 +     * {@link  RoundingMode#HALF_DOWN},
  17.229 +     * {@link  RoundingMode#HALF_EVEN},
  17.230 +     * {@link  RoundingMode#HALF_UP},
  17.231 +     * {@link  RoundingMode#UNNECESSARY}, or
  17.232 +     * {@link  RoundingMode#UP}.
  17.233 +     *
  17.234 +     * @return a {@code RoundingMode} object which is the value of the
  17.235 +     *         {@code roundingMode} setting
  17.236 +     */
  17.237 +
  17.238 +    public RoundingMode getRoundingMode() {
  17.239 +        return roundingMode;
  17.240 +    }
  17.241 +
  17.242 +    /**
  17.243 +     * Compares this {@code MathContext} with the specified
  17.244 +     * {@code Object} for equality.
  17.245 +     *
  17.246 +     * @param  x {@code Object} to which this {@code MathContext} is to
  17.247 +     *         be compared.
  17.248 +     * @return {@code true} if and only if the specified {@code Object} is
  17.249 +     *         a {@code MathContext} object which has exactly the same
  17.250 +     *         settings as this object
  17.251 +     */
  17.252 +    public boolean equals(Object x){
  17.253 +        MathContext mc;
  17.254 +        if (!(x instanceof MathContext))
  17.255 +            return false;
  17.256 +        mc = (MathContext) x;
  17.257 +        return mc.precision == this.precision
  17.258 +            && mc.roundingMode == this.roundingMode; // no need for .equals()
  17.259 +    }
  17.260 +
  17.261 +    /**
  17.262 +     * Returns the hash code for this {@code MathContext}.
  17.263 +     *
  17.264 +     * @return hash code for this {@code MathContext}
  17.265 +     */
  17.266 +    public int hashCode() {
  17.267 +        return this.precision + roundingMode.hashCode() * 59;
  17.268 +    }
  17.269 +
  17.270 +    /**
  17.271 +     * Returns the string representation of this {@code MathContext}.
  17.272 +     * The {@code String} returned represents the settings of the
  17.273 +     * {@code MathContext} object as two space-delimited words
  17.274 +     * (separated by a single space character, <tt>'&#92;u0020'</tt>,
  17.275 +     * and with no leading or trailing white space), as follows:
  17.276 +     * <ol>
  17.277 +     * <li>
  17.278 +     * The string {@code "precision="}, immediately followed
  17.279 +     * by the value of the precision setting as a numeric string as if
  17.280 +     * generated by the {@link Integer#toString(int) Integer.toString}
  17.281 +     * method.
  17.282 +     *
  17.283 +     * <li>
  17.284 +     * The string {@code "roundingMode="}, immediately
  17.285 +     * followed by the value of the {@code roundingMode} setting as a
  17.286 +     * word.  This word will be the same as the name of the
  17.287 +     * corresponding public constant in the {@link RoundingMode}
  17.288 +     * enum.
  17.289 +     * </ol>
  17.290 +     * <p>
  17.291 +     * For example:
  17.292 +     * <pre>
  17.293 +     * precision=9 roundingMode=HALF_UP
  17.294 +     * </pre>
  17.295 +     *
  17.296 +     * Additional words may be appended to the result of
  17.297 +     * {@code toString} in the future if more properties are added to
  17.298 +     * this class.
  17.299 +     *
  17.300 +     * @return a {@code String} representing the context settings
  17.301 +     */
  17.302 +    public java.lang.String toString() {
  17.303 +        return "precision=" +           precision + " " +
  17.304 +               "roundingMode=" +        roundingMode.toString();
  17.305 +    }
  17.306 +
  17.307 +    // Private methods
  17.308 +
  17.309 +    /**
  17.310 +     * Reconstitute the {@code MathContext} instance from a stream (that is,
  17.311 +     * deserialize it).
  17.312 +     *
  17.313 +     * @param s the stream being read.
  17.314 +     */
  17.315 +    private void readObject(java.io.ObjectInputStream s)
  17.316 +        throws java.io.IOException, ClassNotFoundException {
  17.317 +        s.defaultReadObject();     // read in all fields
  17.318 +        // validate possibly bad fields
  17.319 +        if (precision < MIN_DIGITS) {
  17.320 +            String message = "MathContext: invalid digits in stream";
  17.321 +            throw new java.io.StreamCorruptedException(message);
  17.322 +        }
  17.323 +        if (roundingMode == null) {
  17.324 +            String message = "MathContext: null roundingMode in stream";
  17.325 +            throw new java.io.StreamCorruptedException(message);
  17.326 +        }
  17.327 +    }
  17.328 +
  17.329 +}
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/rt/emul/compact/src/main/java/java/math/MutableBigInteger.java	Sat Sep 07 13:55:09 2013 +0200
    18.3 @@ -0,0 +1,1477 @@
    18.4 +/*
    18.5 + * Copyright (c) 1999, 2007, 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.math;
   18.30 +
   18.31 +/**
   18.32 + * A class used to represent multiprecision integers that makes efficient
   18.33 + * use of allocated space by allowing a number to occupy only part of
   18.34 + * an array so that the arrays do not have to be reallocated as often.
   18.35 + * When performing an operation with many iterations the array used to
   18.36 + * hold a number is only reallocated when necessary and does not have to
   18.37 + * be the same size as the number it represents. A mutable number allows
   18.38 + * calculations to occur on the same number without having to create
   18.39 + * a new number for every step of the calculation as occurs with
   18.40 + * BigIntegers.
   18.41 + *
   18.42 + * @see     BigInteger
   18.43 + * @author  Michael McCloskey
   18.44 + * @since   1.3
   18.45 + */
   18.46 +
   18.47 +import java.util.Arrays;
   18.48 +
   18.49 +import static java.math.BigInteger.LONG_MASK;
   18.50 +import static java.math.BigDecimal.INFLATED;
   18.51 +
   18.52 +class MutableBigInteger {
   18.53 +    /**
   18.54 +     * Holds the magnitude of this MutableBigInteger in big endian order.
   18.55 +     * The magnitude may start at an offset into the value array, and it may
   18.56 +     * end before the length of the value array.
   18.57 +     */
   18.58 +    int[] value;
   18.59 +
   18.60 +    /**
   18.61 +     * The number of ints of the value array that are currently used
   18.62 +     * to hold the magnitude of this MutableBigInteger. The magnitude starts
   18.63 +     * at an offset and offset + intLen may be less than value.length.
   18.64 +     */
   18.65 +    int intLen;
   18.66 +
   18.67 +    /**
   18.68 +     * The offset into the value array where the magnitude of this
   18.69 +     * MutableBigInteger begins.
   18.70 +     */
   18.71 +    int offset = 0;
   18.72 +
   18.73 +    // Constants
   18.74 +    /**
   18.75 +     * MutableBigInteger with one element value array with the value 1. Used by
   18.76 +     * BigDecimal divideAndRound to increment the quotient. Use this constant
   18.77 +     * only when the method is not going to modify this object.
   18.78 +     */
   18.79 +    static final MutableBigInteger ONE = new MutableBigInteger(1);
   18.80 +
   18.81 +    // Constructors
   18.82 +
   18.83 +    /**
   18.84 +     * The default constructor. An empty MutableBigInteger is created with
   18.85 +     * a one word capacity.
   18.86 +     */
   18.87 +    MutableBigInteger() {
   18.88 +        value = new int[1];
   18.89 +        intLen = 0;
   18.90 +    }
   18.91 +
   18.92 +    /**
   18.93 +     * Construct a new MutableBigInteger with a magnitude specified by
   18.94 +     * the int val.
   18.95 +     */
   18.96 +    MutableBigInteger(int val) {
   18.97 +        value = new int[1];
   18.98 +        intLen = 1;
   18.99 +        value[0] = val;
  18.100 +    }
  18.101 +
  18.102 +    /**
  18.103 +     * Construct a new MutableBigInteger with the specified value array
  18.104 +     * up to the length of the array supplied.
  18.105 +     */
  18.106 +    MutableBigInteger(int[] val) {
  18.107 +        value = val;
  18.108 +        intLen = val.length;
  18.109 +    }
  18.110 +
  18.111 +    /**
  18.112 +     * Construct a new MutableBigInteger with a magnitude equal to the
  18.113 +     * specified BigInteger.
  18.114 +     */
  18.115 +    MutableBigInteger(BigInteger b) {
  18.116 +        intLen = b.mag.length;
  18.117 +        value = Arrays.copyOf(b.mag, intLen);
  18.118 +    }
  18.119 +
  18.120 +    /**
  18.121 +     * Construct a new MutableBigInteger with a magnitude equal to the
  18.122 +     * specified MutableBigInteger.
  18.123 +     */
  18.124 +    MutableBigInteger(MutableBigInteger val) {
  18.125 +        intLen = val.intLen;
  18.126 +        value = Arrays.copyOfRange(val.value, val.offset, val.offset + intLen);
  18.127 +    }
  18.128 +
  18.129 +    /**
  18.130 +     * Internal helper method to return the magnitude array. The caller is not
  18.131 +     * supposed to modify the returned array.
  18.132 +     */
  18.133 +    private int[] getMagnitudeArray() {
  18.134 +        if (offset > 0 || value.length != intLen)
  18.135 +            return Arrays.copyOfRange(value, offset, offset + intLen);
  18.136 +        return value;
  18.137 +    }
  18.138 +
  18.139 +    /**
  18.140 +     * Convert this MutableBigInteger to a long value. The caller has to make
  18.141 +     * sure this MutableBigInteger can be fit into long.
  18.142 +     */
  18.143 +    private long toLong() {
  18.144 +        assert (intLen <= 2) : "this MutableBigInteger exceeds the range of long";
  18.145 +        if (intLen == 0)
  18.146 +            return 0;
  18.147 +        long d = value[offset] & LONG_MASK;
  18.148 +        return (intLen == 2) ? d << 32 | (value[offset + 1] & LONG_MASK) : d;
  18.149 +    }
  18.150 +
  18.151 +    /**
  18.152 +     * Convert this MutableBigInteger to a BigInteger object.
  18.153 +     */
  18.154 +    BigInteger toBigInteger(int sign) {
  18.155 +        if (intLen == 0 || sign == 0)
  18.156 +            return BigInteger.ZERO;
  18.157 +        return new BigInteger(getMagnitudeArray(), sign);
  18.158 +    }
  18.159 +
  18.160 +    /**
  18.161 +     * Convert this MutableBigInteger to BigDecimal object with the specified sign
  18.162 +     * and scale.
  18.163 +     */
  18.164 +    BigDecimal toBigDecimal(int sign, int scale) {
  18.165 +        if (intLen == 0 || sign == 0)
  18.166 +            return BigDecimal.valueOf(0, scale);
  18.167 +        int[] mag = getMagnitudeArray();
  18.168 +        int len = mag.length;
  18.169 +        int d = mag[0];
  18.170 +        // If this MutableBigInteger can't be fit into long, we need to
  18.171 +        // make a BigInteger object for the resultant BigDecimal object.
  18.172 +        if (len > 2 || (d < 0 && len == 2))
  18.173 +            return new BigDecimal(new BigInteger(mag, sign), INFLATED, scale, 0);
  18.174 +        long v = (len == 2) ?
  18.175 +            ((mag[1] & LONG_MASK) | (d & LONG_MASK) << 32) :
  18.176 +            d & LONG_MASK;
  18.177 +        return new BigDecimal(null, sign == -1 ? -v : v, scale, 0);
  18.178 +    }
  18.179 +
  18.180 +    /**
  18.181 +     * Clear out a MutableBigInteger for reuse.
  18.182 +     */
  18.183 +    void clear() {
  18.184 +        offset = intLen = 0;
  18.185 +        for (int index=0, n=value.length; index < n; index++)
  18.186 +            value[index] = 0;
  18.187 +    }
  18.188 +
  18.189 +    /**
  18.190 +     * Set a MutableBigInteger to zero, removing its offset.
  18.191 +     */
  18.192 +    void reset() {
  18.193 +        offset = intLen = 0;
  18.194 +    }
  18.195 +
  18.196 +    /**
  18.197 +     * Compare the magnitude of two MutableBigIntegers. Returns -1, 0 or 1
  18.198 +     * as this MutableBigInteger is numerically less than, equal to, or
  18.199 +     * greater than <tt>b</tt>.
  18.200 +     */
  18.201 +    final int compare(MutableBigInteger b) {
  18.202 +        int blen = b.intLen;
  18.203 +        if (intLen < blen)
  18.204 +            return -1;
  18.205 +        if (intLen > blen)
  18.206 +           return 1;
  18.207 +
  18.208 +        // Add Integer.MIN_VALUE to make the comparison act as unsigned integer
  18.209 +        // comparison.
  18.210 +        int[] bval = b.value;
  18.211 +        for (int i = offset, j = b.offset; i < intLen + offset; i++, j++) {
  18.212 +            int b1 = value[i] + 0x80000000;
  18.213 +            int b2 = bval[j]  + 0x80000000;
  18.214 +            if (b1 < b2)
  18.215 +                return -1;
  18.216 +            if (b1 > b2)
  18.217 +                return 1;
  18.218 +        }
  18.219 +        return 0;
  18.220 +    }
  18.221 +
  18.222 +    /**
  18.223 +     * Compare this against half of a MutableBigInteger object (Needed for
  18.224 +     * remainder tests).
  18.225 +     * Assumes no leading unnecessary zeros, which holds for results
  18.226 +     * from divide().
  18.227 +     */
  18.228 +    final int compareHalf(MutableBigInteger b) {
  18.229 +        int blen = b.intLen;
  18.230 +        int len = intLen;
  18.231 +        if (len <= 0)
  18.232 +            return blen <=0 ? 0 : -1;
  18.233 +        if (len > blen)
  18.234 +            return 1;
  18.235 +        if (len < blen - 1)
  18.236 +            return -1;
  18.237 +        int[] bval = b.value;
  18.238 +        int bstart = 0;
  18.239 +        int carry = 0;
  18.240 +        // Only 2 cases left:len == blen or len == blen - 1
  18.241 +        if (len != blen) { // len == blen - 1
  18.242 +            if (bval[bstart] == 1) {
  18.243 +                ++bstart;
  18.244 +                carry = 0x80000000;
  18.245 +            } else
  18.246 +                return -1;
  18.247 +        }
  18.248 +        // compare values with right-shifted values of b,
  18.249 +        // carrying shifted-out bits across words
  18.250 +        int[] val = value;
  18.251 +        for (int i = offset, j = bstart; i < len + offset;) {
  18.252 +            int bv = bval[j++];
  18.253 +            long hb = ((bv >>> 1) + carry) & LONG_MASK;
  18.254 +            long v = val[i++] & LONG_MASK;
  18.255 +            if (v != hb)
  18.256 +                return v < hb ? -1 : 1;
  18.257 +            carry = (bv & 1) << 31; // carray will be either 0x80000000 or 0
  18.258 +        }
  18.259 +        return carry == 0? 0 : -1;
  18.260 +    }
  18.261 +
  18.262 +    /**
  18.263 +     * Return the index of the lowest set bit in this MutableBigInteger. If the
  18.264 +     * magnitude of this MutableBigInteger is zero, -1 is returned.
  18.265 +     */
  18.266 +    private final int getLowestSetBit() {
  18.267 +        if (intLen == 0)
  18.268 +            return -1;
  18.269 +        int j, b;
  18.270 +        for (j=intLen-1; (j>0) && (value[j+offset]==0); j--)
  18.271 +            ;
  18.272 +        b = value[j+offset];
  18.273 +        if (b==0)
  18.274 +            return -1;
  18.275 +        return ((intLen-1-j)<<5) + Integer.numberOfTrailingZeros(b);
  18.276 +    }
  18.277 +
  18.278 +    /**
  18.279 +     * Return the int in use in this MutableBigInteger at the specified
  18.280 +     * index. This method is not used because it is not inlined on all
  18.281 +     * platforms.
  18.282 +     */
  18.283 +    private final int getInt(int index) {
  18.284 +        return value[offset+index];
  18.285 +    }
  18.286 +
  18.287 +    /**
  18.288 +     * Return a long which is equal to the unsigned value of the int in
  18.289 +     * use in this MutableBigInteger at the specified index. This method is
  18.290 +     * not used because it is not inlined on all platforms.
  18.291 +     */
  18.292 +    private final long getLong(int index) {
  18.293 +        return value[offset+index] & LONG_MASK;
  18.294 +    }
  18.295 +
  18.296 +    /**
  18.297 +     * Ensure that the MutableBigInteger is in normal form, specifically
  18.298 +     * making sure that there are no leading zeros, and that if the
  18.299 +     * magnitude is zero, then intLen is zero.
  18.300 +     */
  18.301 +    final void normalize() {
  18.302 +        if (intLen == 0) {
  18.303 +            offset = 0;
  18.304 +            return;
  18.305 +        }
  18.306 +
  18.307 +        int index = offset;
  18.308 +        if (value[index] != 0)
  18.309 +            return;
  18.310 +
  18.311 +        int indexBound = index+intLen;
  18.312 +        do {
  18.313 +            index++;
  18.314 +        } while(index < indexBound && value[index]==0);
  18.315 +
  18.316 +        int numZeros = index - offset;
  18.317 +        intLen -= numZeros;
  18.318 +        offset = (intLen==0 ?  0 : offset+numZeros);
  18.319 +    }
  18.320 +
  18.321 +    /**
  18.322 +     * If this MutableBigInteger cannot hold len words, increase the size
  18.323 +     * of the value array to len words.
  18.324 +     */
  18.325 +    private final void ensureCapacity(int len) {
  18.326 +        if (value.length < len) {
  18.327 +            value = new int[len];
  18.328 +            offset = 0;
  18.329 +            intLen = len;
  18.330 +        }
  18.331 +    }
  18.332 +
  18.333 +    /**
  18.334 +     * Convert this MutableBigInteger into an int array with no leading
  18.335 +     * zeros, of a length that is equal to this MutableBigInteger's intLen.
  18.336 +     */
  18.337 +    int[] toIntArray() {
  18.338 +        int[] result = new int[intLen];
  18.339 +        for(int i=0; i<intLen; i++)
  18.340 +            result[i] = value[offset+i];
  18.341 +        return result;
  18.342 +    }
  18.343 +
  18.344 +    /**
  18.345 +     * Sets the int at index+offset in this MutableBigInteger to val.
  18.346 +     * This does not get inlined on all platforms so it is not used
  18.347 +     * as often as originally intended.
  18.348 +     */
  18.349 +    void setInt(int index, int val) {
  18.350 +        value[offset + index] = val;
  18.351 +    }
  18.352 +
  18.353 +    /**
  18.354 +     * Sets this MutableBigInteger's value array to the specified array.
  18.355 +     * The intLen is set to the specified length.
  18.356 +     */
  18.357 +    void setValue(int[] val, int length) {
  18.358 +        value = val;
  18.359 +        intLen = length;
  18.360 +        offset = 0;
  18.361 +    }
  18.362 +
  18.363 +    /**
  18.364 +     * Sets this MutableBigInteger's value array to a copy of the specified
  18.365 +     * array. The intLen is set to the length of the new array.
  18.366 +     */
  18.367 +    void copyValue(MutableBigInteger src) {
  18.368 +        int len = src.intLen;
  18.369 +        if (value.length < len)
  18.370 +            value = new int[len];
  18.371 +        System.arraycopy(src.value, src.offset, value, 0, len);
  18.372 +        intLen = len;
  18.373 +        offset = 0;
  18.374 +    }
  18.375 +
  18.376 +    /**
  18.377 +     * Sets this MutableBigInteger's value array to a copy of the specified
  18.378 +     * array. The intLen is set to the length of the specified array.
  18.379 +     */
  18.380 +    void copyValue(int[] val) {
  18.381 +        int len = val.length;
  18.382 +        if (value.length < len)
  18.383 +            value = new int[len];
  18.384 +        System.arraycopy(val, 0, value, 0, len);
  18.385 +        intLen = len;
  18.386 +        offset = 0;
  18.387 +    }
  18.388 +
  18.389 +    /**
  18.390 +     * Returns true iff this MutableBigInteger has a value of one.
  18.391 +     */
  18.392 +    boolean isOne() {
  18.393 +        return (intLen == 1) && (value[offset] == 1);
  18.394 +    }
  18.395 +
  18.396 +    /**
  18.397 +     * Returns true iff this MutableBigInteger has a value of zero.
  18.398 +     */
  18.399 +    boolean isZero() {
  18.400 +        return (intLen == 0);
  18.401 +    }
  18.402 +
  18.403 +    /**
  18.404 +     * Returns true iff this MutableBigInteger is even.
  18.405 +     */
  18.406 +    boolean isEven() {
  18.407 +        return (intLen == 0) || ((value[offset + intLen - 1] & 1) == 0);
  18.408 +    }
  18.409 +
  18.410 +    /**
  18.411 +     * Returns true iff this MutableBigInteger is odd.
  18.412 +     */
  18.413 +    boolean isOdd() {
  18.414 +        return isZero() ? false : ((value[offset + intLen - 1] & 1) == 1);
  18.415 +    }
  18.416 +
  18.417 +    /**
  18.418 +     * Returns true iff this MutableBigInteger is in normal form. A
  18.419 +     * MutableBigInteger is in normal form if it has no leading zeros
  18.420 +     * after the offset, and intLen + offset <= value.length.
  18.421 +     */
  18.422 +    boolean isNormal() {
  18.423 +        if (intLen + offset > value.length)
  18.424 +            return false;
  18.425 +        if (intLen ==0)
  18.426 +            return true;
  18.427 +        return (value[offset] != 0);
  18.428 +    }
  18.429 +
  18.430 +    /**
  18.431 +     * Returns a String representation of this MutableBigInteger in radix 10.
  18.432 +     */
  18.433 +    public String toString() {
  18.434 +        BigInteger b = toBigInteger(1);
  18.435 +        return b.toString();
  18.436 +    }
  18.437 +
  18.438 +    /**
  18.439 +     * Right shift this MutableBigInteger n bits. The MutableBigInteger is left
  18.440 +     * in normal form.
  18.441 +     */
  18.442 +    void rightShift(int n) {
  18.443 +        if (intLen == 0)
  18.444 +            return;
  18.445 +        int nInts = n >>> 5;
  18.446 +        int nBits = n & 0x1F;
  18.447 +        this.intLen -= nInts;
  18.448 +        if (nBits == 0)
  18.449 +            return;
  18.450 +        int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
  18.451 +        if (nBits >= bitsInHighWord) {
  18.452 +            this.primitiveLeftShift(32 - nBits);
  18.453 +            this.intLen--;
  18.454 +        } else {
  18.455 +            primitiveRightShift(nBits);
  18.456 +        }
  18.457 +    }
  18.458 +
  18.459 +    /**
  18.460 +     * Left shift this MutableBigInteger n bits.
  18.461 +     */
  18.462 +    void leftShift(int n) {
  18.463 +        /*
  18.464 +         * If there is enough storage space in this MutableBigInteger already
  18.465 +         * the available space will be used. Space to the right of the used
  18.466 +         * ints in the value array is faster to utilize, so the extra space
  18.467 +         * will be taken from the right if possible.
  18.468 +         */
  18.469 +        if (intLen == 0)
  18.470 +           return;
  18.471 +        int nInts = n >>> 5;
  18.472 +        int nBits = n&0x1F;
  18.473 +        int bitsInHighWord = BigInteger.bitLengthForInt(value[offset]);
  18.474 +
  18.475 +        // If shift can be done without moving words, do so
  18.476 +        if (n <= (32-bitsInHighWord)) {
  18.477 +            primitiveLeftShift(nBits);
  18.478 +            return;
  18.479 +        }
  18.480 +
  18.481 +        int newLen = intLen + nInts +1;
  18.482 +        if (nBits <= (32-bitsInHighWord))
  18.483 +            newLen--;
  18.484 +        if (value.length < newLen) {
  18.485 +            // The array must grow
  18.486 +            int[] result = new int[newLen];
  18.487 +            for (int i=0; i<intLen; i++)
  18.488 +                result[i] = value[offset+i];
  18.489 +            setValue(result, newLen);
  18.490 +        } else if (value.length - offset >= newLen) {
  18.491 +            // Use space on right
  18.492 +            for(int i=0; i<newLen - intLen; i++)
  18.493 +                value[offset+intLen+i] = 0;
  18.494 +        } else {
  18.495 +            // Must use space on left
  18.496 +            for (int i=0; i<intLen; i++)
  18.497 +                value[i] = value[offset+i];
  18.498 +            for (int i=intLen; i<newLen; i++)
  18.499 +                value[i] = 0;
  18.500 +            offset = 0;
  18.501 +        }
  18.502 +        intLen = newLen;
  18.503 +        if (nBits == 0)
  18.504 +            return;
  18.505 +        if (nBits <= (32-bitsInHighWord))
  18.506 +            primitiveLeftShift(nBits);
  18.507 +        else
  18.508 +            primitiveRightShift(32 -nBits);
  18.509 +    }
  18.510 +
  18.511 +    /**
  18.512 +     * A primitive used for division. This method adds in one multiple of the
  18.513 +     * divisor a back to the dividend result at a specified offset. It is used
  18.514 +     * when qhat was estimated too large, and must be adjusted.
  18.515 +     */
  18.516 +    private int divadd(int[] a, int[] result, int offset) {
  18.517 +        long carry = 0;
  18.518 +
  18.519 +        for (int j=a.length-1; j >= 0; j--) {
  18.520 +            long sum = (a[j] & LONG_MASK) +
  18.521 +                       (result[j+offset] & LONG_MASK) + carry;
  18.522 +            result[j+offset] = (int)sum;
  18.523 +            carry = sum >>> 32;
  18.524 +        }
  18.525 +        return (int)carry;
  18.526 +    }
  18.527 +
  18.528 +    /**
  18.529 +     * This method is used for division. It multiplies an n word input a by one
  18.530 +     * word input x, and subtracts the n word product from q. This is needed
  18.531 +     * when subtracting qhat*divisor from dividend.
  18.532 +     */
  18.533 +    private int mulsub(int[] q, int[] a, int x, int len, int offset) {
  18.534 +        long xLong = x & LONG_MASK;
  18.535 +        long carry = 0;
  18.536 +        offset += len;
  18.537 +
  18.538 +        for (int j=len-1; j >= 0; j--) {
  18.539 +            long product = (a[j] & LONG_MASK) * xLong + carry;
  18.540 +            long difference = q[offset] - product;
  18.541 +            q[offset--] = (int)difference;
  18.542 +            carry = (product >>> 32)
  18.543 +                     + (((difference & LONG_MASK) >
  18.544 +                         (((~(int)product) & LONG_MASK))) ? 1:0);
  18.545 +        }
  18.546 +        return (int)carry;
  18.547 +    }
  18.548 +
  18.549 +    /**
  18.550 +     * Right shift this MutableBigInteger n bits, where n is
  18.551 +     * less than 32.
  18.552 +     * Assumes that intLen > 0, n > 0 for speed
  18.553 +     */
  18.554 +    private final void primitiveRightShift(int n) {
  18.555 +        int[] val = value;
  18.556 +        int n2 = 32 - n;
  18.557 +        for (int i=offset+intLen-1, c=val[i]; i>offset; i--) {
  18.558 +            int b = c;
  18.559 +            c = val[i-1];
  18.560 +            val[i] = (c << n2) | (b >>> n);
  18.561 +        }
  18.562 +        val[offset] >>>= n;
  18.563 +    }
  18.564 +
  18.565 +    /**
  18.566 +     * Left shift this MutableBigInteger n bits, where n is
  18.567 +     * less than 32.
  18.568 +     * Assumes that intLen > 0, n > 0 for speed
  18.569 +     */
  18.570 +    private final void primitiveLeftShift(int n) {
  18.571 +        int[] val = value;
  18.572 +        int n2 = 32 - n;
  18.573 +        for (int i=offset, c=val[i], m=i+intLen-1; i<m; i++) {
  18.574 +            int b = c;
  18.575 +            c = val[i+1];
  18.576 +            val[i] = (b << n) | (c >>> n2);
  18.577 +        }
  18.578 +        val[offset+intLen-1] <<= n;
  18.579 +    }
  18.580 +
  18.581 +    /**
  18.582 +     * Adds the contents of two MutableBigInteger objects.The result
  18.583 +     * is placed within this MutableBigInteger.
  18.584 +     * The contents of the addend are not changed.
  18.585 +     */
  18.586 +    void add(MutableBigInteger addend) {
  18.587 +        int x = intLen;
  18.588 +        int y = addend.intLen;
  18.589 +        int resultLen = (intLen > addend.intLen ? intLen : addend.intLen);
  18.590 +        int[] result = (value.length < resultLen ? new int[resultLen] : value);
  18.591 +
  18.592 +        int rstart = result.length-1;
  18.593 +        long sum;
  18.594 +        long carry = 0;
  18.595 +
  18.596 +        // Add common parts of both numbers
  18.597 +        while(x>0 && y>0) {
  18.598 +            x--; y--;
  18.599 +            sum = (value[x+offset] & LONG_MASK) +
  18.600 +                (addend.value[y+addend.offset] & LONG_MASK) + carry;
  18.601 +            result[rstart--] = (int)sum;
  18.602 +            carry = sum >>> 32;
  18.603 +        }
  18.604 +
  18.605 +        // Add remainder of the longer number
  18.606 +        while(x>0) {
  18.607 +            x--;
  18.608 +            if (carry == 0 && result == value && rstart == (x + offset))
  18.609 +                return;
  18.610 +            sum = (value[x+offset] & LONG_MASK) + carry;
  18.611 +            result[rstart--] = (int)sum;
  18.612 +            carry = sum >>> 32;
  18.613 +        }
  18.614 +        while(y>0) {
  18.615 +            y--;
  18.616 +            sum = (addend.value[y+addend.offset] & LONG_MASK) + carry;
  18.617 +            result[rstart--] = (int)sum;
  18.618 +            carry = sum >>> 32;
  18.619 +        }
  18.620 +
  18.621 +        if (carry > 0) { // Result must grow in length
  18.622 +            resultLen++;
  18.623 +            if (result.length < resultLen) {
  18.624 +                int temp[] = new int[resultLen];
  18.625 +                // Result one word longer from carry-out; copy low-order
  18.626 +                // bits into new result.
  18.627 +                System.arraycopy(result, 0, temp, 1, result.length);
  18.628 +                temp[0] = 1;
  18.629 +                result = temp;
  18.630 +            } else {
  18.631 +                result[rstart--] = 1;
  18.632 +            }
  18.633 +        }
  18.634 +
  18.635 +        value = result;
  18.636 +        intLen = resultLen;
  18.637 +        offset = result.length - resultLen;
  18.638 +    }
  18.639 +
  18.640 +
  18.641 +    /**
  18.642 +     * Subtracts the smaller of this and b from the larger and places the
  18.643 +     * result into this MutableBigInteger.
  18.644 +     */
  18.645 +    int subtract(MutableBigInteger b) {
  18.646 +        MutableBigInteger a = this;
  18.647 +
  18.648 +        int[] result = value;
  18.649 +        int sign = a.compare(b);
  18.650 +
  18.651 +        if (sign == 0) {
  18.652 +            reset();
  18.653 +            return 0;
  18.654 +        }
  18.655 +        if (sign < 0) {
  18.656 +            MutableBigInteger tmp = a;
  18.657 +            a = b;
  18.658 +            b = tmp;
  18.659 +        }
  18.660 +
  18.661 +        int resultLen = a.intLen;
  18.662 +        if (result.length < resultLen)
  18.663 +            result = new int[resultLen];
  18.664 +
  18.665 +        long diff = 0;
  18.666 +        int x = a.intLen;
  18.667 +        int y = b.intLen;
  18.668 +        int rstart = result.length - 1;
  18.669 +
  18.670 +        // Subtract common parts of both numbers
  18.671 +        while (y>0) {
  18.672 +            x--; y--;
  18.673 +
  18.674 +            diff = (a.value[x+a.offset] & LONG_MASK) -
  18.675 +                   (b.value[y+b.offset] & LONG_MASK) - ((int)-(diff>>32));
  18.676 +            result[rstart--] = (int)diff;
  18.677 +        }
  18.678 +        // Subtract remainder of longer number
  18.679 +        while (x>0) {
  18.680 +            x--;
  18.681 +            diff = (a.value[x+a.offset] & LONG_MASK) - ((int)-(diff>>32));
  18.682 +            result[rstart--] = (int)diff;
  18.683 +        }
  18.684 +
  18.685 +        value = result;
  18.686 +        intLen = resultLen;
  18.687 +        offset = value.length - resultLen;
  18.688 +        normalize();
  18.689 +        return sign;
  18.690 +    }
  18.691 +
  18.692 +    /**
  18.693 +     * Subtracts the smaller of a and b from the larger and places the result
  18.694 +     * into the larger. Returns 1 if the answer is in a, -1 if in b, 0 if no
  18.695 +     * operation was performed.
  18.696 +     */
  18.697 +    private int difference(MutableBigInteger b) {
  18.698 +        MutableBigInteger a = this;
  18.699 +        int sign = a.compare(b);
  18.700 +        if (sign ==0)
  18.701 +            return 0;
  18.702 +        if (sign < 0) {
  18.703 +            MutableBigInteger tmp = a;
  18.704 +            a = b;
  18.705 +            b = tmp;
  18.706 +        }
  18.707 +
  18.708 +        long diff = 0;
  18.709 +        int x = a.intLen;
  18.710 +        int y = b.intLen;
  18.711 +
  18.712 +        // Subtract common parts of both numbers
  18.713 +        while (y>0) {
  18.714 +            x--; y--;
  18.715 +            diff = (a.value[a.offset+ x] & LONG_MASK) -
  18.716 +                (b.value[b.offset+ y] & LONG_MASK) - ((int)-(diff>>32));
  18.717 +            a.value[a.offset+x] = (int)diff;
  18.718 +        }
  18.719 +        // Subtract remainder of longer number
  18.720 +        while (x>0) {
  18.721 +            x--;
  18.722 +            diff = (a.value[a.offset+ x] & LONG_MASK) - ((int)-(diff>>32));
  18.723 +            a.value[a.offset+x] = (int)diff;
  18.724 +        }
  18.725 +
  18.726 +        a.normalize();
  18.727 +        return sign;
  18.728 +    }
  18.729 +
  18.730 +    /**
  18.731 +     * Multiply the contents of two MutableBigInteger objects. The result is
  18.732 +     * placed into MutableBigInteger z. The contents of y are not changed.
  18.733 +     */
  18.734 +    void multiply(MutableBigInteger y, MutableBigInteger z) {
  18.735 +        int xLen = intLen;
  18.736 +        int yLen = y.intLen;
  18.737 +        int newLen = xLen + yLen;
  18.738 +
  18.739 +        // Put z into an appropriate state to receive product
  18.740 +        if (z.value.length < newLen)
  18.741 +            z.value = new int[newLen];
  18.742 +        z.offset = 0;
  18.743 +        z.intLen = newLen;
  18.744 +
  18.745 +        // The first iteration is hoisted out of the loop to avoid extra add
  18.746 +        long carry = 0;
  18.747 +        for (int j=yLen-1, k=yLen+xLen-1; j >= 0; j--, k--) {
  18.748 +                long product = (y.value[j+y.offset] & LONG_MASK) *
  18.749 +                               (value[xLen-1+offset] & LONG_MASK) + carry;
  18.750 +                z.value[k] = (int)product;
  18.751 +                carry = product >>> 32;
  18.752 +        }
  18.753 +        z.value[xLen-1] = (int)carry;
  18.754 +
  18.755 +        // Perform the multiplication word by word
  18.756 +        for (int i = xLen-2; i >= 0; i--) {
  18.757 +            carry = 0;
  18.758 +            for (int j=yLen-1, k=yLen+i; j >= 0; j--, k--) {
  18.759 +                long product = (y.value[j+y.offset] & LONG_MASK) *
  18.760 +                               (value[i+offset] & LONG_MASK) +
  18.761 +                               (z.value[k] & LONG_MASK) + carry;
  18.762 +                z.value[k] = (int)product;
  18.763 +                carry = product >>> 32;
  18.764 +            }
  18.765 +            z.value[i] = (int)carry;
  18.766 +        }
  18.767 +
  18.768 +        // Remove leading zeros from product
  18.769 +        z.normalize();
  18.770 +    }
  18.771 +
  18.772 +    /**
  18.773 +     * Multiply the contents of this MutableBigInteger by the word y. The
  18.774 +     * result is placed into z.
  18.775 +     */
  18.776 +    void mul(int y, MutableBigInteger z) {
  18.777 +        if (y == 1) {
  18.778 +            z.copyValue(this);
  18.779 +            return;
  18.780 +        }
  18.781 +
  18.782 +        if (y == 0) {
  18.783 +            z.clear();
  18.784 +            return;
  18.785 +        }
  18.786 +
  18.787 +        // Perform the multiplication word by word
  18.788 +        long ylong = y & LONG_MASK;
  18.789 +        int[] zval = (z.value.length<intLen+1 ? new int[intLen + 1]
  18.790 +                                              : z.value);
  18.791 +        long carry = 0;
  18.792 +        for (int i = intLen-1; i >= 0; i--) {
  18.793 +            long product = ylong * (value[i+offset] & LONG_MASK) + carry;
  18.794 +            zval[i+1] = (int)product;
  18.795 +            carry = product >>> 32;
  18.796 +        }
  18.797 +
  18.798 +        if (carry == 0) {
  18.799 +            z.offset = 1;
  18.800 +            z.intLen = intLen;
  18.801 +        } else {
  18.802 +            z.offset = 0;
  18.803 +            z.intLen = intLen + 1;
  18.804 +            zval[0] = (int)carry;
  18.805 +        }
  18.806 +        z.value = zval;
  18.807 +    }
  18.808 +
  18.809 +     /**
  18.810 +     * This method is used for division of an n word dividend by a one word
  18.811 +     * divisor. The quotient is placed into quotient. The one word divisor is
  18.812 +     * specified by divisor.
  18.813 +     *
  18.814 +     * @return the remainder of the division is returned.
  18.815 +     *
  18.816 +     */
  18.817 +    int divideOneWord(int divisor, MutableBigInteger quotient) {
  18.818 +        long divisorLong = divisor & LONG_MASK;
  18.819 +
  18.820 +        // Special case of one word dividend
  18.821 +        if (intLen == 1) {
  18.822 +            long dividendValue = value[offset] & LONG_MASK;
  18.823 +            int q = (int) (dividendValue / divisorLong);
  18.824 +            int r = (int) (dividendValue - q * divisorLong);
  18.825 +            quotient.value[0] = q;
  18.826 +            quotient.intLen = (q == 0) ? 0 : 1;
  18.827 +            quotient.offset = 0;
  18.828 +            return r;
  18.829 +        }
  18.830 +
  18.831 +        if (quotient.value.length < intLen)
  18.832 +            quotient.value = new int[intLen];
  18.833 +        quotient.offset = 0;
  18.834 +        quotient.intLen = intLen;
  18.835 +
  18.836 +        // Normalize the divisor
  18.837 +        int shift = Integer.numberOfLeadingZeros(divisor);
  18.838 +
  18.839 +        int rem = value[offset];
  18.840 +        long remLong = rem & LONG_MASK;
  18.841 +        if (remLong < divisorLong) {
  18.842 +            quotient.value[0] = 0;
  18.843 +        } else {
  18.844 +            quotient.value[0] = (int)(remLong / divisorLong);
  18.845 +            rem = (int) (remLong - (quotient.value[0] * divisorLong));
  18.846 +            remLong = rem & LONG_MASK;
  18.847 +        }
  18.848 +
  18.849 +        int xlen = intLen;
  18.850 +        int[] qWord = new int[2];
  18.851 +        while (--xlen > 0) {
  18.852 +            long dividendEstimate = (remLong<<32) |
  18.853 +                (value[offset + intLen - xlen] & LONG_MASK);
  18.854 +            if (dividendEstimate >= 0) {
  18.855 +                qWord[0] = (int) (dividendEstimate / divisorLong);
  18.856 +                qWord[1] = (int) (dividendEstimate - qWord[0] * divisorLong);
  18.857 +            } else {
  18.858 +                divWord(qWord, dividendEstimate, divisor);
  18.859 +            }
  18.860 +            quotient.value[intLen - xlen] = qWord[0];
  18.861 +            rem = qWord[1];
  18.862 +            remLong = rem & LONG_MASK;
  18.863 +        }
  18.864 +
  18.865 +        quotient.normalize();
  18.866 +        // Unnormalize
  18.867 +        if (shift > 0)
  18.868 +            return rem % divisor;
  18.869 +        else
  18.870 +            return rem;
  18.871 +    }
  18.872 +
  18.873 +    /**
  18.874 +     * Calculates the quotient of this div b and places the quotient in the
  18.875 +     * provided MutableBigInteger objects and the remainder object is returned.
  18.876 +     *
  18.877 +     * Uses Algorithm D in Knuth section 4.3.1.
  18.878 +     * Many optimizations to that algorithm have been adapted from the Colin
  18.879 +     * Plumb C library.
  18.880 +     * It special cases one word divisors for speed. The content of b is not
  18.881 +     * changed.
  18.882 +     *
  18.883 +     */
  18.884 +    MutableBigInteger divide(MutableBigInteger b, MutableBigInteger quotient) {
  18.885 +        if (b.intLen == 0)
  18.886 +            throw new ArithmeticException("BigInteger divide by zero");
  18.887 +
  18.888 +        // Dividend is zero
  18.889 +        if (intLen == 0) {
  18.890 +            quotient.intLen = quotient.offset;
  18.891 +            return new MutableBigInteger();
  18.892 +        }
  18.893 +
  18.894 +        int cmp = compare(b);
  18.895 +        // Dividend less than divisor
  18.896 +        if (cmp < 0) {
  18.897 +            quotient.intLen = quotient.offset = 0;
  18.898 +            return new MutableBigInteger(this);
  18.899 +        }
  18.900 +        // Dividend equal to divisor
  18.901 +        if (cmp == 0) {
  18.902 +            quotient.value[0] = quotient.intLen = 1;
  18.903 +            quotient.offset = 0;
  18.904 +            return new MutableBigInteger();
  18.905 +        }
  18.906 +
  18.907 +        quotient.clear();
  18.908 +        // Special case one word divisor
  18.909 +        if (b.intLen == 1) {
  18.910 +            int r = divideOneWord(b.value[b.offset], quotient);
  18.911 +            if (r == 0)
  18.912 +                return new MutableBigInteger();
  18.913 +            return new MutableBigInteger(r);
  18.914 +        }
  18.915 +
  18.916 +        // Copy divisor value to protect divisor
  18.917 +        int[] div = Arrays.copyOfRange(b.value, b.offset, b.offset + b.intLen);
  18.918 +        return divideMagnitude(div, quotient);
  18.919 +    }
  18.920 +
  18.921 +    /**
  18.922 +     * Internally used  to calculate the quotient of this div v and places the
  18.923 +     * quotient in the provided MutableBigInteger object and the remainder is
  18.924 +     * returned.
  18.925 +     *
  18.926 +     * @return the remainder of the division will be returned.
  18.927 +     */
  18.928 +    long divide(long v, MutableBigInteger quotient) {
  18.929 +        if (v == 0)
  18.930 +            throw new ArithmeticException("BigInteger divide by zero");
  18.931 +
  18.932 +        // Dividend is zero
  18.933 +        if (intLen == 0) {
  18.934 +            quotient.intLen = quotient.offset = 0;
  18.935 +            return 0;
  18.936 +        }
  18.937 +        if (v < 0)
  18.938 +            v = -v;
  18.939 +
  18.940 +        int d = (int)(v >>> 32);
  18.941 +        quotient.clear();
  18.942 +        // Special case on word divisor
  18.943 +        if (d == 0)
  18.944 +            return divideOneWord((int)v, quotient) & LONG_MASK;
  18.945 +        else {
  18.946 +            int[] div = new int[]{ d, (int)(v & LONG_MASK) };
  18.947 +            return divideMagnitude(div, quotient).toLong();
  18.948 +        }
  18.949 +    }
  18.950 +
  18.951 +    /**
  18.952 +     * Divide this MutableBigInteger by the divisor represented by its magnitude
  18.953 +     * array. The quotient will be placed into the provided quotient object &
  18.954 +     * the remainder object is returned.
  18.955 +     */
  18.956 +    private MutableBigInteger divideMagnitude(int[] divisor,
  18.957 +                                              MutableBigInteger quotient) {
  18.958 +
  18.959 +        // Remainder starts as dividend with space for a leading zero
  18.960 +        MutableBigInteger rem = new MutableBigInteger(new int[intLen + 1]);
  18.961 +        System.arraycopy(value, offset, rem.value, 1, intLen);
  18.962 +        rem.intLen = intLen;
  18.963 +        rem.offset = 1;
  18.964 +
  18.965 +        int nlen = rem.intLen;
  18.966 +
  18.967 +        // Set the quotient size
  18.968 +        int dlen = divisor.length;
  18.969 +        int limit = nlen - dlen + 1;
  18.970 +        if (quotient.value.length < limit) {
  18.971 +            quotient.value = new int[limit];
  18.972 +            quotient.offset = 0;
  18.973 +        }
  18.974 +        quotient.intLen = limit;
  18.975 +        int[] q = quotient.value;
  18.976 +
  18.977 +        // D1 normalize the divisor
  18.978 +        int shift = Integer.numberOfLeadingZeros(divisor[0]);
  18.979 +        if (shift > 0) {
  18.980 +            // First shift will not grow array
  18.981 +            BigInteger.primitiveLeftShift(divisor, dlen, shift);
  18.982 +            // But this one might
  18.983 +            rem.leftShift(shift);
  18.984 +        }
  18.985 +
  18.986 +        // Must insert leading 0 in rem if its length did not change
  18.987 +        if (rem.intLen == nlen) {
  18.988 +            rem.offset = 0;
  18.989 +            rem.value[0] = 0;
  18.990 +            rem.intLen++;
  18.991 +        }
  18.992 +
  18.993 +        int dh = divisor[0];
  18.994 +        long dhLong = dh & LONG_MASK;
  18.995 +        int dl = divisor[1];
  18.996 +        int[] qWord = new int[2];
  18.997 +
  18.998 +        // D2 Initialize j
  18.999 +        for(int j=0; j<limit; j++) {
 18.1000 +            // D3 Calculate qhat
 18.1001 +            // estimate qhat
 18.1002 +            int qhat = 0;
 18.1003 +            int qrem = 0;
 18.1004 +            boolean skipCorrection = false;
 18.1005 +            int nh = rem.value[j+rem.offset];
 18.1006 +            int nh2 = nh + 0x80000000;
 18.1007 +            int nm = rem.value[j+1+rem.offset];
 18.1008 +
 18.1009 +            if (nh == dh) {
 18.1010 +                qhat = ~0;
 18.1011 +                qrem = nh + nm;
 18.1012 +                skipCorrection = qrem + 0x80000000 < nh2;
 18.1013 +            } else {
 18.1014 +                long nChunk = (((long)nh) << 32) | (nm & LONG_MASK);
 18.1015 +                if (nChunk >= 0) {
 18.1016 +                    qhat = (int) (nChunk / dhLong);
 18.1017 +                    qrem = (int) (nChunk - (qhat * dhLong));
 18.1018 +                } else {
 18.1019 +                    divWord(qWord, nChunk, dh);
 18.1020 +                    qhat = qWord[0];
 18.1021 +                    qrem = qWord[1];
 18.1022 +                }
 18.1023 +            }
 18.1024 +
 18.1025 +            if (qhat == 0)
 18.1026 +                continue;
 18.1027 +
 18.1028 +            if (!skipCorrection) { // Correct qhat
 18.1029 +                long nl = rem.value[j+2+rem.offset] & LONG_MASK;
 18.1030 +                long rs = ((qrem & LONG_MASK) << 32) | nl;
 18.1031 +                long estProduct = (dl & LONG_MASK) * (qhat & LONG_MASK);
 18.1032 +
 18.1033 +                if (unsignedLongCompare(estProduct, rs)) {
 18.1034 +                    qhat--;
 18.1035 +                    qrem = (int)((qrem & LONG_MASK) + dhLong);
 18.1036 +                    if ((qrem & LONG_MASK) >=  dhLong) {
 18.1037 +                        estProduct -= (dl & LONG_MASK);
 18.1038 +                        rs = ((qrem & LONG_MASK) << 32) | nl;
 18.1039 +                        if (unsignedLongCompare(estProduct, rs))
 18.1040 +                            qhat--;
 18.1041 +                    }
 18.1042 +                }
 18.1043 +            }
 18.1044 +
 18.1045 +            // D4 Multiply and subtract
 18.1046 +            rem.value[j+rem.offset] = 0;
 18.1047 +            int borrow = mulsub(rem.value, divisor, qhat, dlen, j+rem.offset);
 18.1048 +
 18.1049 +            // D5 Test remainder
 18.1050 +            if (borrow + 0x80000000 > nh2) {
 18.1051 +                // D6 Add back
 18.1052 +                divadd(divisor, rem.value, j+1+rem.offset);
 18.1053 +                qhat--;
 18.1054 +            }
 18.1055 +
 18.1056 +            // Store the quotient digit
 18.1057 +            q[j] = qhat;
 18.1058 +        } // D7 loop on j
 18.1059 +
 18.1060 +        // D8 Unnormalize
 18.1061 +        if (shift > 0)
 18.1062 +            rem.rightShift(shift);
 18.1063 +
 18.1064 +        quotient.normalize();
 18.1065 +        rem.normalize();
 18.1066 +        return rem;
 18.1067 +    }
 18.1068 +
 18.1069 +    /**
 18.1070 +     * Compare two longs as if they were unsigned.
 18.1071 +     * Returns true iff one is bigger than two.
 18.1072 +     */
 18.1073 +    private boolean unsignedLongCompare(long one, long two) {
 18.1074 +        return (one+Long.MIN_VALUE) > (two+Long.MIN_VALUE);
 18.1075 +    }
 18.1076 +
 18.1077 +    /**
 18.1078 +     * This method divides a long quantity by an int to estimate
 18.1079 +     * qhat for two multi precision numbers. It is used when
 18.1080 +     * the signed value of n is less than zero.
 18.1081 +     */
 18.1082 +    private void divWord(int[] result, long n, int d) {
 18.1083 +        long dLong = d & LONG_MASK;
 18.1084 +
 18.1085 +        if (dLong == 1) {
 18.1086 +            result[0] = (int)n;
 18.1087 +            result[1] = 0;
 18.1088 +            return;
 18.1089 +        }
 18.1090 +
 18.1091 +        // Approximate the quotient and remainder
 18.1092 +        long q = (n >>> 1) / (dLong >>> 1);
 18.1093 +        long r = n - q*dLong;
 18.1094 +
 18.1095 +        // Correct the approximation
 18.1096 +        while (r < 0) {
 18.1097 +            r += dLong;
 18.1098 +            q--;
 18.1099 +        }
 18.1100 +        while (r >= dLong) {
 18.1101 +            r -= dLong;
 18.1102 +            q++;
 18.1103 +        }
 18.1104 +
 18.1105 +        // n - q*dlong == r && 0 <= r <dLong, hence we're done.
 18.1106 +        result[0] = (int)q;
 18.1107 +        result[1] = (int)r;
 18.1108 +    }
 18.1109 +
 18.1110 +    /**
 18.1111 +     * Calculate GCD of this and b. This and b are changed by the computation.
 18.1112 +     */
 18.1113 +    MutableBigInteger hybridGCD(MutableBigInteger b) {
 18.1114 +        // Use Euclid's algorithm until the numbers are approximately the
 18.1115 +        // same length, then use the binary GCD algorithm to find the GCD.
 18.1116 +        MutableBigInteger a = this;
 18.1117 +        MutableBigInteger q = new MutableBigInteger();
 18.1118 +
 18.1119 +        while (b.intLen != 0) {
 18.1120 +            if (Math.abs(a.intLen - b.intLen) < 2)
 18.1121 +                return a.binaryGCD(b);
 18.1122 +
 18.1123 +            MutableBigInteger r = a.divide(b, q);
 18.1124 +            a = b;
 18.1125 +            b = r;
 18.1126 +        }
 18.1127 +        return a;
 18.1128 +    }
 18.1129 +
 18.1130 +    /**
 18.1131 +     * Calculate GCD of this and v.
 18.1132 +     * Assumes that this and v are not zero.
 18.1133 +     */
 18.1134 +    private MutableBigInteger binaryGCD(MutableBigInteger v) {
 18.1135 +        // Algorithm B from Knuth section 4.5.2
 18.1136 +        MutableBigInteger u = this;
 18.1137 +        MutableBigInteger r = new MutableBigInteger();
 18.1138 +
 18.1139 +        // step B1
 18.1140 +        int s1 = u.getLowestSetBit();
 18.1141 +        int s2 = v.getLowestSetBit();
 18.1142 +        int k = (s1 < s2) ? s1 : s2;
 18.1143 +        if (k != 0) {
 18.1144 +            u.rightShift(k);
 18.1145 +            v.rightShift(k);
 18.1146 +        }
 18.1147 +
 18.1148 +        // step B2
 18.1149 +        boolean uOdd = (k==s1);
 18.1150 +        MutableBigInteger t = uOdd ? v: u;
 18.1151 +        int tsign = uOdd ? -1 : 1;
 18.1152 +
 18.1153 +        int lb;
 18.1154 +        while ((lb = t.getLowestSetBit()) >= 0) {
 18.1155 +            // steps B3 and B4
 18.1156 +            t.rightShift(lb);
 18.1157 +            // step B5
 18.1158 +            if (tsign > 0)
 18.1159 +                u = t;
 18.1160 +            else
 18.1161 +                v = t;
 18.1162 +
 18.1163 +            // Special case one word numbers
 18.1164 +            if (u.intLen < 2 && v.intLen < 2) {
 18.1165 +                int x = u.value[u.offset];
 18.1166 +                int y = v.value[v.offset];
 18.1167 +                x  = binaryGcd(x, y);
 18.1168 +                r.value[0] = x;
 18.1169 +                r.intLen = 1;
 18.1170 +                r.offset = 0;
 18.1171 +                if (k > 0)
 18.1172 +                    r.leftShift(k);
 18.1173 +                return r;
 18.1174 +            }
 18.1175 +
 18.1176 +            // step B6
 18.1177 +            if ((tsign = u.difference(v)) == 0)
 18.1178 +                break;
 18.1179 +            t = (tsign >= 0) ? u : v;
 18.1180 +        }
 18.1181 +
 18.1182 +        if (k > 0)
 18.1183 +            u.leftShift(k);
 18.1184 +        return u;
 18.1185 +    }
 18.1186 +
 18.1187 +    /**
 18.1188 +     * Calculate GCD of a and b interpreted as unsigned integers.
 18.1189 +     */
 18.1190 +    static int binaryGcd(int a, int b) {
 18.1191 +        if (b==0)
 18.1192 +            return a;
 18.1193 +        if (a==0)
 18.1194 +            return b;
 18.1195 +
 18.1196 +        // Right shift a & b till their last bits equal to 1.
 18.1197 +        int aZeros = Integer.numberOfTrailingZeros(a);
 18.1198 +        int bZeros = Integer.numberOfTrailingZeros(b);
 18.1199 +        a >>>= aZeros;
 18.1200 +        b >>>= bZeros;
 18.1201 +
 18.1202 +        int t = (aZeros < bZeros ? aZeros : bZeros);
 18.1203 +
 18.1204 +        while (a != b) {
 18.1205 +            if ((a+0x80000000) > (b+0x80000000)) {  // a > b as unsigned
 18.1206 +                a -= b;
 18.1207 +                a >>>= Integer.numberOfTrailingZeros(a);
 18.1208 +            } else {
 18.1209 +                b -= a;
 18.1210 +                b >>>= Integer.numberOfTrailingZeros(b);
 18.1211 +            }
 18.1212 +        }
 18.1213 +        return a<<t;
 18.1214 +    }
 18.1215 +
 18.1216 +    /**
 18.1217 +     * Returns the modInverse of this mod p. This and p are not affected by
 18.1218 +     * the operation.
 18.1219 +     */
 18.1220 +    MutableBigInteger mutableModInverse(MutableBigInteger p) {
 18.1221 +        // Modulus is odd, use Schroeppel's algorithm
 18.1222 +        if (p.isOdd())
 18.1223 +            return modInverse(p);
 18.1224 +
 18.1225 +        // Base and modulus are even, throw exception
 18.1226 +        if (isEven())
 18.1227 +            throw new ArithmeticException("BigInteger not invertible.");
 18.1228 +
 18.1229 +        // Get even part of modulus expressed as a power of 2
 18.1230 +        int powersOf2 = p.getLowestSetBit();
 18.1231 +
 18.1232 +        // Construct odd part of modulus
 18.1233 +        MutableBigInteger oddMod = new MutableBigInteger(p);
 18.1234 +        oddMod.rightShift(powersOf2);
 18.1235 +
 18.1236 +        if (oddMod.isOne())
 18.1237 +            return modInverseMP2(powersOf2);
 18.1238 +
 18.1239 +        // Calculate 1/a mod oddMod
 18.1240 +        MutableBigInteger oddPart = modInverse(oddMod);
 18.1241 +
 18.1242 +        // Calculate 1/a mod evenMod
 18.1243 +        MutableBigInteger evenPart = modInverseMP2(powersOf2);
 18.1244 +
 18.1245 +        // Combine the results using Chinese Remainder Theorem
 18.1246 +        MutableBigInteger y1 = modInverseBP2(oddMod, powersOf2);
 18.1247 +        MutableBigInteger y2 = oddMod.modInverseMP2(powersOf2);
 18.1248 +
 18.1249 +        MutableBigInteger temp1 = new MutableBigInteger();
 18.1250 +        MutableBigInteger temp2 = new MutableBigInteger();
 18.1251 +        MutableBigInteger result = new MutableBigInteger();
 18.1252 +
 18.1253 +        oddPart.leftShift(powersOf2);
 18.1254 +        oddPart.multiply(y1, result);
 18.1255 +
 18.1256 +        evenPart.multiply(oddMod, temp1);
 18.1257 +        temp1.multiply(y2, temp2);
 18.1258 +
 18.1259 +        result.add(temp2);
 18.1260 +        return result.divide(p, temp1);
 18.1261 +    }
 18.1262 +
 18.1263 +    /*
 18.1264 +     * Calculate the multiplicative inverse of this mod 2^k.
 18.1265 +     */
 18.1266 +    MutableBigInteger modInverseMP2(int k) {
 18.1267 +        if (isEven())
 18.1268 +            throw new ArithmeticException("Non-invertible. (GCD != 1)");
 18.1269 +
 18.1270 +        if (k > 64)
 18.1271 +            return euclidModInverse(k);
 18.1272 +
 18.1273 +        int t = inverseMod32(value[offset+intLen-1]);
 18.1274 +
 18.1275 +        if (k < 33) {
 18.1276 +            t = (k == 32 ? t : t & ((1 << k) - 1));
 18.1277 +            return new MutableBigInteger(t);
 18.1278 +        }
 18.1279 +
 18.1280 +        long pLong = (value[offset+intLen-1] & LONG_MASK);
 18.1281 +        if (intLen > 1)
 18.1282 +            pLong |=  ((long)value[offset+intLen-2] << 32);
 18.1283 +        long tLong = t & LONG_MASK;
 18.1284 +        tLong = tLong * (2 - pLong * tLong);  // 1 more Newton iter step
 18.1285 +        tLong = (k == 64 ? tLong : tLong & ((1L << k) - 1));
 18.1286 +
 18.1287 +        MutableBigInteger result = new MutableBigInteger(new int[2]);
 18.1288 +        result.value[0] = (int)(tLong >>> 32);
 18.1289 +        result.value[1] = (int)tLong;
 18.1290 +        result.intLen = 2;
 18.1291 +        result.normalize();
 18.1292 +        return result;
 18.1293 +    }
 18.1294 +
 18.1295 +    /*
 18.1296 +     * Returns the multiplicative inverse of val mod 2^32.  Assumes val is odd.
 18.1297 +     */
 18.1298 +    static int inverseMod32(int val) {
 18.1299 +        // Newton's iteration!
 18.1300 +        int t = val;
 18.1301 +        t *= 2 - val*t;
 18.1302 +        t *= 2 - val*t;
 18.1303 +        t *= 2 - val*t;
 18.1304 +        t *= 2 - val*t;
 18.1305 +        return t;
 18.1306 +    }
 18.1307 +
 18.1308 +    /*
 18.1309 +     * Calculate the multiplicative inverse of 2^k mod mod, where mod is odd.
 18.1310 +     */
 18.1311 +    static MutableBigInteger modInverseBP2(MutableBigInteger mod, int k) {
 18.1312 +        // Copy the mod to protect original
 18.1313 +        return fixup(new MutableBigInteger(1), new MutableBigInteger(mod), k);
 18.1314 +    }
 18.1315 +
 18.1316 +    /**
 18.1317 +     * Calculate the multiplicative inverse of this mod mod, where mod is odd.
 18.1318 +     * This and mod are not changed by the calculation.
 18.1319 +     *
 18.1320 +     * This method implements an algorithm due to Richard Schroeppel, that uses
 18.1321 +     * the same intermediate representation as Montgomery Reduction
 18.1322 +     * ("Montgomery Form").  The algorithm is described in an unpublished
 18.1323 +     * manuscript entitled "Fast Modular Reciprocals."
 18.1324 +     */
 18.1325 +    private MutableBigInteger modInverse(MutableBigInteger mod) {
 18.1326 +        MutableBigInteger p = new MutableBigInteger(mod);
 18.1327 +        MutableBigInteger f = new MutableBigInteger(this);
 18.1328 +        MutableBigInteger g = new MutableBigInteger(p);
 18.1329 +        SignedMutableBigInteger c = new SignedMutableBigInteger(1);
 18.1330 +        SignedMutableBigInteger d = new SignedMutableBigInteger();
 18.1331 +        MutableBigInteger temp = null;
 18.1332 +        SignedMutableBigInteger sTemp = null;
 18.1333 +
 18.1334 +        int k = 0;
 18.1335 +        // Right shift f k times until odd, left shift d k times
 18.1336 +        if (f.isEven()) {
 18.1337 +            int trailingZeros = f.getLowestSetBit();
 18.1338 +            f.rightShift(trailingZeros);
 18.1339 +            d.leftShift(trailingZeros);
 18.1340 +            k = trailingZeros;
 18.1341 +        }
 18.1342 +
 18.1343 +        // The Almost Inverse Algorithm
 18.1344 +        while(!f.isOne()) {
 18.1345 +            // If gcd(f, g) != 1, number is not invertible modulo mod
 18.1346 +            if (f.isZero())
 18.1347 +                throw new ArithmeticException("BigInteger not invertible.");
 18.1348 +
 18.1349 +            // If f < g exchange f, g and c, d
 18.1350 +            if (f.compare(g) < 0) {
 18.1351 +                temp = f; f = g; g = temp;
 18.1352 +                sTemp = d; d = c; c = sTemp;
 18.1353 +            }
 18.1354 +
 18.1355 +            // If f == g (mod 4)
 18.1356 +            if (((f.value[f.offset + f.intLen - 1] ^
 18.1357 +                 g.value[g.offset + g.intLen - 1]) & 3) == 0) {
 18.1358 +                f.subtract(g);
 18.1359 +                c.signedSubtract(d);
 18.1360 +            } else { // If f != g (mod 4)
 18.1361 +                f.add(g);
 18.1362 +                c.signedAdd(d);
 18.1363 +            }
 18.1364 +
 18.1365 +            // Right shift f k times until odd, left shift d k times
 18.1366 +            int trailingZeros = f.getLowestSetBit();
 18.1367 +            f.rightShift(trailingZeros);
 18.1368 +            d.leftShift(trailingZeros);
 18.1369 +            k += trailingZeros;
 18.1370 +        }
 18.1371 +
 18.1372 +        while (c.sign < 0)
 18.1373 +           c.signedAdd(p);
 18.1374 +
 18.1375 +        return fixup(c, p, k);
 18.1376 +    }
 18.1377 +
 18.1378 +    /*
 18.1379 +     * The Fixup Algorithm
 18.1380 +     * Calculates X such that X = C * 2^(-k) (mod P)
 18.1381 +     * Assumes C<P and P is odd.
 18.1382 +     */
 18.1383 +    static MutableBigInteger fixup(MutableBigInteger c, MutableBigInteger p,
 18.1384 +                                                                      int k) {
 18.1385 +        MutableBigInteger temp = new MutableBigInteger();
 18.1386 +        // Set r to the multiplicative inverse of p mod 2^32
 18.1387 +        int r = -inverseMod32(p.value[p.offset+p.intLen-1]);
 18.1388 +
 18.1389 +        for(int i=0, numWords = k >> 5; i<numWords; i++) {
 18.1390 +            // V = R * c (mod 2^j)
 18.1391 +            int  v = r * c.value[c.offset + c.intLen-1];
 18.1392 +            // c = c + (v * p)
 18.1393 +            p.mul(v, temp);
 18.1394 +            c.add(temp);
 18.1395 +            // c = c / 2^j
 18.1396 +            c.intLen--;
 18.1397 +        }
 18.1398 +        int numBits = k & 0x1f;
 18.1399 +        if (numBits != 0) {
 18.1400 +            // V = R * c (mod 2^j)
 18.1401 +            int v = r * c.value[c.offset + c.intLen-1];
 18.1402 +            v &= ((1<<numBits) - 1);
 18.1403 +            // c = c + (v * p)
 18.1404 +            p.mul(v, temp);
 18.1405 +            c.add(temp);
 18.1406 +            // c = c / 2^j
 18.1407 +            c.rightShift(numBits);
 18.1408 +        }
 18.1409 +
 18.1410 +        // In theory, c may be greater than p at this point (Very rare!)
 18.1411 +        while (c.compare(p) >= 0)
 18.1412 +            c.subtract(p);
 18.1413 +
 18.1414 +        return c;
 18.1415 +    }
 18.1416 +
 18.1417 +    /**
 18.1418 +     * Uses the extended Euclidean algorithm to compute the modInverse of base
 18.1419 +     * mod a modulus that is a power of 2. The modulus is 2^k.
 18.1420 +     */
 18.1421 +    MutableBigInteger euclidModInverse(int k) {
 18.1422 +        MutableBigInteger b = new MutableBigInteger(1);
 18.1423 +        b.leftShift(k);
 18.1424 +        MutableBigInteger mod = new MutableBigInteger(b);
 18.1425 +
 18.1426 +        MutableBigInteger a = new MutableBigInteger(this);
 18.1427 +        MutableBigInteger q = new MutableBigInteger();
 18.1428 +        MutableBigInteger r = b.divide(a, q);
 18.1429 +
 18.1430 +        MutableBigInteger swapper = b;
 18.1431 +        // swap b & r
 18.1432 +        b = r;
 18.1433 +        r = swapper;
 18.1434 +
 18.1435 +        MutableBigInteger t1 = new MutableBigInteger(q);
 18.1436 +        MutableBigInteger t0 = new MutableBigInteger(1);
 18.1437 +        MutableBigInteger temp = new MutableBigInteger();
 18.1438 +
 18.1439 +        while (!b.isOne()) {
 18.1440 +            r = a.divide(b, q);
 18.1441 +
 18.1442 +            if (r.intLen == 0)
 18.1443 +                throw new ArithmeticException("BigInteger not invertible.");
 18.1444 +
 18.1445 +            swapper = r;
 18.1446 +            a = swapper;
 18.1447 +
 18.1448 +            if (q.intLen == 1)
 18.1449 +                t1.mul(q.value[q.offset], temp);
 18.1450 +            else
 18.1451 +                q.multiply(t1, temp);
 18.1452 +            swapper = q;
 18.1453 +            q = temp;
 18.1454 +            temp = swapper;
 18.1455 +            t0.add(q);
 18.1456 +
 18.1457 +            if (a.isOne())
 18.1458 +                return t0;
 18.1459 +
 18.1460 +            r = b.divide(a, q);
 18.1461 +
 18.1462 +            if (r.intLen == 0)
 18.1463 +                throw new ArithmeticException("BigInteger not invertible.");
 18.1464 +
 18.1465 +            swapper = b;
 18.1466 +            b =  r;
 18.1467 +
 18.1468 +            if (q.intLen == 1)
 18.1469 +                t0.mul(q.value[q.offset], temp);
 18.1470 +            else
 18.1471 +                q.multiply(t0, temp);
 18.1472 +            swapper = q; q = temp; temp = swapper;
 18.1473 +
 18.1474 +            t1.add(q);
 18.1475 +        }
 18.1476 +        mod.subtract(t1);
 18.1477 +        return mod;
 18.1478 +    }
 18.1479 +
 18.1480 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/rt/emul/compact/src/main/java/java/math/RoundingMode.java	Sat Sep 07 13:55:09 2013 +0200
    19.3 @@ -0,0 +1,349 @@
    19.4 +/*
    19.5 + * Copyright (c) 2003, 2011, 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 +/*
   19.30 + * Portions Copyright IBM Corporation, 2001. All Rights Reserved.
   19.31 + */
   19.32 +package java.math;
   19.33 +
   19.34 +/**
   19.35 + * Specifies a <i>rounding behavior</i> for numerical operations
   19.36 + * capable of discarding precision. Each rounding mode indicates how
   19.37 + * the least significant returned digit of a rounded result is to be
   19.38 + * calculated.  If fewer digits are returned than the digits needed to
   19.39 + * represent the exact numerical result, the discarded digits will be
   19.40 + * referred to as the <i>discarded fraction</i> regardless the digits'
   19.41 + * contribution to the value of the number.  In other words,
   19.42 + * considered as a numerical value, the discarded fraction could have
   19.43 + * an absolute value greater than one.
   19.44 + *
   19.45 + * <p>Each rounding mode description includes a table listing how
   19.46 + * different two-digit decimal values would round to a one digit
   19.47 + * decimal value under the rounding mode in question.  The result
   19.48 + * column in the tables could be gotten by creating a
   19.49 + * {@code BigDecimal} number with the specified value, forming a
   19.50 + * {@link MathContext} object with the proper settings
   19.51 + * ({@code precision} set to {@code 1}, and the
   19.52 + * {@code roundingMode} set to the rounding mode in question), and
   19.53 + * calling {@link BigDecimal#round round} on this number with the
   19.54 + * proper {@code MathContext}.  A summary table showing the results
   19.55 + * of these rounding operations for all rounding modes appears below.
   19.56 + *
   19.57 + *<p>
   19.58 + *<table border>
   19.59 + * <caption><b>Summary of Rounding Operations Under Different Rounding Modes</b></caption>
   19.60 + * <tr><th></th><th colspan=8>Result of rounding input to one digit with the given
   19.61 + *                           rounding mode</th>
   19.62 + * <tr valign=top>
   19.63 + * <th>Input Number</th>         <th>{@code UP}</th>
   19.64 + *                                           <th>{@code DOWN}</th>
   19.65 + *                                                        <th>{@code CEILING}</th>
   19.66 + *                                                                       <th>{@code FLOOR}</th>
   19.67 + *                                                                                    <th>{@code HALF_UP}</th>
   19.68 + *                                                                                                   <th>{@code HALF_DOWN}</th>
   19.69 + *                                                                                                                    <th>{@code HALF_EVEN}</th>
   19.70 + *                                                                                                                                     <th>{@code UNNECESSARY}</th>
   19.71 + *
   19.72 + * <tr align=right><td>5.5</td>  <td>6</td>  <td>5</td>    <td>6</td>    <td>5</td>  <td>6</td>      <td>5</td>       <td>6</td>       <td>throw {@code ArithmeticException}</td>
   19.73 + * <tr align=right><td>2.5</td>  <td>3</td>  <td>2</td>    <td>3</td>    <td>2</td>  <td>3</td>      <td>2</td>       <td>2</td>       <td>throw {@code ArithmeticException}</td>
   19.74 + * <tr align=right><td>1.6</td>  <td>2</td>  <td>1</td>    <td>2</td>    <td>1</td>  <td>2</td>      <td>2</td>       <td>2</td>       <td>throw {@code ArithmeticException}</td>
   19.75 + * <tr align=right><td>1.1</td>  <td>2</td>  <td>1</td>    <td>2</td>    <td>1</td>  <td>1</td>      <td>1</td>       <td>1</td>       <td>throw {@code ArithmeticException}</td>
   19.76 + * <tr align=right><td>1.0</td>  <td>1</td>  <td>1</td>    <td>1</td>    <td>1</td>  <td>1</td>      <td>1</td>       <td>1</td>       <td>1</td>
   19.77 + * <tr align=right><td>-1.0</td> <td>-1</td> <td>-1</td>   <td>-1</td>   <td>-1</td> <td>-1</td>     <td>-1</td>      <td>-1</td>      <td>-1</td>
   19.78 + * <tr align=right><td>-1.1</td> <td>-2</td> <td>-1</td>   <td>-1</td>   <td>-2</td> <td>-1</td>     <td>-1</td>      <td>-1</td>      <td>throw {@code ArithmeticException}</td>
   19.79 + * <tr align=right><td>-1.6</td> <td>-2</td> <td>-1</td>   <td>-1</td>   <td>-2</td> <td>-2</td>     <td>-2</td>      <td>-2</td>      <td>throw {@code ArithmeticException}</td>
   19.80 + * <tr align=right><td>-2.5</td> <td>-3</td> <td>-2</td>   <td>-2</td>   <td>-3</td> <td>-3</td>     <td>-2</td>      <td>-2</td>      <td>throw {@code ArithmeticException}</td>
   19.81 + * <tr align=right><td>-5.5</td> <td>-6</td> <td>-5</td>   <td>-5</td>   <td>-6</td> <td>-6</td>     <td>-5</td>      <td>-6</td>      <td>throw {@code ArithmeticException}</td>
   19.82 + *</table>
   19.83 + *
   19.84 + *
   19.85 + * <p>This {@code enum} is intended to replace the integer-based
   19.86 + * enumeration of rounding mode constants in {@link BigDecimal}
   19.87 + * ({@link BigDecimal#ROUND_UP}, {@link BigDecimal#ROUND_DOWN},
   19.88 + * etc. ).
   19.89 + *
   19.90 + * @see     BigDecimal
   19.91 + * @see     MathContext
   19.92 + * @author  Josh Bloch
   19.93 + * @author  Mike Cowlishaw
   19.94 + * @author  Joseph D. Darcy
   19.95 + * @since 1.5
   19.96 + */
   19.97 +public enum RoundingMode {
   19.98 +
   19.99 +        /**
  19.100 +         * Rounding mode to round away from zero.  Always increments the
  19.101 +         * digit prior to a non-zero discarded fraction.  Note that this
  19.102 +         * rounding mode never decreases the magnitude of the calculated
  19.103 +         * value.
  19.104 +         *
  19.105 +         *<p>Example:
  19.106 +         *<table border>
  19.107 +         *<tr valign=top><th>Input Number</th>
  19.108 +         *    <th>Input rounded to one digit<br> with {@code UP} rounding
  19.109 +         *<tr align=right><td>5.5</td>  <td>6</td>
  19.110 +         *<tr align=right><td>2.5</td>  <td>3</td>
  19.111 +         *<tr align=right><td>1.6</td>  <td>2</td>
  19.112 +         *<tr align=right><td>1.1</td>  <td>2</td>
  19.113 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.114 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.115 +         *<tr align=right><td>-1.1</td> <td>-2</td>
  19.116 +         *<tr align=right><td>-1.6</td> <td>-2</td>
  19.117 +         *<tr align=right><td>-2.5</td> <td>-3</td>
  19.118 +         *<tr align=right><td>-5.5</td> <td>-6</td>
  19.119 +         *</table>
  19.120 +         */
  19.121 +    UP(BigDecimal.ROUND_UP),
  19.122 +
  19.123 +        /**
  19.124 +         * Rounding mode to round towards zero.  Never increments the digit
  19.125 +         * prior to a discarded fraction (i.e., truncates).  Note that this
  19.126 +         * rounding mode never increases the magnitude of the calculated value.
  19.127 +         *
  19.128 +         *<p>Example:
  19.129 +         *<table border>
  19.130 +         *<tr valign=top><th>Input Number</th>
  19.131 +         *    <th>Input rounded to one digit<br> with {@code DOWN} rounding
  19.132 +         *<tr align=right><td>5.5</td>  <td>5</td>
  19.133 +         *<tr align=right><td>2.5</td>  <td>2</td>
  19.134 +         *<tr align=right><td>1.6</td>  <td>1</td>
  19.135 +         *<tr align=right><td>1.1</td>  <td>1</td>
  19.136 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.137 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.138 +         *<tr align=right><td>-1.1</td> <td>-1</td>
  19.139 +         *<tr align=right><td>-1.6</td> <td>-1</td>
  19.140 +         *<tr align=right><td>-2.5</td> <td>-2</td>
  19.141 +         *<tr align=right><td>-5.5</td> <td>-5</td>
  19.142 +         *</table>
  19.143 +         */
  19.144 +    DOWN(BigDecimal.ROUND_DOWN),
  19.145 +
  19.146 +        /**
  19.147 +         * Rounding mode to round towards positive infinity.  If the
  19.148 +         * result is positive, behaves as for {@code RoundingMode.UP};
  19.149 +         * if negative, behaves as for {@code RoundingMode.DOWN}.  Note
  19.150 +         * that this rounding mode never decreases the calculated value.
  19.151 +         *
  19.152 +         *<p>Example:
  19.153 +         *<table border>
  19.154 +         *<tr valign=top><th>Input Number</th>
  19.155 +         *    <th>Input rounded to one digit<br> with {@code CEILING} rounding
  19.156 +         *<tr align=right><td>5.5</td>  <td>6</td>
  19.157 +         *<tr align=right><td>2.5</td>  <td>3</td>
  19.158 +         *<tr align=right><td>1.6</td>  <td>2</td>
  19.159 +         *<tr align=right><td>1.1</td>  <td>2</td>
  19.160 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.161 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.162 +         *<tr align=right><td>-1.1</td> <td>-1</td>
  19.163 +         *<tr align=right><td>-1.6</td> <td>-1</td>
  19.164 +         *<tr align=right><td>-2.5</td> <td>-2</td>
  19.165 +         *<tr align=right><td>-5.5</td> <td>-5</td>
  19.166 +         *</table>
  19.167 +         */
  19.168 +    CEILING(BigDecimal.ROUND_CEILING),
  19.169 +
  19.170 +        /**
  19.171 +         * Rounding mode to round towards negative infinity.  If the
  19.172 +         * result is positive, behave as for {@code RoundingMode.DOWN};
  19.173 +         * if negative, behave as for {@code RoundingMode.UP}.  Note that
  19.174 +         * this rounding mode never increases the calculated value.
  19.175 +         *
  19.176 +         *<p>Example:
  19.177 +         *<table border>
  19.178 +         *<tr valign=top><th>Input Number</th>
  19.179 +         *    <th>Input rounded to one digit<br> with {@code FLOOR} rounding
  19.180 +         *<tr align=right><td>5.5</td>  <td>5</td>
  19.181 +         *<tr align=right><td>2.5</td>  <td>2</td>
  19.182 +         *<tr align=right><td>1.6</td>  <td>1</td>
  19.183 +         *<tr align=right><td>1.1</td>  <td>1</td>
  19.184 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.185 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.186 +         *<tr align=right><td>-1.1</td> <td>-2</td>
  19.187 +         *<tr align=right><td>-1.6</td> <td>-2</td>
  19.188 +         *<tr align=right><td>-2.5</td> <td>-3</td>
  19.189 +         *<tr align=right><td>-5.5</td> <td>-6</td>
  19.190 +         *</table>
  19.191 +         */
  19.192 +    FLOOR(BigDecimal.ROUND_FLOOR),
  19.193 +
  19.194 +        /**
  19.195 +         * Rounding mode to round towards {@literal "nearest neighbor"}
  19.196 +         * unless both neighbors are equidistant, in which case round up.
  19.197 +         * Behaves as for {@code RoundingMode.UP} if the discarded
  19.198 +         * fraction is &ge; 0.5; otherwise, behaves as for
  19.199 +         * {@code RoundingMode.DOWN}.  Note that this is the rounding
  19.200 +         * mode commonly taught at school.
  19.201 +         *
  19.202 +         *<p>Example:
  19.203 +         *<table border>
  19.204 +         *<tr valign=top><th>Input Number</th>
  19.205 +         *    <th>Input rounded to one digit<br> with {@code HALF_UP} rounding
  19.206 +         *<tr align=right><td>5.5</td>  <td>6</td>
  19.207 +         *<tr align=right><td>2.5</td>  <td>3</td>
  19.208 +         *<tr align=right><td>1.6</td>  <td>2</td>
  19.209 +         *<tr align=right><td>1.1</td>  <td>1</td>
  19.210 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.211 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.212 +         *<tr align=right><td>-1.1</td> <td>-1</td>
  19.213 +         *<tr align=right><td>-1.6</td> <td>-2</td>
  19.214 +         *<tr align=right><td>-2.5</td> <td>-3</td>
  19.215 +         *<tr align=right><td>-5.5</td> <td>-6</td>
  19.216 +         *</table>
  19.217 +         */
  19.218 +    HALF_UP(BigDecimal.ROUND_HALF_UP),
  19.219 +
  19.220 +        /**
  19.221 +         * Rounding mode to round towards {@literal "nearest neighbor"}
  19.222 +         * unless both neighbors are equidistant, in which case round
  19.223 +         * down.  Behaves as for {@code RoundingMode.UP} if the discarded
  19.224 +         * fraction is &gt; 0.5; otherwise, behaves as for
  19.225 +         * {@code RoundingMode.DOWN}.
  19.226 +         *
  19.227 +         *<p>Example:
  19.228 +         *<table border>
  19.229 +         *<tr valign=top><th>Input Number</th>
  19.230 +         *    <th>Input rounded to one digit<br> with {@code HALF_DOWN} rounding
  19.231 +         *<tr align=right><td>5.5</td>  <td>5</td>
  19.232 +         *<tr align=right><td>2.5</td>  <td>2</td>
  19.233 +         *<tr align=right><td>1.6</td>  <td>2</td>
  19.234 +         *<tr align=right><td>1.1</td>  <td>1</td>
  19.235 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.236 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.237 +         *<tr align=right><td>-1.1</td> <td>-1</td>
  19.238 +         *<tr align=right><td>-1.6</td> <td>-2</td>
  19.239 +         *<tr align=right><td>-2.5</td> <td>-2</td>
  19.240 +         *<tr align=right><td>-5.5</td> <td>-5</td>
  19.241 +         *</table>
  19.242 +         */
  19.243 +    HALF_DOWN(BigDecimal.ROUND_HALF_DOWN),
  19.244 +
  19.245 +        /**
  19.246 +         * Rounding mode to round towards the {@literal "nearest neighbor"}
  19.247 +         * unless both neighbors are equidistant, in which case, round
  19.248 +         * towards the even neighbor.  Behaves as for
  19.249 +         * {@code RoundingMode.HALF_UP} if the digit to the left of the
  19.250 +         * discarded fraction is odd; behaves as for
  19.251 +         * {@code RoundingMode.HALF_DOWN} if it's even.  Note that this
  19.252 +         * is the rounding mode that statistically minimizes cumulative
  19.253 +         * error when applied repeatedly over a sequence of calculations.
  19.254 +         * It is sometimes known as {@literal "Banker's rounding,"} and is
  19.255 +         * chiefly used in the USA.  This rounding mode is analogous to
  19.256 +         * the rounding policy used for {@code float} and {@code double}
  19.257 +         * arithmetic in Java.
  19.258 +         *
  19.259 +         *<p>Example:
  19.260 +         *<table border>
  19.261 +         *<tr valign=top><th>Input Number</th>
  19.262 +         *    <th>Input rounded to one digit<br> with {@code HALF_EVEN} rounding
  19.263 +         *<tr align=right><td>5.5</td>  <td>6</td>
  19.264 +         *<tr align=right><td>2.5</td>  <td>2</td>
  19.265 +         *<tr align=right><td>1.6</td>  <td>2</td>
  19.266 +         *<tr align=right><td>1.1</td>  <td>1</td>
  19.267 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.268 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.269 +         *<tr align=right><td>-1.1</td> <td>-1</td>
  19.270 +         *<tr align=right><td>-1.6</td> <td>-2</td>
  19.271 +         *<tr align=right><td>-2.5</td> <td>-2</td>
  19.272 +         *<tr align=right><td>-5.5</td> <td>-6</td>
  19.273 +         *</table>
  19.274 +         */
  19.275 +    HALF_EVEN(BigDecimal.ROUND_HALF_EVEN),
  19.276 +
  19.277 +        /**
  19.278 +         * Rounding mode to assert that the requested operation has an exact
  19.279 +         * result, hence no rounding is necessary.  If this rounding mode is
  19.280 +         * specified on an operation that yields an inexact result, an
  19.281 +         * {@code ArithmeticException} is thrown.
  19.282 +         *<p>Example:
  19.283 +         *<table border>
  19.284 +         *<tr valign=top><th>Input Number</th>
  19.285 +         *    <th>Input rounded to one digit<br> with {@code UNNECESSARY} rounding
  19.286 +         *<tr align=right><td>5.5</td>  <td>throw {@code ArithmeticException}</td>
  19.287 +         *<tr align=right><td>2.5</td>  <td>throw {@code ArithmeticException}</td>
  19.288 +         *<tr align=right><td>1.6</td>  <td>throw {@code ArithmeticException}</td>
  19.289 +         *<tr align=right><td>1.1</td>  <td>throw {@code ArithmeticException}</td>
  19.290 +         *<tr align=right><td>1.0</td>  <td>1</td>
  19.291 +         *<tr align=right><td>-1.0</td> <td>-1</td>
  19.292 +         *<tr align=right><td>-1.1</td> <td>throw {@code ArithmeticException}</td>
  19.293 +         *<tr align=right><td>-1.6</td> <td>throw {@code ArithmeticException}</td>
  19.294 +         *<tr align=right><td>-2.5</td> <td>throw {@code ArithmeticException}</td>
  19.295 +         *<tr align=right><td>-5.5</td> <td>throw {@code ArithmeticException}</td>
  19.296 +         *</table>
  19.297 +         */
  19.298 +    UNNECESSARY(BigDecimal.ROUND_UNNECESSARY);
  19.299 +
  19.300 +    // Corresponding BigDecimal rounding constant
  19.301 +    final int oldMode;
  19.302 +
  19.303 +    /**
  19.304 +     * Constructor
  19.305 +     *
  19.306 +     * @param oldMode The {@code BigDecimal} constant corresponding to
  19.307 +     *        this mode
  19.308 +     */
  19.309 +    private RoundingMode(int oldMode) {
  19.310 +        this.oldMode = oldMode;
  19.311 +    }
  19.312 +
  19.313 +    /**
  19.314 +     * Returns the {@code RoundingMode} object corresponding to a
  19.315 +     * legacy integer rounding mode constant in {@link BigDecimal}.
  19.316 +     *
  19.317 +     * @param  rm legacy integer rounding mode to convert
  19.318 +     * @return {@code RoundingMode} corresponding to the given integer.
  19.319 +     * @throws IllegalArgumentException integer is out of range
  19.320 +     */
  19.321 +    public static RoundingMode valueOf(int rm) {
  19.322 +        switch(rm) {
  19.323 +
  19.324 +        case BigDecimal.ROUND_UP:
  19.325 +            return UP;
  19.326 +
  19.327 +        case BigDecimal.ROUND_DOWN:
  19.328 +            return DOWN;
  19.329 +
  19.330 +        case BigDecimal.ROUND_CEILING:
  19.331 +            return CEILING;
  19.332 +
  19.333 +        case BigDecimal.ROUND_FLOOR:
  19.334 +            return FLOOR;
  19.335 +
  19.336 +        case BigDecimal.ROUND_HALF_UP:
  19.337 +            return HALF_UP;
  19.338 +
  19.339 +        case BigDecimal.ROUND_HALF_DOWN:
  19.340 +            return HALF_DOWN;
  19.341 +
  19.342 +        case BigDecimal.ROUND_HALF_EVEN:
  19.343 +            return HALF_EVEN;
  19.344 +
  19.345 +        case BigDecimal.ROUND_UNNECESSARY:
  19.346 +            return UNNECESSARY;
  19.347 +
  19.348 +        default:
  19.349 +            throw new IllegalArgumentException("argument out of range");
  19.350 +        }
  19.351 +    }
  19.352 +}
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/rt/emul/compact/src/main/java/java/math/SignedMutableBigInteger.java	Sat Sep 07 13:55:09 2013 +0200
    20.3 @@ -0,0 +1,135 @@
    20.4 +/*
    20.5 + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
    20.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    20.7 + *
    20.8 + * This code is free software; you can redistribute it and/or modify it
    20.9 + * under the terms of the GNU General Public License version 2 only, as
   20.10 + * published by the Free Software Foundation.  Oracle designates this
   20.11 + * particular file as subject to the "Classpath" exception as provided
   20.12 + * by Oracle in the LICENSE file that accompanied this code.
   20.13 + *
   20.14 + * This code is distributed in the hope that it will be useful, but WITHOUT
   20.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   20.16 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   20.17 + * version 2 for more details (a copy is included in the LICENSE file that
   20.18 + * accompanied this code).
   20.19 + *
   20.20 + * You should have received a copy of the GNU General Public License version
   20.21 + * 2 along with this work; if not, write to the Free Software Foundation,
   20.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20.23 + *
   20.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   20.25 + * or visit www.oracle.com if you need additional information or have any
   20.26 + * questions.
   20.27 + */
   20.28 +
   20.29 +package java.math;
   20.30 +
   20.31 +/**
   20.32 + * A class used to represent multiprecision integers that makes efficient
   20.33 + * use of allocated space by allowing a number to occupy only part of
   20.34 + * an array so that the arrays do not have to be reallocated as often.
   20.35 + * When performing an operation with many iterations the array used to
   20.36 + * hold a number is only increased when necessary and does not have to
   20.37 + * be the same size as the number it represents. A mutable number allows
   20.38 + * calculations to occur on the same number without having to create
   20.39 + * a new number for every step of the calculation as occurs with
   20.40 + * BigIntegers.
   20.41 + *
   20.42 + * Note that SignedMutableBigIntegers only support signed addition and
   20.43 + * subtraction. All other operations occur as with MutableBigIntegers.
   20.44 + *
   20.45 + * @see     BigInteger
   20.46 + * @author  Michael McCloskey
   20.47 + * @since   1.3
   20.48 + */
   20.49 +
   20.50 +class SignedMutableBigInteger extends MutableBigInteger {
   20.51 +
   20.52 +   /**
   20.53 +     * The sign of this MutableBigInteger.
   20.54 +     */
   20.55 +    int sign = 1;
   20.56 +
   20.57 +    // Constructors
   20.58 +
   20.59 +    /**
   20.60 +     * The default constructor. An empty MutableBigInteger is created with
   20.61 +     * a one word capacity.
   20.62 +     */
   20.63 +    SignedMutableBigInteger() {
   20.64 +        super();
   20.65 +    }
   20.66 +
   20.67 +    /**
   20.68 +     * Construct a new MutableBigInteger with a magnitude specified by
   20.69 +     * the int val.
   20.70 +     */
   20.71 +    SignedMutableBigInteger(int val) {
   20.72 +        super(val);
   20.73 +    }
   20.74 +
   20.75 +    /**
   20.76 +     * Construct a new MutableBigInteger with a magnitude equal to the
   20.77 +     * specified MutableBigInteger.
   20.78 +     */
   20.79 +    SignedMutableBigInteger(MutableBigInteger val) {
   20.80 +        super(val);
   20.81 +    }
   20.82 +
   20.83 +   // Arithmetic Operations
   20.84 +
   20.85 +   /**
   20.86 +     * Signed addition built upon unsigned add and subtract.
   20.87 +     */
   20.88 +    void signedAdd(SignedMutableBigInteger addend) {
   20.89 +        if (sign == addend.sign)
   20.90 +            add(addend);
   20.91 +        else
   20.92 +            sign = sign * subtract(addend);
   20.93 +
   20.94 +    }
   20.95 +
   20.96 +   /**
   20.97 +     * Signed addition built upon unsigned add and subtract.
   20.98 +     */
   20.99 +    void signedAdd(MutableBigInteger addend) {
  20.100 +        if (sign == 1)
  20.101 +            add(addend);
  20.102 +        else
  20.103 +            sign = sign * subtract(addend);
  20.104 +
  20.105 +    }
  20.106 +
  20.107 +   /**
  20.108 +     * Signed subtraction built upon unsigned add and subtract.
  20.109 +     */
  20.110 +    void signedSubtract(SignedMutableBigInteger addend) {
  20.111 +        if (sign == addend.sign)
  20.112 +            sign = sign * subtract(addend);
  20.113 +        else
  20.114 +            add(addend);
  20.115 +
  20.116 +    }
  20.117 +
  20.118 +   /**
  20.119 +     * Signed subtraction built upon unsigned add and subtract.
  20.120 +     */
  20.121 +    void signedSubtract(MutableBigInteger addend) {
  20.122 +        if (sign == 1)
  20.123 +            sign = sign * subtract(addend);
  20.124 +        else
  20.125 +            add(addend);
  20.126 +        if (intLen == 0)
  20.127 +             sign = 1;
  20.128 +    }
  20.129 +
  20.130 +    /**
  20.131 +     * Print out the first intLen ints of this MutableBigInteger's value
  20.132 +     * array starting at offset.
  20.133 +     */
  20.134 +    public String toString() {
  20.135 +        return this.toBigInteger(sign).toString();
  20.136 +    }
  20.137 +
  20.138 +}
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/rt/emul/compact/src/main/java/java/math/package-info.java	Sat Sep 07 13:55:09 2013 +0200
    21.3 @@ -0,0 +1,45 @@
    21.4 +/*
    21.5 + * Copyright (c) 1998, 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 +/**
   21.30 + * Provides classes for performing arbitrary-precision integer
   21.31 + * arithmetic ({@code BigInteger}) and arbitrary-precision decimal
   21.32 + * arithmetic ({@code BigDecimal}).  {@code BigInteger} is analogous
   21.33 + * to the primitive integer types except that it provides arbitrary
   21.34 + * precision, hence operations on {@code BigInteger}s do not overflow
   21.35 + * or lose precision.  In addition to standard arithmetic operations,
   21.36 + * {@code BigInteger} provides modular arithmetic, GCD calculation,
   21.37 + * primality testing, prime generation, bit manipulation, and a few
   21.38 + * other miscellaneous operations.
   21.39 + *
   21.40 + * {@code BigDecimal} provides arbitrary-precision signed decimal
   21.41 + * numbers suitable for currency calculations and the like.  {@code
   21.42 + * BigDecimal} gives the user complete control over rounding behavior,
   21.43 + * allowing the user to choose from a comprehensive set of eight
   21.44 + * rounding modes.
   21.45 + *
   21.46 + * @since JDK1.1
   21.47 + */
   21.48 +package java.math;
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/rt/emul/compact/src/main/java/java/net/URI.java	Sat Sep 07 13:55:09 2013 +0200
    22.3 @@ -0,0 +1,3524 @@
    22.4 +/*
    22.5 + * Copyright (c) 2000, 2011, 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.net;
   22.30 +
   22.31 +import java.io.IOException;
   22.32 +import java.io.InvalidObjectException;
   22.33 +import java.io.ObjectInputStream;
   22.34 +import java.io.ObjectOutputStream;
   22.35 +import java.io.Serializable;
   22.36 +import java.nio.ByteBuffer;
   22.37 +import java.nio.CharBuffer;
   22.38 +import java.nio.charset.CharsetDecoder;
   22.39 +import java.nio.charset.CharsetEncoder;
   22.40 +import java.nio.charset.CoderResult;
   22.41 +import java.nio.charset.CodingErrorAction;
   22.42 +import java.nio.charset.CharacterCodingException;
   22.43 +import java.text.Normalizer;
   22.44 +import sun.nio.cs.ThreadLocalCoders;
   22.45 +
   22.46 +import java.lang.Character;             // for javadoc
   22.47 +import java.lang.NullPointerException;  // for javadoc
   22.48 +
   22.49 +
   22.50 +/**
   22.51 + * Represents a Uniform Resource Identifier (URI) reference.
   22.52 + *
   22.53 + * <p> Aside from some minor deviations noted below, an instance of this
   22.54 + * class represents a URI reference as defined by
   22.55 + * <a href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform
   22.56 + * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a
   22.57 + * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for
   22.58 + * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format
   22.59 + * also supports scope_ids. The syntax and usage of scope_ids is described
   22.60 + * <a href="Inet6Address.html#scoped">here</a>.
   22.61 + * This class provides constructors for creating URI instances from
   22.62 + * their components or by parsing their string forms, methods for accessing the
   22.63 + * various components of an instance, and methods for normalizing, resolving,
   22.64 + * and relativizing URI instances.  Instances of this class are immutable.
   22.65 + *
   22.66 + *
   22.67 + * <h4> URI syntax and components </h4>
   22.68 + *
   22.69 + * At the highest level a URI reference (hereinafter simply "URI") in string
   22.70 + * form has the syntax
   22.71 + *
   22.72 + * <blockquote>
   22.73 + * [<i>scheme</i><tt><b>:</b></tt><i></i>]<i>scheme-specific-part</i>[<tt><b>#</b></tt><i>fragment</i>]
   22.74 + * </blockquote>
   22.75 + *
   22.76 + * where square brackets [...] delineate optional components and the characters
   22.77 + * <tt><b>:</b></tt> and <tt><b>#</b></tt> stand for themselves.
   22.78 + *
   22.79 + * <p> An <i>absolute</i> URI specifies a scheme; a URI that is not absolute is
   22.80 + * said to be <i>relative</i>.  URIs are also classified according to whether
   22.81 + * they are <i>opaque</i> or <i>hierarchical</i>.
   22.82 + *
   22.83 + * <p> An <i>opaque</i> URI is an absolute URI whose scheme-specific part does
   22.84 + * not begin with a slash character (<tt>'/'</tt>).  Opaque URIs are not
   22.85 + * subject to further parsing.  Some examples of opaque URIs are:
   22.86 + *
   22.87 + * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
   22.88 + * <tr><td><tt>mailto:java-net@java.sun.com</tt><td></tr>
   22.89 + * <tr><td><tt>news:comp.lang.java</tt><td></tr>
   22.90 + * <tr><td><tt>urn:isbn:096139210x</tt></td></tr>
   22.91 + * </table></blockquote>
   22.92 + *
   22.93 + * <p> A <i>hierarchical</i> URI is either an absolute URI whose
   22.94 + * scheme-specific part begins with a slash character, or a relative URI, that
   22.95 + * is, a URI that does not specify a scheme.  Some examples of hierarchical
   22.96 + * URIs are:
   22.97 + *
   22.98 + * <blockquote>
   22.99 + * <tt>http://java.sun.com/j2se/1.3/</tt><br>
  22.100 + * <tt>docs/guide/collections/designfaq.html#28</tt><br>
  22.101 + * <tt>../../../demo/jfc/SwingSet2/src/SwingSet2.java</tt><br>
  22.102 + * <tt>file:///~/calendar</tt>
  22.103 + * </blockquote>
  22.104 + *
  22.105 + * <p> A hierarchical URI is subject to further parsing according to the syntax
  22.106 + *
  22.107 + * <blockquote>
  22.108 + * [<i>scheme</i><tt><b>:</b></tt>][<tt><b>//</b></tt><i>authority</i>][<i>path</i>][<tt><b>?</b></tt><i>query</i>][<tt><b>#</b></tt><i>fragment</i>]
  22.109 + * </blockquote>
  22.110 + *
  22.111 + * where the characters <tt><b>:</b></tt>, <tt><b>/</b></tt>,
  22.112 + * <tt><b>?</b></tt>, and <tt><b>#</b></tt> stand for themselves.  The
  22.113 + * scheme-specific part of a hierarchical URI consists of the characters
  22.114 + * between the scheme and fragment components.
  22.115 + *
  22.116 + * <p> The authority component of a hierarchical URI is, if specified, either
  22.117 + * <i>server-based</i> or <i>registry-based</i>.  A server-based authority
  22.118 + * parses according to the familiar syntax
  22.119 + *
  22.120 + * <blockquote>
  22.121 + * [<i>user-info</i><tt><b>@</b></tt>]<i>host</i>[<tt><b>:</b></tt><i>port</i>]
  22.122 + * </blockquote>
  22.123 + *
  22.124 + * where the characters <tt><b>@</b></tt> and <tt><b>:</b></tt> stand for
  22.125 + * themselves.  Nearly all URI schemes currently in use are server-based.  An
  22.126 + * authority component that does not parse in this way is considered to be
  22.127 + * registry-based.
  22.128 + *
  22.129 + * <p> The path component of a hierarchical URI is itself said to be absolute
  22.130 + * if it begins with a slash character (<tt>'/'</tt>); otherwise it is
  22.131 + * relative.  The path of a hierarchical URI that is either absolute or
  22.132 + * specifies an authority is always absolute.
  22.133 + *
  22.134 + * <p> All told, then, a URI instance has the following nine components:
  22.135 + *
  22.136 + * <blockquote><table summary="Describes the components of a URI:scheme,scheme-specific-part,authority,user-info,host,port,path,query,fragment">
  22.137 + * <tr><th><i>Component</i></th><th><i>Type</i></th></tr>
  22.138 + * <tr><td>scheme</td><td><tt>String</tt></td></tr>
  22.139 + * <tr><td>scheme-specific-part&nbsp;&nbsp;&nbsp;&nbsp;</td><td><tt>String</tt></td></tr>
  22.140 + * <tr><td>authority</td><td><tt>String</tt></td></tr>
  22.141 + * <tr><td>user-info</td><td><tt>String</tt></td></tr>
  22.142 + * <tr><td>host</td><td><tt>String</tt></td></tr>
  22.143 + * <tr><td>port</td><td><tt>int</tt></td></tr>
  22.144 + * <tr><td>path</td><td><tt>String</tt></td></tr>
  22.145 + * <tr><td>query</td><td><tt>String</tt></td></tr>
  22.146 + * <tr><td>fragment</td><td><tt>String</tt></td></tr>
  22.147 + * </table></blockquote>
  22.148 + *
  22.149 + * In a given instance any particular component is either <i>undefined</i> or
  22.150 + * <i>defined</i> with a distinct value.  Undefined string components are
  22.151 + * represented by <tt>null</tt>, while undefined integer components are
  22.152 + * represented by <tt>-1</tt>.  A string component may be defined to have the
  22.153 + * empty string as its value; this is not equivalent to that component being
  22.154 + * undefined.
  22.155 + *
  22.156 + * <p> Whether a particular component is or is not defined in an instance
  22.157 + * depends upon the type of the URI being represented.  An absolute URI has a
  22.158 + * scheme component.  An opaque URI has a scheme, a scheme-specific part, and
  22.159 + * possibly a fragment, but has no other components.  A hierarchical URI always
  22.160 + * has a path (though it may be empty) and a scheme-specific-part (which at
  22.161 + * least contains the path), and may have any of the other components.  If the
  22.162 + * authority component is present and is server-based then the host component
  22.163 + * will be defined and the user-information and port components may be defined.
  22.164 + *
  22.165 + *
  22.166 + * <h4> Operations on URI instances </h4>
  22.167 + *
  22.168 + * The key operations supported by this class are those of
  22.169 + * <i>normalization</i>, <i>resolution</i>, and <i>relativization</i>.
  22.170 + *
  22.171 + * <p> <i>Normalization</i> is the process of removing unnecessary <tt>"."</tt>
  22.172 + * and <tt>".."</tt> segments from the path component of a hierarchical URI.
  22.173 + * Each <tt>"."</tt> segment is simply removed.  A <tt>".."</tt> segment is
  22.174 + * removed only if it is preceded by a non-<tt>".."</tt> segment.
  22.175 + * Normalization has no effect upon opaque URIs.
  22.176 + *
  22.177 + * <p> <i>Resolution</i> is the process of resolving one URI against another,
  22.178 + * <i>base</i> URI.  The resulting URI is constructed from components of both
  22.179 + * URIs in the manner specified by RFC&nbsp;2396, taking components from the
  22.180 + * base URI for those not specified in the original.  For hierarchical URIs,
  22.181 + * the path of the original is resolved against the path of the base and then
  22.182 + * normalized.  The result, for example, of resolving
  22.183 + *
  22.184 + * <blockquote>
  22.185 + * <tt>docs/guide/collections/designfaq.html#28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt>(1)
  22.186 + * </blockquote>
  22.187 + *
  22.188 + * against the base URI <tt>http://java.sun.com/j2se/1.3/</tt> is the result
  22.189 + * URI
  22.190 + *
  22.191 + * <blockquote>
  22.192 + * <tt>http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28</tt>
  22.193 + * </blockquote>
  22.194 + *
  22.195 + * Resolving the relative URI
  22.196 + *
  22.197 + * <blockquote>
  22.198 + * <tt>../../../demo/jfc/SwingSet2/src/SwingSet2.java&nbsp;&nbsp;&nbsp;&nbsp;</tt>(2)
  22.199 + * </blockquote>
  22.200 + *
  22.201 + * against this result yields, in turn,
  22.202 + *
  22.203 + * <blockquote>
  22.204 + * <tt>http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java</tt>
  22.205 + * </blockquote>
  22.206 + *
  22.207 + * Resolution of both absolute and relative URIs, and of both absolute and
  22.208 + * relative paths in the case of hierarchical URIs, is supported.  Resolving
  22.209 + * the URI <tt>file:///~calendar</tt> against any other URI simply yields the
  22.210 + * original URI, since it is absolute.  Resolving the relative URI (2) above
  22.211 + * against the relative base URI (1) yields the normalized, but still relative,
  22.212 + * URI
  22.213 + *
  22.214 + * <blockquote>
  22.215 + * <tt>demo/jfc/SwingSet2/src/SwingSet2.java</tt>
  22.216 + * </blockquote>
  22.217 + *
  22.218 + * <p> <i>Relativization</i>, finally, is the inverse of resolution: For any
  22.219 + * two normalized URIs <i>u</i> and&nbsp;<i>v</i>,
  22.220 + *
  22.221 + * <blockquote>
  22.222 + *   <i>u</i><tt>.relativize(</tt><i>u</i><tt>.resolve(</tt><i>v</i><tt>)).equals(</tt><i>v</i><tt>)</tt>&nbsp;&nbsp;and<br>
  22.223 + *   <i>u</i><tt>.resolve(</tt><i>u</i><tt>.relativize(</tt><i>v</i><tt>)).equals(</tt><i>v</i><tt>)</tt>&nbsp;&nbsp;.<br>
  22.224 + * </blockquote>
  22.225 + *
  22.226 + * This operation is often useful when constructing a document containing URIs
  22.227 + * that must be made relative to the base URI of the document wherever
  22.228 + * possible.  For example, relativizing the URI
  22.229 + *
  22.230 + * <blockquote>
  22.231 + * <tt>http://java.sun.com/j2se/1.3/docs/guide/index.html</tt>
  22.232 + * </blockquote>
  22.233 + *
  22.234 + * against the base URI
  22.235 + *
  22.236 + * <blockquote>
  22.237 + * <tt>http://java.sun.com/j2se/1.3</tt>
  22.238 + * </blockquote>
  22.239 + *
  22.240 + * yields the relative URI <tt>docs/guide/index.html</tt>.
  22.241 + *
  22.242 + *
  22.243 + * <h4> Character categories </h4>
  22.244 + *
  22.245 + * RFC&nbsp;2396 specifies precisely which characters are permitted in the
  22.246 + * various components of a URI reference.  The following categories, most of
  22.247 + * which are taken from that specification, are used below to describe these
  22.248 + * constraints:
  22.249 + *
  22.250 + * <blockquote><table cellspacing=2 summary="Describes categories alpha,digit,alphanum,unreserved,punct,reserved,escaped,and other">
  22.251 + *   <tr><th valign=top><i>alpha</i></th>
  22.252 + *       <td>The US-ASCII alphabetic characters,
  22.253 + *        <tt>'A'</tt>&nbsp;through&nbsp;<tt>'Z'</tt>
  22.254 + *        and <tt>'a'</tt>&nbsp;through&nbsp;<tt>'z'</tt></td></tr>
  22.255 + *   <tr><th valign=top><i>digit</i></th>
  22.256 + *       <td>The US-ASCII decimal digit characters,
  22.257 + *       <tt>'0'</tt>&nbsp;through&nbsp;<tt>'9'</tt></td></tr>
  22.258 + *   <tr><th valign=top><i>alphanum</i></th>
  22.259 + *       <td>All <i>alpha</i> and <i>digit</i> characters</td></tr>
  22.260 + *   <tr><th valign=top><i>unreserved</i>&nbsp;&nbsp;&nbsp;&nbsp;</th>
  22.261 + *       <td>All <i>alphanum</i> characters together with those in the string
  22.262 + *        <tt>"_-!.~'()*"</tt></td></tr>
  22.263 + *   <tr><th valign=top><i>punct</i></th>
  22.264 + *       <td>The characters in the string <tt>",;:$&+="</tt></td></tr>
  22.265 + *   <tr><th valign=top><i>reserved</i></th>
  22.266 + *       <td>All <i>punct</i> characters together with those in the string
  22.267 + *        <tt>"?/[]@"</tt></td></tr>
  22.268 + *   <tr><th valign=top><i>escaped</i></th>
  22.269 + *       <td>Escaped octets, that is, triplets consisting of the percent
  22.270 + *           character (<tt>'%'</tt>) followed by two hexadecimal digits
  22.271 + *           (<tt>'0'</tt>-<tt>'9'</tt>, <tt>'A'</tt>-<tt>'F'</tt>, and
  22.272 + *           <tt>'a'</tt>-<tt>'f'</tt>)</td></tr>
  22.273 + *   <tr><th valign=top><i>other</i></th>
  22.274 + *       <td>The Unicode characters that are not in the US-ASCII character set,
  22.275 + *           are not control characters (according to the {@link
  22.276 + *           java.lang.Character#isISOControl(char) Character.isISOControl}
  22.277 + *           method), and are not space characters (according to the {@link
  22.278 + *           java.lang.Character#isSpaceChar(char) Character.isSpaceChar}
  22.279 + *           method)&nbsp;&nbsp;<i>(<b>Deviation from RFC 2396</b>, which is
  22.280 + *           limited to US-ASCII)</i></td></tr>
  22.281 + * </table></blockquote>
  22.282 + *
  22.283 + * <p><a name="legal-chars"></a> The set of all legal URI characters consists of
  22.284 + * the <i>unreserved</i>, <i>reserved</i>, <i>escaped</i>, and <i>other</i>
  22.285 + * characters.
  22.286 + *
  22.287 + *
  22.288 + * <h4> Escaped octets, quotation, encoding, and decoding </h4>
  22.289 + *
  22.290 + * RFC 2396 allows escaped octets to appear in the user-info, path, query, and
  22.291 + * fragment components.  Escaping serves two purposes in URIs:
  22.292 + *
  22.293 + * <ul>
  22.294 + *
  22.295 + *   <li><p> To <i>encode</i> non-US-ASCII characters when a URI is required to
  22.296 + *   conform strictly to RFC&nbsp;2396 by not containing any <i>other</i>
  22.297 + *   characters.  </p></li>
  22.298 + *
  22.299 + *   <li><p> To <i>quote</i> characters that are otherwise illegal in a
  22.300 + *   component.  The user-info, path, query, and fragment components differ
  22.301 + *   slightly in terms of which characters are considered legal and illegal.
  22.302 + *   </p></li>
  22.303 + *
  22.304 + * </ul>
  22.305 + *
  22.306 + * These purposes are served in this class by three related operations:
  22.307 + *
  22.308 + * <ul>
  22.309 + *
  22.310 + *   <li><p><a name="encode"></a> A character is <i>encoded</i> by replacing it
  22.311 + *   with the sequence of escaped octets that represent that character in the
  22.312 + *   UTF-8 character set.  The Euro currency symbol (<tt>'&#92;u20AC'</tt>),
  22.313 + *   for example, is encoded as <tt>"%E2%82%AC"</tt>.  <i>(<b>Deviation from
  22.314 + *   RFC&nbsp;2396</b>, which does not specify any particular character
  22.315 + *   set.)</i> </p></li>
  22.316 + *
  22.317 + *   <li><p><a name="quote"></a> An illegal character is <i>quoted</i> simply by
  22.318 + *   encoding it.  The space character, for example, is quoted by replacing it
  22.319 + *   with <tt>"%20"</tt>.  UTF-8 contains US-ASCII, hence for US-ASCII
  22.320 + *   characters this transformation has exactly the effect required by
  22.321 + *   RFC&nbsp;2396. </p></li>
  22.322 + *
  22.323 + *   <li><p><a name="decode"></a>
  22.324 + *   A sequence of escaped octets is <i>decoded</i> by
  22.325 + *   replacing it with the sequence of characters that it represents in the
  22.326 + *   UTF-8 character set.  UTF-8 contains US-ASCII, hence decoding has the
  22.327 + *   effect of de-quoting any quoted US-ASCII characters as well as that of
  22.328 + *   decoding any encoded non-US-ASCII characters.  If a <a
  22.329 + *   href="../nio/charset/CharsetDecoder.html#ce">decoding error</a> occurs
  22.330 + *   when decoding the escaped octets then the erroneous octets are replaced by
  22.331 + *   <tt>'&#92;uFFFD'</tt>, the Unicode replacement character.  </p></li>
  22.332 + *
  22.333 + * </ul>
  22.334 + *
  22.335 + * These operations are exposed in the constructors and methods of this class
  22.336 + * as follows:
  22.337 + *
  22.338 + * <ul>
  22.339 + *
  22.340 + *   <li><p> The {@link #URI(java.lang.String) <code>single-argument
  22.341 + *   constructor</code>} requires any illegal characters in its argument to be
  22.342 + *   quoted and preserves any escaped octets and <i>other</i> characters that
  22.343 + *   are present.  </p></li>
  22.344 + *
  22.345 + *   <li><p> The {@link
  22.346 + *   #URI(java.lang.String,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String,java.lang.String)
  22.347 + *   <code>multi-argument constructors</code>} quote illegal characters as
  22.348 + *   required by the components in which they appear.  The percent character
  22.349 + *   (<tt>'%'</tt>) is always quoted by these constructors.  Any <i>other</i>
  22.350 + *   characters are preserved.  </p></li>
  22.351 + *
  22.352 + *   <li><p> The {@link #getRawUserInfo() getRawUserInfo}, {@link #getRawPath()
  22.353 + *   getRawPath}, {@link #getRawQuery() getRawQuery}, {@link #getRawFragment()
  22.354 + *   getRawFragment}, {@link #getRawAuthority() getRawAuthority}, and {@link
  22.355 + *   #getRawSchemeSpecificPart() getRawSchemeSpecificPart} methods return the
  22.356 + *   values of their corresponding components in raw form, without interpreting
  22.357 + *   any escaped octets.  The strings returned by these methods may contain
  22.358 + *   both escaped octets and <i>other</i> characters, and will not contain any
  22.359 + *   illegal characters.  </p></li>
  22.360 + *
  22.361 + *   <li><p> The {@link #getUserInfo() getUserInfo}, {@link #getPath()
  22.362 + *   getPath}, {@link #getQuery() getQuery}, {@link #getFragment()
  22.363 + *   getFragment}, {@link #getAuthority() getAuthority}, and {@link
  22.364 + *   #getSchemeSpecificPart() getSchemeSpecificPart} methods decode any escaped
  22.365 + *   octets in their corresponding components.  The strings returned by these
  22.366 + *   methods may contain both <i>other</i> characters and illegal characters,
  22.367 + *   and will not contain any escaped octets.  </p></li>
  22.368 + *
  22.369 + *   <li><p> The {@link #toString() toString} method returns a URI string with
  22.370 + *   all necessary quotation but which may contain <i>other</i> characters.
  22.371 + *   </p></li>
  22.372 + *
  22.373 + *   <li><p> The {@link #toASCIIString() toASCIIString} method returns a fully
  22.374 + *   quoted and encoded URI string that does not contain any <i>other</i>
  22.375 + *   characters.  </p></li>
  22.376 + *
  22.377 + * </ul>
  22.378 + *
  22.379 + *
  22.380 + * <h4> Identities </h4>
  22.381 + *
  22.382 + * For any URI <i>u</i>, it is always the case that
  22.383 + *
  22.384 + * <blockquote>
  22.385 + * <tt>new URI(</tt><i>u</i><tt>.toString()).equals(</tt><i>u</i><tt>)</tt>&nbsp;.
  22.386 + * </blockquote>
  22.387 + *
  22.388 + * For any URI <i>u</i> that does not contain redundant syntax such as two
  22.389 + * slashes before an empty authority (as in <tt>file:///tmp/</tt>&nbsp;) or a
  22.390 + * colon following a host name but no port (as in
  22.391 + * <tt>http://java.sun.com:</tt>&nbsp;), and that does not encode characters
  22.392 + * except those that must be quoted, the following identities also hold:
  22.393 + *
  22.394 + * <blockquote>
  22.395 + * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br>
  22.396 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getSchemeSpecificPart(),<br>
  22.397 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getFragment())<br>
  22.398 + * .equals(</tt><i>u</i><tt>)</tt>
  22.399 + * </blockquote>
  22.400 + *
  22.401 + * in all cases,
  22.402 + *
  22.403 + * <blockquote>
  22.404 + * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br>
  22.405 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getUserInfo(),&nbsp;</tt><i>u</i><tt>.getAuthority(),<br>
  22.406 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getPath(),&nbsp;</tt><i>u</i><tt>.getQuery(),<br>
  22.407 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getFragment())<br>
  22.408 + * .equals(</tt><i>u</i><tt>)</tt>
  22.409 + * </blockquote>
  22.410 + *
  22.411 + * if <i>u</i> is hierarchical, and
  22.412 + *
  22.413 + * <blockquote>
  22.414 + * <tt>new URI(</tt><i>u</i><tt>.getScheme(),<br>
  22.415 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getUserInfo(),&nbsp;</tt><i>u</i><tt>.getHost(),&nbsp;</tt><i>u</i><tt>.getPort(),<br>
  22.416 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getPath(),&nbsp;</tt><i>u</i><tt>.getQuery(),<br>
  22.417 + * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt><i>u</i><tt>.getFragment())<br>
  22.418 + * .equals(</tt><i>u</i><tt>)</tt>
  22.419 + * </blockquote>
  22.420 + *
  22.421 + * if <i>u</i> is hierarchical and has either no authority or a server-based
  22.422 + * authority.
  22.423 + *
  22.424 + *
  22.425 + * <h4> URIs, URLs, and URNs </h4>
  22.426 + *
  22.427 + * A URI is a uniform resource <i>identifier</i> while a URL is a uniform
  22.428 + * resource <i>locator</i>.  Hence every URL is a URI, abstractly speaking, but
  22.429 + * not every URI is a URL.  This is because there is another subcategory of
  22.430 + * URIs, uniform resource <i>names</i> (URNs), which name resources but do not
  22.431 + * specify how to locate them.  The <tt>mailto</tt>, <tt>news</tt>, and
  22.432 + * <tt>isbn</tt> URIs shown above are examples of URNs.
  22.433 + *
  22.434 + * <p> The conceptual distinction between URIs and URLs is reflected in the
  22.435 + * differences between this class and the {@link URL} class.
  22.436 + *
  22.437 + * <p> An instance of this class represents a URI reference in the syntactic
  22.438 + * sense defined by RFC&nbsp;2396.  A URI may be either absolute or relative.
  22.439 + * A URI string is parsed according to the generic syntax without regard to the
  22.440 + * scheme, if any, that it specifies.  No lookup of the host, if any, is
  22.441 + * performed, and no scheme-dependent stream handler is constructed.  Equality,
  22.442 + * hashing, and comparison are defined strictly in terms of the character
  22.443 + * content of the instance.  In other words, a URI instance is little more than
  22.444 + * a structured string that supports the syntactic, scheme-independent
  22.445 + * operations of comparison, normalization, resolution, and relativization.
  22.446 + *
  22.447 + * <p> An instance of the {@link URL} class, by contrast, represents the
  22.448 + * syntactic components of a URL together with some of the information required
  22.449 + * to access the resource that it describes.  A URL must be absolute, that is,
  22.450 + * it must always specify a scheme.  A URL string is parsed according to its
  22.451 + * scheme.  A stream handler is always established for a URL, and in fact it is
  22.452 + * impossible to create a URL instance for a scheme for which no handler is
  22.453 + * available.  Equality and hashing depend upon both the scheme and the
  22.454 + * Internet address of the host, if any; comparison is not defined.  In other
  22.455 + * words, a URL is a structured string that supports the syntactic operation of
  22.456 + * resolution as well as the network I/O operations of looking up the host and
  22.457 + * opening a connection to the specified resource.
  22.458 + *
  22.459 + *
  22.460 + * @author Mark Reinhold
  22.461 + * @since 1.4
  22.462 + *
  22.463 + * @see <a href="http://www.ietf.org/rfc/rfc2279.txt"><i>RFC&nbsp;2279: UTF-8, a
  22.464 + * transformation format of ISO 10646</i></a>, <br><a
  22.465 + * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IPv6 Addressing
  22.466 + * Architecture</i></a>, <br><a
  22.467 + * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform
  22.468 + * Resource Identifiers (URI): Generic Syntax</i></a>, <br><a
  22.469 + * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for
  22.470 + * Literal IPv6 Addresses in URLs</i></a>, <br><a
  22.471 + * href="URISyntaxException.html">URISyntaxException</a>
  22.472 + */
  22.473 +
  22.474 +public final class URI
  22.475 +    implements Comparable<URI>, Serializable
  22.476 +{
  22.477 +
  22.478 +    // Note: Comments containing the word "ASSERT" indicate places where a
  22.479 +    // throw of an InternalError should be replaced by an appropriate assertion
  22.480 +    // statement once asserts are enabled in the build.
  22.481 +
  22.482 +    static final long serialVersionUID = -6052424284110960213L;
  22.483 +
  22.484 +
  22.485 +    // -- Properties and components of this instance --
  22.486 +
  22.487 +    // Components of all URIs: [<scheme>:]<scheme-specific-part>[#<fragment>]
  22.488 +    private transient String scheme;            // null ==> relative URI
  22.489 +    private transient String fragment;
  22.490 +
  22.491 +    // Hierarchical URI components: [//<authority>]<path>[?<query>]
  22.492 +    private transient String authority;         // Registry or server
  22.493 +
  22.494 +    // Server-based authority: [<userInfo>@]<host>[:<port>]
  22.495 +    private transient String userInfo;
  22.496 +    private transient String host;              // null ==> registry-based
  22.497 +    private transient int port = -1;            // -1 ==> undefined
  22.498 +
  22.499 +    // Remaining components of hierarchical URIs
  22.500 +    private transient String path;              // null ==> opaque
  22.501 +    private transient String query;
  22.502 +
  22.503 +    // The remaining fields may be computed on demand
  22.504 +
  22.505 +    private volatile transient String schemeSpecificPart;
  22.506 +    private volatile transient int hash;        // Zero ==> undefined
  22.507 +
  22.508 +    private volatile transient String decodedUserInfo = null;
  22.509 +    private volatile transient String decodedAuthority = null;
  22.510 +    private volatile transient String decodedPath = null;
  22.511 +    private volatile transient String decodedQuery = null;
  22.512 +    private volatile transient String decodedFragment = null;
  22.513 +    private volatile transient String decodedSchemeSpecificPart = null;
  22.514 +
  22.515 +    /**
  22.516 +     * The string form of this URI.
  22.517 +     *
  22.518 +     * @serial
  22.519 +     */
  22.520 +    private volatile String string;             // The only serializable field
  22.521 +
  22.522 +
  22.523 +
  22.524 +    // -- Constructors and factories --
  22.525 +
  22.526 +    private URI() { }                           // Used internally
  22.527 +
  22.528 +    /**
  22.529 +     * Constructs a URI by parsing the given string.
  22.530 +     *
  22.531 +     * <p> This constructor parses the given string exactly as specified by the
  22.532 +     * grammar in <a
  22.533 +     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
  22.534 +     * Appendix&nbsp;A, <b><i>except for the following deviations:</i></b> </p>
  22.535 +     *
  22.536 +     * <ul type=disc>
  22.537 +     *
  22.538 +     *   <li><p> An empty authority component is permitted as long as it is
  22.539 +     *   followed by a non-empty path, a query component, or a fragment
  22.540 +     *   component.  This allows the parsing of URIs such as
  22.541 +     *   <tt>"file:///foo/bar"</tt>, which seems to be the intent of
  22.542 +     *   RFC&nbsp;2396 although the grammar does not permit it.  If the
  22.543 +     *   authority component is empty then the user-information, host, and port
  22.544 +     *   components are undefined. </p></li>
  22.545 +     *
  22.546 +     *   <li><p> Empty relative paths are permitted; this seems to be the
  22.547 +     *   intent of RFC&nbsp;2396 although the grammar does not permit it.  The
  22.548 +     *   primary consequence of this deviation is that a standalone fragment
  22.549 +     *   such as <tt>"#foo"</tt> parses as a relative URI with an empty path
  22.550 +     *   and the given fragment, and can be usefully <a
  22.551 +     *   href="#resolve-frag">resolved</a> against a base URI.
  22.552 +     *
  22.553 +     *   <li><p> IPv4 addresses in host components are parsed rigorously, as
  22.554 +     *   specified by <a
  22.555 +     *   href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>: Each
  22.556 +     *   element of a dotted-quad address must contain no more than three
  22.557 +     *   decimal digits.  Each element is further constrained to have a value
  22.558 +     *   no greater than 255. </p></li>
  22.559 +     *
  22.560 +     *   <li> <p> Hostnames in host components that comprise only a single
  22.561 +     *   domain label are permitted to start with an <i>alphanum</i>
  22.562 +     *   character. This seems to be the intent of <a
  22.563 +     *   href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>
  22.564 +     *   section&nbsp;3.2.2 although the grammar does not permit it. The
  22.565 +     *   consequence of this deviation is that the authority component of a
  22.566 +     *   hierarchical URI such as <tt>s://123</tt>, will parse as a server-based
  22.567 +     *   authority. </p></li>
  22.568 +     *
  22.569 +     *   <li><p> IPv6 addresses are permitted for the host component.  An IPv6
  22.570 +     *   address must be enclosed in square brackets (<tt>'['</tt> and
  22.571 +     *   <tt>']'</tt>) as specified by <a
  22.572 +     *   href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>.  The
  22.573 +     *   IPv6 address itself must parse according to <a
  22.574 +     *   href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>.  IPv6
  22.575 +     *   addresses are further constrained to describe no more than sixteen
  22.576 +     *   bytes of address information, a constraint implicit in RFC&nbsp;2373
  22.577 +     *   but not expressible in the grammar. </p></li>
  22.578 +     *
  22.579 +     *   <li><p> Characters in the <i>other</i> category are permitted wherever
  22.580 +     *   RFC&nbsp;2396 permits <i>escaped</i> octets, that is, in the
  22.581 +     *   user-information, path, query, and fragment components, as well as in
  22.582 +     *   the authority component if the authority is registry-based.  This
  22.583 +     *   allows URIs to contain Unicode characters beyond those in the US-ASCII
  22.584 +     *   character set. </p></li>
  22.585 +     *
  22.586 +     * </ul>
  22.587 +     *
  22.588 +     * @param  str   The string to be parsed into a URI
  22.589 +     *
  22.590 +     * @throws  NullPointerException
  22.591 +     *          If <tt>str</tt> is <tt>null</tt>
  22.592 +     *
  22.593 +     * @throws  URISyntaxException
  22.594 +     *          If the given string violates RFC&nbsp;2396, as augmented
  22.595 +     *          by the above deviations
  22.596 +     */
  22.597 +    public URI(String str) throws URISyntaxException {
  22.598 +        new Parser(str).parse(false);
  22.599 +    }
  22.600 +
  22.601 +    /**
  22.602 +     * Constructs a hierarchical URI from the given components.
  22.603 +     *
  22.604 +     * <p> If a scheme is given then the path, if also given, must either be
  22.605 +     * empty or begin with a slash character (<tt>'/'</tt>).  Otherwise a
  22.606 +     * component of the new URI may be left undefined by passing <tt>null</tt>
  22.607 +     * for the corresponding parameter or, in the case of the <tt>port</tt>
  22.608 +     * parameter, by passing <tt>-1</tt>.
  22.609 +     *
  22.610 +     * <p> This constructor first builds a URI string from the given components
  22.611 +     * according to the rules specified in <a
  22.612 +     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
  22.613 +     * section&nbsp;5.2, step&nbsp;7: </p>
  22.614 +     *
  22.615 +     * <ol>
  22.616 +     *
  22.617 +     *   <li><p> Initially, the result string is empty. </p></li>
  22.618 +     *
  22.619 +     *   <li><p> If a scheme is given then it is appended to the result,
  22.620 +     *   followed by a colon character (<tt>':'</tt>).  </p></li>
  22.621 +     *
  22.622 +     *   <li><p> If user information, a host, or a port are given then the
  22.623 +     *   string <tt>"//"</tt> is appended.  </p></li>
  22.624 +     *
  22.625 +     *   <li><p> If user information is given then it is appended, followed by
  22.626 +     *   a commercial-at character (<tt>'@'</tt>).  Any character not in the
  22.627 +     *   <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
  22.628 +     *   categories is <a href="#quote">quoted</a>.  </p></li>
  22.629 +     *
  22.630 +     *   <li><p> If a host is given then it is appended.  If the host is a
  22.631 +     *   literal IPv6 address but is not enclosed in square brackets
  22.632 +     *   (<tt>'['</tt> and <tt>']'</tt>) then the square brackets are added.
  22.633 +     *   </p></li>
  22.634 +     *
  22.635 +     *   <li><p> If a port number is given then a colon character
  22.636 +     *   (<tt>':'</tt>) is appended, followed by the port number in decimal.
  22.637 +     *   </p></li>
  22.638 +     *
  22.639 +     *   <li><p> If a path is given then it is appended.  Any character not in
  22.640 +     *   the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
  22.641 +     *   categories, and not equal to the slash character (<tt>'/'</tt>) or the
  22.642 +     *   commercial-at character (<tt>'@'</tt>), is quoted.  </p></li>
  22.643 +     *
  22.644 +     *   <li><p> If a query is given then a question-mark character
  22.645 +     *   (<tt>'?'</tt>) is appended, followed by the query.  Any character that
  22.646 +     *   is not a <a href="#legal-chars">legal URI character</a> is quoted.
  22.647 +     *   </p></li>
  22.648 +     *
  22.649 +     *   <li><p> Finally, if a fragment is given then a hash character
  22.650 +     *   (<tt>'#'</tt>) is appended, followed by the fragment.  Any character
  22.651 +     *   that is not a legal URI character is quoted.  </p></li>
  22.652 +     *
  22.653 +     * </ol>
  22.654 +     *
  22.655 +     * <p> The resulting URI string is then parsed as if by invoking the {@link
  22.656 +     * #URI(String)} constructor and then invoking the {@link
  22.657 +     * #parseServerAuthority()} method upon the result; this may cause a {@link
  22.658 +     * URISyntaxException} to be thrown.  </p>
  22.659 +     *
  22.660 +     * @param   scheme    Scheme name
  22.661 +     * @param   userInfo  User name and authorization information
  22.662 +     * @param   host      Host name
  22.663 +     * @param   port      Port number
  22.664 +     * @param   path      Path
  22.665 +     * @param   query     Query
  22.666 +     * @param   fragment  Fragment
  22.667 +     *
  22.668 +     * @throws URISyntaxException
  22.669 +     *         If both a scheme and a path are given but the path is relative,
  22.670 +     *         if the URI string constructed from the given components violates
  22.671 +     *         RFC&nbsp;2396, or if the authority component of the string is
  22.672 +     *         present but cannot be parsed as a server-based authority
  22.673 +     */
  22.674 +    public URI(String scheme,
  22.675 +               String userInfo, String host, int port,
  22.676 +               String path, String query, String fragment)
  22.677 +        throws URISyntaxException
  22.678 +    {
  22.679 +        String s = toString(scheme, null,
  22.680 +                            null, userInfo, host, port,
  22.681 +                            path, query, fragment);
  22.682 +        checkPath(s, scheme, path);
  22.683 +        new Parser(s).parse(true);
  22.684 +    }
  22.685 +
  22.686 +    /**
  22.687 +     * Constructs a hierarchical URI from the given components.
  22.688 +     *
  22.689 +     * <p> If a scheme is given then the path, if also given, must either be
  22.690 +     * empty or begin with a slash character (<tt>'/'</tt>).  Otherwise a
  22.691 +     * component of the new URI may be left undefined by passing <tt>null</tt>
  22.692 +     * for the corresponding parameter.
  22.693 +     *
  22.694 +     * <p> This constructor first builds a URI string from the given components
  22.695 +     * according to the rules specified in <a
  22.696 +     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
  22.697 +     * section&nbsp;5.2, step&nbsp;7: </p>
  22.698 +     *
  22.699 +     * <ol>
  22.700 +     *
  22.701 +     *   <li><p> Initially, the result string is empty.  </p></li>
  22.702 +     *
  22.703 +     *   <li><p> If a scheme is given then it is appended to the result,
  22.704 +     *   followed by a colon character (<tt>':'</tt>).  </p></li>
  22.705 +     *
  22.706 +     *   <li><p> If an authority is given then the string <tt>"//"</tt> is
  22.707 +     *   appended, followed by the authority.  If the authority contains a
  22.708 +     *   literal IPv6 address then the address must be enclosed in square
  22.709 +     *   brackets (<tt>'['</tt> and <tt>']'</tt>).  Any character not in the
  22.710 +     *   <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
  22.711 +     *   categories, and not equal to the commercial-at character
  22.712 +     *   (<tt>'@'</tt>), is <a href="#quote">quoted</a>.  </p></li>
  22.713 +     *
  22.714 +     *   <li><p> If a path is given then it is appended.  Any character not in
  22.715 +     *   the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
  22.716 +     *   categories, and not equal to the slash character (<tt>'/'</tt>) or the
  22.717 +     *   commercial-at character (<tt>'@'</tt>), is quoted.  </p></li>
  22.718 +     *
  22.719 +     *   <li><p> If a query is given then a question-mark character
  22.720 +     *   (<tt>'?'</tt>) is appended, followed by the query.  Any character that
  22.721 +     *   is not a <a href="#legal-chars">legal URI character</a> is quoted.
  22.722 +     *   </p></li>
  22.723 +     *
  22.724 +     *   <li><p> Finally, if a fragment is given then a hash character
  22.725 +     *   (<tt>'#'</tt>) is appended, followed by the fragment.  Any character
  22.726 +     *   that is not a legal URI character is quoted.  </p></li>
  22.727 +     *
  22.728 +     * </ol>
  22.729 +     *
  22.730 +     * <p> The resulting URI string is then parsed as if by invoking the {@link
  22.731 +     * #URI(String)} constructor and then invoking the {@link
  22.732 +     * #parseServerAuthority()} method upon the result; this may cause a {@link
  22.733 +     * URISyntaxException} to be thrown.  </p>
  22.734 +     *
  22.735 +     * @param   scheme     Scheme name
  22.736 +     * @param   authority  Authority
  22.737 +     * @param   path       Path
  22.738 +     * @param   query      Query
  22.739 +     * @param   fragment   Fragment
  22.740 +     *
  22.741 +     * @throws URISyntaxException
  22.742 +     *         If both a scheme and a path are given but the path is relative,
  22.743 +     *         if the URI string constructed from the given components violates
  22.744 +     *         RFC&nbsp;2396, or if the authority component of the string is
  22.745 +     *         present but cannot be parsed as a server-based authority
  22.746 +     */
  22.747 +    public URI(String scheme,
  22.748 +               String authority,
  22.749 +               String path, String query, String fragment)
  22.750 +        throws URISyntaxException
  22.751 +    {
  22.752 +        String s = toString(scheme, null,
  22.753 +                            authority, null, null, -1,
  22.754 +                            path, query, fragment);
  22.755 +        checkPath(s, scheme, path);
  22.756 +        new Parser(s).parse(false);
  22.757 +    }
  22.758 +
  22.759 +    /**
  22.760 +     * Constructs a hierarchical URI from the given components.
  22.761 +     *
  22.762 +     * <p> A component may be left undefined by passing <tt>null</tt>.
  22.763 +     *
  22.764 +     * <p> This convenience constructor works as if by invoking the
  22.765 +     * seven-argument constructor as follows:
  22.766 +     *
  22.767 +     * <blockquote><tt>
  22.768 +     * new&nbsp;{@link #URI(String, String, String, int, String, String, String)
  22.769 +     * URI}(scheme,&nbsp;null,&nbsp;host,&nbsp;-1,&nbsp;path,&nbsp;null,&nbsp;fragment);
  22.770 +     * </tt></blockquote>
  22.771 +     *
  22.772 +     * @param   scheme    Scheme name
  22.773 +     * @param   host      Host name
  22.774 +     * @param   path      Path
  22.775 +     * @param   fragment  Fragment
  22.776 +     *
  22.777 +     * @throws  URISyntaxException
  22.778 +     *          If the URI string constructed from the given components
  22.779 +     *          violates RFC&nbsp;2396
  22.780 +     */
  22.781 +    public URI(String scheme, String host, String path, String fragment)
  22.782 +        throws URISyntaxException
  22.783 +    {
  22.784 +        this(scheme, null, host, -1, path, null, fragment);
  22.785 +    }
  22.786 +
  22.787 +    /**
  22.788 +     * Constructs a URI from the given components.
  22.789 +     *
  22.790 +     * <p> A component may be left undefined by passing <tt>null</tt>.
  22.791 +     *
  22.792 +     * <p> This constructor first builds a URI in string form using the given
  22.793 +     * components as follows:  </p>
  22.794 +     *
  22.795 +     * <ol>
  22.796 +     *
  22.797 +     *   <li><p> Initially, the result string is empty.  </p></li>
  22.798 +     *
  22.799 +     *   <li><p> If a scheme is given then it is appended to the result,
  22.800 +     *   followed by a colon character (<tt>':'</tt>).  </p></li>
  22.801 +     *
  22.802 +     *   <li><p> If a scheme-specific part is given then it is appended.  Any
  22.803 +     *   character that is not a <a href="#legal-chars">legal URI character</a>
  22.804 +     *   is <a href="#quote">quoted</a>.  </p></li>
  22.805 +     *
  22.806 +     *   <li><p> Finally, if a fragment is given then a hash character
  22.807 +     *   (<tt>'#'</tt>) is appended to the string, followed by the fragment.
  22.808 +     *   Any character that is not a legal URI character is quoted.  </p></li>
  22.809 +     *
  22.810 +     * </ol>
  22.811 +     *
  22.812 +     * <p> The resulting URI string is then parsed in order to create the new
  22.813 +     * URI instance as if by invoking the {@link #URI(String)} constructor;
  22.814 +     * this may cause a {@link URISyntaxException} to be thrown.  </p>
  22.815 +     *
  22.816 +     * @param   scheme    Scheme name
  22.817 +     * @param   ssp       Scheme-specific part
  22.818 +     * @param   fragment  Fragment
  22.819 +     *
  22.820 +     * @throws  URISyntaxException
  22.821 +     *          If the URI string constructed from the given components
  22.822 +     *          violates RFC&nbsp;2396
  22.823 +     */
  22.824 +    public URI(String scheme, String ssp, String fragment)
  22.825 +        throws URISyntaxException
  22.826 +    {
  22.827 +        new Parser(toString(scheme, ssp,
  22.828 +                            null, null, null, -1,
  22.829 +                            null, null, fragment))
  22.830 +            .parse(false);
  22.831 +    }
  22.832 +
  22.833 +    /**
  22.834 +     * Creates a URI by parsing the given string.
  22.835 +     *
  22.836 +     * <p> This convenience factory method works as if by invoking the {@link
  22.837 +     * #URI(String)} constructor; any {@link URISyntaxException} thrown by the
  22.838 +     * constructor is caught and wrapped in a new {@link
  22.839 +     * IllegalArgumentException} object, which is then thrown.
  22.840 +     *
  22.841 +     * <p> This method is provided for use in situations where it is known that
  22.842 +     * the given string is a legal URI, for example for URI constants declared
  22.843 +     * within in a program, and so it would be considered a programming error
  22.844 +     * for the string not to parse as such.  The constructors, which throw
  22.845 +     * {@link URISyntaxException} directly, should be used situations where a
  22.846 +     * URI is being constructed from user input or from some other source that
  22.847 +     * may be prone to errors.  </p>
  22.848 +     *
  22.849 +     * @param  str   The string to be parsed into a URI
  22.850 +     * @return The new URI
  22.851 +     *
  22.852 +     * @throws  NullPointerException
  22.853 +     *          If <tt>str</tt> is <tt>null</tt>
  22.854 +     *
  22.855 +     * @throws  IllegalArgumentException
  22.856 +     *          If the given string violates RFC&nbsp;2396
  22.857 +     */
  22.858 +    public static URI create(String str) {
  22.859 +        try {
  22.860 +            return new URI(str);
  22.861 +        } catch (URISyntaxException x) {
  22.862 +            throw new IllegalArgumentException(x.getMessage(), x);
  22.863 +        }
  22.864 +    }
  22.865 +
  22.866 +
  22.867 +    // -- Operations --
  22.868 +
  22.869 +    /**
  22.870 +     * Attempts to parse this URI's authority component, if defined, into
  22.871 +     * user-information, host, and port components.
  22.872 +     *
  22.873 +     * <p> If this URI's authority component has already been recognized as
  22.874 +     * being server-based then it will already have been parsed into
  22.875 +     * user-information, host, and port components.  In this case, or if this
  22.876 +     * URI has no authority component, this method simply returns this URI.
  22.877 +     *
  22.878 +     * <p> Otherwise this method attempts once more to parse the authority
  22.879 +     * component into user-information, host, and port components, and throws
  22.880 +     * an exception describing why the authority component could not be parsed
  22.881 +     * in that way.
  22.882 +     *
  22.883 +     * <p> This method is provided because the generic URI syntax specified in
  22.884 +     * <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>
  22.885 +     * cannot always distinguish a malformed server-based authority from a
  22.886 +     * legitimate registry-based authority.  It must therefore treat some
  22.887 +     * instances of the former as instances of the latter.  The authority
  22.888 +     * component in the URI string <tt>"//foo:bar"</tt>, for example, is not a
  22.889 +     * legal server-based authority but it is legal as a registry-based
  22.890 +     * authority.
  22.891 +     *
  22.892 +     * <p> In many common situations, for example when working URIs that are
  22.893 +     * known to be either URNs or URLs, the hierarchical URIs being used will
  22.894 +     * always be server-based.  They therefore must either be parsed as such or
  22.895 +     * treated as an error.  In these cases a statement such as
  22.896 +     *
  22.897 +     * <blockquote>
  22.898 +     * <tt>URI </tt><i>u</i><tt> = new URI(str).parseServerAuthority();</tt>
  22.899 +     * </blockquote>
  22.900 +     *
  22.901 +     * <p> can be used to ensure that <i>u</i> always refers to a URI that, if
  22.902 +     * it has an authority component, has a server-based authority with proper
  22.903 +     * user-information, host, and port components.  Invoking this method also
  22.904 +     * ensures that if the authority could not be parsed in that way then an
  22.905 +     * appropriate diagnostic message can be issued based upon the exception
  22.906 +     * that is thrown. </p>
  22.907 +     *
  22.908 +     * @return  A URI whose authority field has been parsed
  22.909 +     *          as a server-based authority
  22.910 +     *
  22.911 +     * @throws  URISyntaxException
  22.912 +     *          If the authority component of this URI is defined
  22.913 +     *          but cannot be parsed as a server-based authority
  22.914 +     *          according to RFC&nbsp;2396
  22.915 +     */
  22.916 +    public URI parseServerAuthority()
  22.917 +        throws URISyntaxException
  22.918 +    {
  22.919 +        // We could be clever and cache the error message and index from the
  22.920 +        // exception thrown during the original parse, but that would require
  22.921 +        // either more fields or a more-obscure representation.
  22.922 +        if ((host != null) || (authority == null))
  22.923 +            return this;
  22.924 +        defineString();
  22.925 +        new Parser(string).parse(true);
  22.926 +        return this;
  22.927 +    }
  22.928 +
  22.929 +    /**
  22.930 +     * Normalizes this URI's path.
  22.931 +     *
  22.932 +     * <p> If this URI is opaque, or if its path is already in normal form,
  22.933 +     * then this URI is returned.  Otherwise a new URI is constructed that is
  22.934 +     * identical to this URI except that its path is computed by normalizing
  22.935 +     * this URI's path in a manner consistent with <a
  22.936 +     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
  22.937 +     * section&nbsp;5.2, step&nbsp;6, sub-steps&nbsp;c through&nbsp;f; that is:
  22.938 +     * </p>
  22.939 +     *
  22.940 +     * <ol>
  22.941 +     *
  22.942 +     *   <li><p> All <tt>"."</tt> segments are removed. </p></li>
  22.943 +     *
  22.944 +     *   <li><p> If a <tt>".."</tt> segment is preceded by a non-<tt>".."</tt>
  22.945 +     *   segment then both of these segments are removed.  This step is
  22.946 +     *   repeated until it is no longer applicable. </p></li>
  22.947 +     *
  22.948 +     *   <li><p> If the path is relative, and if its first segment contains a
  22.949 +     *   colon character (<tt>':'</tt>), then a <tt>"."</tt> segment is
  22.950 +     *   prepended.  This prevents a relative URI with a path such as
  22.951 +     *   <tt>"a:b/c/d"</tt> from later being re-parsed as an opaque URI with a
  22.952 +     *   scheme of <tt>"a"</tt> and a scheme-specific part of <tt>"b/c/d"</tt>.
  22.953 +     *   <b><i>(Deviation from RFC&nbsp;2396)</i></b> </p></li>
  22.954 +     *
  22.955 +     * </ol>
  22.956 +     *
  22.957 +     * <p> A normalized path will begin with one or more <tt>".."</tt> segments
  22.958 +     * if there were insufficient non-<tt>".."</tt> segments preceding them to
  22.959 +     * allow their removal.  A normalized path will begin with a <tt>"."</tt>
  22.960 +     * segment if one was inserted by step 3 above.  Otherwise, a normalized
  22.961 +     * path will not contain any <tt>"."</tt> or <tt>".."</tt> segments. </p>
  22.962 +     *
  22.963 +     * @return  A URI equivalent to this URI,
  22.964 +     *          but whose path is in normal form
  22.965 +     */
  22.966 +    public URI normalize() {
  22.967 +        return normalize(this);
  22.968 +    }
  22.969 +
  22.970 +    /**
  22.971 +     * Resolves the given URI against this URI.
  22.972 +     *
  22.973 +     * <p> If the given URI is already absolute, or if this URI is opaque, then
  22.974 +     * the given URI is returned.
  22.975 +     *
  22.976 +     * <p><a name="resolve-frag"></a> If the given URI's fragment component is
  22.977 +     * defined, its path component is empty, and its scheme, authority, and
  22.978 +     * query components are undefined, then a URI with the given fragment but
  22.979 +     * with all other components equal to those of this URI is returned.  This
  22.980 +     * allows a URI representing a standalone fragment reference, such as
  22.981 +     * <tt>"#foo"</tt>, to be usefully resolved against a base URI.
  22.982 +     *
  22.983 +     * <p> Otherwise this method constructs a new hierarchical URI in a manner
  22.984 +     * consistent with <a
  22.985 +     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
  22.986 +     * section&nbsp;5.2; that is: </p>
  22.987 +     *
  22.988 +     * <ol>
  22.989 +     *
  22.990 +     *   <li><p> A new URI is constructed with this URI's scheme and the given
  22.991 +     *   URI's query and fragment components. </p></li>
  22.992 +     *
  22.993 +     *   <li><p> If the given URI has an authority component then the new URI's
  22.994 +     *   authority and path are taken from the given URI. </p></li>
  22.995 +     *
  22.996 +     *   <li><p> Otherwise the new URI's authority component is copied from
  22.997 +     *   this URI, and its path is computed as follows: </p>
  22.998 +     *
  22.999 +     *   <ol type=a>
 22.1000 +     *
 22.1001 +     *     <li><p> If the given URI's path is absolute then the new URI's path
 22.1002 +     *     is taken from the given URI. </p></li>
 22.1003 +     *
 22.1004 +     *     <li><p> Otherwise the given URI's path is relative, and so the new
 22.1005 +     *     URI's path is computed by resolving the path of the given URI
 22.1006 +     *     against the path of this URI.  This is done by concatenating all but
 22.1007 +     *     the last segment of this URI's path, if any, with the given URI's
 22.1008 +     *     path and then normalizing the result as if by invoking the {@link
 22.1009 +     *     #normalize() normalize} method. </p></li>
 22.1010 +     *
 22.1011 +     *   </ol></li>
 22.1012 +     *
 22.1013 +     * </ol>
 22.1014 +     *
 22.1015 +     * <p> The result of this method is absolute if, and only if, either this
 22.1016 +     * URI is absolute or the given URI is absolute.  </p>
 22.1017 +     *
 22.1018 +     * @param  uri  The URI to be resolved against this URI
 22.1019 +     * @return The resulting URI
 22.1020 +     *
 22.1021 +     * @throws  NullPointerException
 22.1022 +     *          If <tt>uri</tt> is <tt>null</tt>
 22.1023 +     */
 22.1024 +    public URI resolve(URI uri) {
 22.1025 +        return resolve(this, uri);
 22.1026 +    }
 22.1027 +
 22.1028 +    /**
 22.1029 +     * Constructs a new URI by parsing the given string and then resolving it
 22.1030 +     * against this URI.
 22.1031 +     *
 22.1032 +     * <p> This convenience method works as if invoking it were equivalent to
 22.1033 +     * evaluating the expression <tt>{@link #resolve(java.net.URI)
 22.1034 +     * resolve}(URI.{@link #create(String) create}(str))</tt>. </p>
 22.1035 +     *
 22.1036 +     * @param  str   The string to be parsed into a URI
 22.1037 +     * @return The resulting URI
 22.1038 +     *
 22.1039 +     * @throws  NullPointerException
 22.1040 +     *          If <tt>str</tt> is <tt>null</tt>
 22.1041 +     *
 22.1042 +     * @throws  IllegalArgumentException
 22.1043 +     *          If the given string violates RFC&nbsp;2396
 22.1044 +     */
 22.1045 +    public URI resolve(String str) {
 22.1046 +        return resolve(URI.create(str));
 22.1047 +    }
 22.1048 +
 22.1049 +    /**
 22.1050 +     * Relativizes the given URI against this URI.
 22.1051 +     *
 22.1052 +     * <p> The relativization of the given URI against this URI is computed as
 22.1053 +     * follows: </p>
 22.1054 +     *
 22.1055 +     * <ol>
 22.1056 +     *
 22.1057 +     *   <li><p> If either this URI or the given URI are opaque, or if the
 22.1058 +     *   scheme and authority components of the two URIs are not identical, or
 22.1059 +     *   if the path of this URI is not a prefix of the path of the given URI,
 22.1060 +     *   then the given URI is returned. </p></li>
 22.1061 +     *
 22.1062 +     *   <li><p> Otherwise a new relative hierarchical URI is constructed with
 22.1063 +     *   query and fragment components taken from the given URI and with a path
 22.1064 +     *   component computed by removing this URI's path from the beginning of
 22.1065 +     *   the given URI's path. </p></li>
 22.1066 +     *
 22.1067 +     * </ol>
 22.1068 +     *
 22.1069 +     * @param  uri  The URI to be relativized against this URI
 22.1070 +     * @return The resulting URI
 22.1071 +     *
 22.1072 +     * @throws  NullPointerException
 22.1073 +     *          If <tt>uri</tt> is <tt>null</tt>
 22.1074 +     */
 22.1075 +    public URI relativize(URI uri) {
 22.1076 +        return relativize(this, uri);
 22.1077 +    }
 22.1078 +
 22.1079 +    /**
 22.1080 +     * Constructs a URL from this URI.
 22.1081 +     *
 22.1082 +     * <p> This convenience method works as if invoking it were equivalent to
 22.1083 +     * evaluating the expression <tt>new&nbsp;URL(this.toString())</tt> after
 22.1084 +     * first checking that this URI is absolute. </p>
 22.1085 +     *
 22.1086 +     * @return  A URL constructed from this URI
 22.1087 +     *
 22.1088 +     * @throws  IllegalArgumentException
 22.1089 +     *          If this URL is not absolute
 22.1090 +     *
 22.1091 +     * @throws  MalformedURLException
 22.1092 +     *          If a protocol handler for the URL could not be found,
 22.1093 +     *          or if some other error occurred while constructing the URL
 22.1094 +     */
 22.1095 +    public URL toURL()
 22.1096 +        throws MalformedURLException {
 22.1097 +        if (!isAbsolute())
 22.1098 +            throw new IllegalArgumentException("URI is not absolute");
 22.1099 +        return new URL(toString());
 22.1100 +    }
 22.1101 +
 22.1102 +    // -- Component access methods --
 22.1103 +
 22.1104 +    /**
 22.1105 +     * Returns the scheme component of this URI.
 22.1106 +     *
 22.1107 +     * <p> The scheme component of a URI, if defined, only contains characters
 22.1108 +     * in the <i>alphanum</i> category and in the string <tt>"-.+"</tt>.  A
 22.1109 +     * scheme always starts with an <i>alpha</i> character. <p>
 22.1110 +     *
 22.1111 +     * The scheme component of a URI cannot contain escaped octets, hence this
 22.1112 +     * method does not perform any decoding.
 22.1113 +     *
 22.1114 +     * @return  The scheme component of this URI,
 22.1115 +     *          or <tt>null</tt> if the scheme is undefined
 22.1116 +     */
 22.1117 +    public String getScheme() {
 22.1118 +        return scheme;
 22.1119 +    }
 22.1120 +
 22.1121 +    /**
 22.1122 +     * Tells whether or not this URI is absolute.
 22.1123 +     *
 22.1124 +     * <p> A URI is absolute if, and only if, it has a scheme component. </p>
 22.1125 +     *
 22.1126 +     * @return  <tt>true</tt> if, and only if, this URI is absolute
 22.1127 +     */
 22.1128 +    public boolean isAbsolute() {
 22.1129 +        return scheme != null;
 22.1130 +    }
 22.1131 +
 22.1132 +    /**
 22.1133 +     * Tells whether or not this URI is opaque.
 22.1134 +     *
 22.1135 +     * <p> A URI is opaque if, and only if, it is absolute and its
 22.1136 +     * scheme-specific part does not begin with a slash character ('/').
 22.1137 +     * An opaque URI has a scheme, a scheme-specific part, and possibly
 22.1138 +     * a fragment; all other components are undefined. </p>
 22.1139 +     *
 22.1140 +     * @return  <tt>true</tt> if, and only if, this URI is opaque
 22.1141 +     */
 22.1142 +    public boolean isOpaque() {
 22.1143 +        return path == null;
 22.1144 +    }
 22.1145 +
 22.1146 +    /**
 22.1147 +     * Returns the raw scheme-specific part of this URI.  The scheme-specific
 22.1148 +     * part is never undefined, though it may be empty.
 22.1149 +     *
 22.1150 +     * <p> The scheme-specific part of a URI only contains legal URI
 22.1151 +     * characters. </p>
 22.1152 +     *
 22.1153 +     * @return  The raw scheme-specific part of this URI
 22.1154 +     *          (never <tt>null</tt>)
 22.1155 +     */
 22.1156 +    public String getRawSchemeSpecificPart() {
 22.1157 +        defineSchemeSpecificPart();
 22.1158 +        return schemeSpecificPart;
 22.1159 +    }
 22.1160 +
 22.1161 +    /**
 22.1162 +     * Returns the decoded scheme-specific part of this URI.
 22.1163 +     *
 22.1164 +     * <p> The string returned by this method is equal to that returned by the
 22.1165 +     * {@link #getRawSchemeSpecificPart() getRawSchemeSpecificPart} method
 22.1166 +     * except that all sequences of escaped octets are <a
 22.1167 +     * href="#decode">decoded</a>.  </p>
 22.1168 +     *
 22.1169 +     * @return  The decoded scheme-specific part of this URI
 22.1170 +     *          (never <tt>null</tt>)
 22.1171 +     */
 22.1172 +    public String getSchemeSpecificPart() {
 22.1173 +        if (decodedSchemeSpecificPart == null)
 22.1174 +            decodedSchemeSpecificPart = decode(getRawSchemeSpecificPart());
 22.1175 +        return decodedSchemeSpecificPart;
 22.1176 +    }
 22.1177 +
 22.1178 +    /**
 22.1179 +     * Returns the raw authority component of this URI.
 22.1180 +     *
 22.1181 +     * <p> The authority component of a URI, if defined, only contains the
 22.1182 +     * commercial-at character (<tt>'@'</tt>) and characters in the
 22.1183 +     * <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, and <i>other</i>
 22.1184 +     * categories.  If the authority is server-based then it is further
 22.1185 +     * constrained to have valid user-information, host, and port
 22.1186 +     * components. </p>
 22.1187 +     *
 22.1188 +     * @return  The raw authority component of this URI,
 22.1189 +     *          or <tt>null</tt> if the authority is undefined
 22.1190 +     */
 22.1191 +    public String getRawAuthority() {
 22.1192 +        return authority;
 22.1193 +    }
 22.1194 +
 22.1195 +    /**
 22.1196 +     * Returns the decoded authority component of this URI.
 22.1197 +     *
 22.1198 +     * <p> The string returned by this method is equal to that returned by the
 22.1199 +     * {@link #getRawAuthority() getRawAuthority} method except that all
 22.1200 +     * sequences of escaped octets are <a href="#decode">decoded</a>.  </p>
 22.1201 +     *
 22.1202 +     * @return  The decoded authority component of this URI,
 22.1203 +     *          or <tt>null</tt> if the authority is undefined
 22.1204 +     */
 22.1205 +    public String getAuthority() {
 22.1206 +        if (decodedAuthority == null)
 22.1207 +            decodedAuthority = decode(authority);
 22.1208 +        return decodedAuthority;
 22.1209 +    }
 22.1210 +
 22.1211 +    /**
 22.1212 +     * Returns the raw user-information component of this URI.
 22.1213 +     *
 22.1214 +     * <p> The user-information component of a URI, if defined, only contains
 22.1215 +     * characters in the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, and
 22.1216 +     * <i>other</i> categories. </p>
 22.1217 +     *
 22.1218 +     * @return  The raw user-information component of this URI,
 22.1219 +     *          or <tt>null</tt> if the user information is undefined
 22.1220 +     */
 22.1221 +    public String getRawUserInfo() {
 22.1222 +        return userInfo;
 22.1223 +    }
 22.1224 +
 22.1225 +    /**
 22.1226 +     * Returns the decoded user-information component of this URI.
 22.1227 +     *
 22.1228 +     * <p> The string returned by this method is equal to that returned by the
 22.1229 +     * {@link #getRawUserInfo() getRawUserInfo} method except that all
 22.1230 +     * sequences of escaped octets are <a href="#decode">decoded</a>.  </p>
 22.1231 +     *
 22.1232 +     * @return  The decoded user-information component of this URI,
 22.1233 +     *          or <tt>null</tt> if the user information is undefined
 22.1234 +     */
 22.1235 +    public String getUserInfo() {
 22.1236 +        if ((decodedUserInfo == null) && (userInfo != null))
 22.1237 +            decodedUserInfo = decode(userInfo);
 22.1238 +        return decodedUserInfo;
 22.1239 +    }
 22.1240 +
 22.1241 +    /**
 22.1242 +     * Returns the host component of this URI.
 22.1243 +     *
 22.1244 +     * <p> The host component of a URI, if defined, will have one of the
 22.1245 +     * following forms: </p>
 22.1246 +     *
 22.1247 +     * <ul type=disc>
 22.1248 +     *
 22.1249 +     *   <li><p> A domain name consisting of one or more <i>labels</i>
 22.1250 +     *   separated by period characters (<tt>'.'</tt>), optionally followed by
 22.1251 +     *   a period character.  Each label consists of <i>alphanum</i> characters
 22.1252 +     *   as well as hyphen characters (<tt>'-'</tt>), though hyphens never
 22.1253 +     *   occur as the first or last characters in a label. The rightmost
 22.1254 +     *   label of a domain name consisting of two or more labels, begins
 22.1255 +     *   with an <i>alpha</i> character. </li>
 22.1256 +     *
 22.1257 +     *   <li><p> A dotted-quad IPv4 address of the form
 22.1258 +     *   <i>digit</i><tt>+.</tt><i>digit</i><tt>+.</tt><i>digit</i><tt>+.</tt><i>digit</i><tt>+</tt>,
 22.1259 +     *   where no <i>digit</i> sequence is longer than three characters and no
 22.1260 +     *   sequence has a value larger than 255. </p></li>
 22.1261 +     *
 22.1262 +     *   <li><p> An IPv6 address enclosed in square brackets (<tt>'['</tt> and
 22.1263 +     *   <tt>']'</tt>) and consisting of hexadecimal digits, colon characters
 22.1264 +     *   (<tt>':'</tt>), and possibly an embedded IPv4 address.  The full
 22.1265 +     *   syntax of IPv6 addresses is specified in <a
 22.1266 +     *   href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IPv6
 22.1267 +     *   Addressing Architecture</i></a>.  </p></li>
 22.1268 +     *
 22.1269 +     * </ul>
 22.1270 +     *
 22.1271 +     * The host component of a URI cannot contain escaped octets, hence this
 22.1272 +     * method does not perform any decoding.
 22.1273 +     *
 22.1274 +     * @return  The host component of this URI,
 22.1275 +     *          or <tt>null</tt> if the host is undefined
 22.1276 +     */
 22.1277 +    public String getHost() {
 22.1278 +        return host;
 22.1279 +    }
 22.1280 +
 22.1281 +    /**
 22.1282 +     * Returns the port number of this URI.
 22.1283 +     *
 22.1284 +     * <p> The port component of a URI, if defined, is a non-negative
 22.1285 +     * integer. </p>
 22.1286 +     *
 22.1287 +     * @return  The port component of this URI,
 22.1288 +     *          or <tt>-1</tt> if the port is undefined
 22.1289 +     */
 22.1290 +    public int getPort() {
 22.1291 +        return port;
 22.1292 +    }
 22.1293 +
 22.1294 +    /**
 22.1295 +     * Returns the raw path component of this URI.
 22.1296 +     *
 22.1297 +     * <p> The path component of a URI, if defined, only contains the slash
 22.1298 +     * character (<tt>'/'</tt>), the commercial-at character (<tt>'@'</tt>),
 22.1299 +     * and characters in the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>,
 22.1300 +     * and <i>other</i> categories. </p>
 22.1301 +     *
 22.1302 +     * @return  The path component of this URI,
 22.1303 +     *          or <tt>null</tt> if the path is undefined
 22.1304 +     */
 22.1305 +    public String getRawPath() {
 22.1306 +        return path;
 22.1307 +    }
 22.1308 +
 22.1309 +    /**
 22.1310 +     * Returns the decoded path component of this URI.
 22.1311 +     *
 22.1312 +     * <p> The string returned by this method is equal to that returned by the
 22.1313 +     * {@link #getRawPath() getRawPath} method except that all sequences of
 22.1314 +     * escaped octets are <a href="#decode">decoded</a>.  </p>
 22.1315 +     *
 22.1316 +     * @return  The decoded path component of this URI,
 22.1317 +     *          or <tt>null</tt> if the path is undefined
 22.1318 +     */
 22.1319 +    public String getPath() {
 22.1320 +        if ((decodedPath == null) && (path != null))
 22.1321 +            decodedPath = decode(path);
 22.1322 +        return decodedPath;
 22.1323 +    }
 22.1324 +
 22.1325 +    /**
 22.1326 +     * Returns the raw query component of this URI.
 22.1327 +     *
 22.1328 +     * <p> The query component of a URI, if defined, only contains legal URI
 22.1329 +     * characters. </p>
 22.1330 +     *
 22.1331 +     * @return  The raw query component of this URI,
 22.1332 +     *          or <tt>null</tt> if the query is undefined
 22.1333 +     */
 22.1334 +    public String getRawQuery() {
 22.1335 +        return query;
 22.1336 +    }
 22.1337 +
 22.1338 +    /**
 22.1339 +     * Returns the decoded query component of this URI.
 22.1340 +     *
 22.1341 +     * <p> The string returned by this method is equal to that returned by the
 22.1342 +     * {@link #getRawQuery() getRawQuery} method except that all sequences of
 22.1343 +     * escaped octets are <a href="#decode">decoded</a>.  </p>
 22.1344 +     *
 22.1345 +     * @return  The decoded query component of this URI,
 22.1346 +     *          or <tt>null</tt> if the query is undefined
 22.1347 +     */
 22.1348 +    public String getQuery() {
 22.1349 +        if ((decodedQuery == null) && (query != null))
 22.1350 +            decodedQuery = decode(query);
 22.1351 +        return decodedQuery;
 22.1352 +    }
 22.1353 +
 22.1354 +    /**
 22.1355 +     * Returns the raw fragment component of this URI.
 22.1356 +     *
 22.1357 +     * <p> The fragment component of a URI, if defined, only contains legal URI
 22.1358 +     * characters. </p>
 22.1359 +     *
 22.1360 +     * @return  The raw fragment component of this URI,
 22.1361 +     *          or <tt>null</tt> if the fragment is undefined
 22.1362 +     */
 22.1363 +    public String getRawFragment() {
 22.1364 +        return fragment;
 22.1365 +    }
 22.1366 +
 22.1367 +    /**
 22.1368 +     * Returns the decoded fragment component of this URI.
 22.1369 +     *
 22.1370 +     * <p> The string returned by this method is equal to that returned by the
 22.1371 +     * {@link #getRawFragment() getRawFragment} method except that all
 22.1372 +     * sequences of escaped octets are <a href="#decode">decoded</a>.  </p>
 22.1373 +     *
 22.1374 +     * @return  The decoded fragment component of this URI,
 22.1375 +     *          or <tt>null</tt> if the fragment is undefined
 22.1376 +     */
 22.1377 +    public String getFragment() {
 22.1378 +        if ((decodedFragment == null) && (fragment != null))
 22.1379 +            decodedFragment = decode(fragment);
 22.1380 +        return decodedFragment;
 22.1381 +    }
 22.1382 +
 22.1383 +
 22.1384 +    // -- Equality, comparison, hash code, toString, and serialization --
 22.1385 +
 22.1386 +    /**
 22.1387 +     * Tests this URI for equality with another object.
 22.1388 +     *
 22.1389 +     * <p> If the given object is not a URI then this method immediately
 22.1390 +     * returns <tt>false</tt>.
 22.1391 +     *
 22.1392 +     * <p> For two URIs to be considered equal requires that either both are
 22.1393 +     * opaque or both are hierarchical.  Their schemes must either both be
 22.1394 +     * undefined or else be equal without regard to case. Their fragments
 22.1395 +     * must either both be undefined or else be equal.
 22.1396 +     *
 22.1397 +     * <p> For two opaque URIs to be considered equal, their scheme-specific
 22.1398 +     * parts must be equal.
 22.1399 +     *
 22.1400 +     * <p> For two hierarchical URIs to be considered equal, their paths must
 22.1401 +     * be equal and their queries must either both be undefined or else be
 22.1402 +     * equal.  Their authorities must either both be undefined, or both be
 22.1403 +     * registry-based, or both be server-based.  If their authorities are
 22.1404 +     * defined and are registry-based, then they must be equal.  If their
 22.1405 +     * authorities are defined and are server-based, then their hosts must be
 22.1406 +     * equal without regard to case, their port numbers must be equal, and
 22.1407 +     * their user-information components must be equal.
 22.1408 +     *
 22.1409 +     * <p> When testing the user-information, path, query, fragment, authority,
 22.1410 +     * or scheme-specific parts of two URIs for equality, the raw forms rather
 22.1411 +     * than the encoded forms of these components are compared and the
 22.1412 +     * hexadecimal digits of escaped octets are compared without regard to
 22.1413 +     * case.
 22.1414 +     *
 22.1415 +     * <p> This method satisfies the general contract of the {@link
 22.1416 +     * java.lang.Object#equals(Object) Object.equals} method. </p>
 22.1417 +     *
 22.1418 +     * @param   ob   The object to which this object is to be compared
 22.1419 +     *
 22.1420 +     * @return  <tt>true</tt> if, and only if, the given object is a URI that
 22.1421 +     *          is identical to this URI
 22.1422 +     */
 22.1423 +    public boolean equals(Object ob) {
 22.1424 +        if (ob == this)
 22.1425 +            return true;
 22.1426 +        if (!(ob instanceof URI))
 22.1427 +            return false;
 22.1428 +        URI that = (URI)ob;
 22.1429 +        if (this.isOpaque() != that.isOpaque()) return false;
 22.1430 +        if (!equalIgnoringCase(this.scheme, that.scheme)) return false;
 22.1431 +        if (!equal(this.fragment, that.fragment)) return false;
 22.1432 +
 22.1433 +        // Opaque
 22.1434 +        if (this.isOpaque())
 22.1435 +            return equal(this.schemeSpecificPart, that.schemeSpecificPart);
 22.1436 +
 22.1437 +        // Hierarchical
 22.1438 +        if (!equal(this.path, that.path)) return false;
 22.1439 +        if (!equal(this.query, that.query)) return false;
 22.1440 +
 22.1441 +        // Authorities
 22.1442 +        if (this.authority == that.authority) return true;
 22.1443 +        if (this.host != null) {
 22.1444 +            // Server-based
 22.1445 +            if (!equal(this.userInfo, that.userInfo)) return false;
 22.1446 +            if (!equalIgnoringCase(this.host, that.host)) return false;
 22.1447 +            if (this.port != that.port) return false;
 22.1448 +        } else if (this.authority != null) {
 22.1449 +            // Registry-based
 22.1450 +            if (!equal(this.authority, that.authority)) return false;
 22.1451 +        } else if (this.authority != that.authority) {
 22.1452 +            return false;
 22.1453 +        }
 22.1454 +
 22.1455 +        return true;
 22.1456 +    }
 22.1457 +
 22.1458 +    /**
 22.1459 +     * Returns a hash-code value for this URI.  The hash code is based upon all
 22.1460 +     * of the URI's components, and satisfies the general contract of the
 22.1461 +     * {@link java.lang.Object#hashCode() Object.hashCode} method.
 22.1462 +     *
 22.1463 +     * @return  A hash-code value for this URI
 22.1464 +     */
 22.1465 +    public int hashCode() {
 22.1466 +        if (hash != 0)
 22.1467 +            return hash;
 22.1468 +        int h = hashIgnoringCase(0, scheme);
 22.1469 +        h = hash(h, fragment);
 22.1470 +        if (isOpaque()) {
 22.1471 +            h = hash(h, schemeSpecificPart);
 22.1472 +        } else {
 22.1473 +            h = hash(h, path);
 22.1474 +            h = hash(h, query);
 22.1475 +            if (host != null) {
 22.1476 +                h = hash(h, userInfo);
 22.1477 +                h = hashIgnoringCase(h, host);
 22.1478 +                h += 1949 * port;
 22.1479 +            } else {
 22.1480 +                h = hash(h, authority);
 22.1481 +            }
 22.1482 +        }
 22.1483 +        hash = h;
 22.1484 +        return h;
 22.1485 +    }
 22.1486 +
 22.1487 +    /**
 22.1488 +     * Compares this URI to another object, which must be a URI.
 22.1489 +     *
 22.1490 +     * <p> When comparing corresponding components of two URIs, if one
 22.1491 +     * component is undefined but the other is defined then the first is
 22.1492 +     * considered to be less than the second.  Unless otherwise noted, string
 22.1493 +     * components are ordered according to their natural, case-sensitive
 22.1494 +     * ordering as defined by the {@link java.lang.String#compareTo(Object)
 22.1495 +     * String.compareTo} method.  String components that are subject to
 22.1496 +     * encoding are compared by comparing their raw forms rather than their
 22.1497 +     * encoded forms.
 22.1498 +     *
 22.1499 +     * <p> The ordering of URIs is defined as follows: </p>
 22.1500 +     *
 22.1501 +     * <ul type=disc>
 22.1502 +     *
 22.1503 +     *   <li><p> Two URIs with different schemes are ordered according the
 22.1504 +     *   ordering of their schemes, without regard to case. </p></li>
 22.1505 +     *
 22.1506 +     *   <li><p> A hierarchical URI is considered to be less than an opaque URI
 22.1507 +     *   with an identical scheme. </p></li>
 22.1508 +     *
 22.1509 +     *   <li><p> Two opaque URIs with identical schemes are ordered according
 22.1510 +     *   to the ordering of their scheme-specific parts. </p></li>
 22.1511 +     *
 22.1512 +     *   <li><p> Two opaque URIs with identical schemes and scheme-specific
 22.1513 +     *   parts are ordered according to the ordering of their
 22.1514 +     *   fragments. </p></li>
 22.1515 +     *
 22.1516 +     *   <li><p> Two hierarchical URIs with identical schemes are ordered
 22.1517 +     *   according to the ordering of their authority components: </p>
 22.1518 +     *
 22.1519 +     *   <ul type=disc>
 22.1520 +     *
 22.1521 +     *     <li><p> If both authority components are server-based then the URIs
 22.1522 +     *     are ordered according to their user-information components; if these
 22.1523 +     *     components are identical then the URIs are ordered according to the
 22.1524 +     *     ordering of their hosts, without regard to case; if the hosts are
 22.1525 +     *     identical then the URIs are ordered according to the ordering of
 22.1526 +     *     their ports. </p></li>
 22.1527 +     *
 22.1528 +     *     <li><p> If one or both authority components are registry-based then
 22.1529 +     *     the URIs are ordered according to the ordering of their authority
 22.1530 +     *     components. </p></li>
 22.1531 +     *
 22.1532 +     *   </ul></li>
 22.1533 +     *
 22.1534 +     *   <li><p> Finally, two hierarchical URIs with identical schemes and
 22.1535 +     *   authority components are ordered according to the ordering of their
 22.1536 +     *   paths; if their paths are identical then they are ordered according to
 22.1537 +     *   the ordering of their queries; if the queries are identical then they
 22.1538 +     *   are ordered according to the order of their fragments. </p></li>
 22.1539 +     *
 22.1540 +     * </ul>
 22.1541 +     *
 22.1542 +     * <p> This method satisfies the general contract of the {@link
 22.1543 +     * java.lang.Comparable#compareTo(Object) Comparable.compareTo}
 22.1544 +     * method. </p>
 22.1545 +     *
 22.1546 +     * @param   that
 22.1547 +     *          The object to which this URI is to be compared
 22.1548 +     *
 22.1549 +     * @return  A negative integer, zero, or a positive integer as this URI is
 22.1550 +     *          less than, equal to, or greater than the given URI
 22.1551 +     *
 22.1552 +     * @throws  ClassCastException
 22.1553 +     *          If the given object is not a URI
 22.1554 +     */
 22.1555 +    public int compareTo(URI that) {
 22.1556 +        int c;
 22.1557 +
 22.1558 +        if ((c = compareIgnoringCase(this.scheme, that.scheme)) != 0)
 22.1559 +            return c;
 22.1560 +
 22.1561 +        if (this.isOpaque()) {
 22.1562 +            if (that.isOpaque()) {
 22.1563 +                // Both opaque
 22.1564 +                if ((c = compare(this.schemeSpecificPart,
 22.1565 +                                 that.schemeSpecificPart)) != 0)
 22.1566 +                    return c;
 22.1567 +                return compare(this.fragment, that.fragment);
 22.1568 +            }
 22.1569 +            return +1;                  // Opaque > hierarchical
 22.1570 +        } else if (that.isOpaque()) {
 22.1571 +            return -1;                  // Hierarchical < opaque
 22.1572 +        }
 22.1573 +
 22.1574 +        // Hierarchical
 22.1575 +        if ((this.host != null) && (that.host != null)) {
 22.1576 +            // Both server-based
 22.1577 +            if ((c = compare(this.userInfo, that.userInfo)) != 0)
 22.1578 +                return c;
 22.1579 +            if ((c = compareIgnoringCase(this.host, that.host)) != 0)
 22.1580 +                return c;
 22.1581 +            if ((c = this.port - that.port) != 0)
 22.1582 +                return c;
 22.1583 +        } else {
 22.1584 +            // If one or both authorities are registry-based then we simply
 22.1585 +            // compare them in the usual, case-sensitive way.  If one is
 22.1586 +            // registry-based and one is server-based then the strings are
 22.1587 +            // guaranteed to be unequal, hence the comparison will never return
 22.1588 +            // zero and the compareTo and equals methods will remain
 22.1589 +            // consistent.
 22.1590 +            if ((c = compare(this.authority, that.authority)) != 0) return c;
 22.1591 +        }
 22.1592 +
 22.1593 +        if ((c = compare(this.path, that.path)) != 0) return c;
 22.1594 +        if ((c = compare(this.query, that.query)) != 0) return c;
 22.1595 +        return compare(this.fragment, that.fragment);
 22.1596 +    }
 22.1597 +
 22.1598 +    /**
 22.1599 +     * Returns the content of this URI as a string.
 22.1600 +     *
 22.1601 +     * <p> If this URI was created by invoking one of the constructors in this
 22.1602 +     * class then a string equivalent to the original input string, or to the
 22.1603 +     * string computed from the originally-given components, as appropriate, is
 22.1604 +     * returned.  Otherwise this URI was created by normalization, resolution,
 22.1605 +     * or relativization, and so a string is constructed from this URI's
 22.1606 +     * components according to the rules specified in <a
 22.1607 +     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
 22.1608 +     * section&nbsp;5.2, step&nbsp;7. </p>
 22.1609 +     *
 22.1610 +     * @return  The string form of this URI
 22.1611 +     */
 22.1612 +    public String toString() {
 22.1613 +        defineString();
 22.1614 +        return string;
 22.1615 +    }
 22.1616 +
 22.1617 +    /**
 22.1618 +     * Returns the content of this URI as a US-ASCII string.
 22.1619 +     *
 22.1620 +     * <p> If this URI does not contain any characters in the <i>other</i>
 22.1621 +     * category then an invocation of this method will return the same value as
 22.1622 +     * an invocation of the {@link #toString() toString} method.  Otherwise
 22.1623 +     * this method works as if by invoking that method and then <a
 22.1624 +     * href="#encode">encoding</a> the result.  </p>
 22.1625 +     *
 22.1626 +     * @return  The string form of this URI, encoded as needed
 22.1627 +     *          so that it only contains characters in the US-ASCII
 22.1628 +     *          charset
 22.1629 +     */
 22.1630 +    public String toASCIIString() {
 22.1631 +        defineString();
 22.1632 +        return encode(string);
 22.1633 +    }
 22.1634 +
 22.1635 +
 22.1636 +    // -- Serialization support --
 22.1637 +
 22.1638 +    /**
 22.1639 +     * Saves the content of this URI to the given serial stream.
 22.1640 +     *
 22.1641 +     * <p> The only serializable field of a URI instance is its <tt>string</tt>
 22.1642 +     * field.  That field is given a value, if it does not have one already,
 22.1643 +     * and then the {@link java.io.ObjectOutputStream#defaultWriteObject()}
 22.1644 +     * method of the given object-output stream is invoked. </p>
 22.1645 +     *
 22.1646 +     * @param  os  The object-output stream to which this object
 22.1647 +     *             is to be written
 22.1648 +     */
 22.1649 +    private void writeObject(ObjectOutputStream os)
 22.1650 +        throws IOException
 22.1651 +    {
 22.1652 +        defineString();
 22.1653 +        os.defaultWriteObject();        // Writes the string field only
 22.1654 +    }
 22.1655 +
 22.1656 +    /**
 22.1657 +     * Reconstitutes a URI from the given serial stream.
 22.1658 +     *
 22.1659 +     * <p> The {@link java.io.ObjectInputStream#defaultReadObject()} method is
 22.1660 +     * invoked to read the value of the <tt>string</tt> field.  The result is
 22.1661 +     * then parsed in the usual way.
 22.1662 +     *
 22.1663 +     * @param  is  The object-input stream from which this object
 22.1664 +     *             is being read
 22.1665 +     */
 22.1666 +    private void readObject(ObjectInputStream is)
 22.1667 +        throws ClassNotFoundException, IOException
 22.1668 +    {
 22.1669 +        port = -1;                      // Argh
 22.1670 +        is.defaultReadObject();
 22.1671 +        try {
 22.1672 +            new Parser(string).parse(false);
 22.1673 +        } catch (URISyntaxException x) {
 22.1674 +            IOException y = new InvalidObjectException("Invalid URI");
 22.1675 +            y.initCause(x);
 22.1676 +            throw y;
 22.1677 +        }
 22.1678 +    }
 22.1679 +
 22.1680 +
 22.1681 +    // -- End of public methods --
 22.1682 +
 22.1683 +
 22.1684 +    // -- Utility methods for string-field comparison and hashing --
 22.1685 +
 22.1686 +    // These methods return appropriate values for null string arguments,
 22.1687 +    // thereby simplifying the equals, hashCode, and compareTo methods.
 22.1688 +    //
 22.1689 +    // The case-ignoring methods should only be applied to strings whose
 22.1690 +    // characters are all known to be US-ASCII.  Because of this restriction,
 22.1691 +    // these methods are faster than the similar methods in the String class.
 22.1692 +
 22.1693 +    // US-ASCII only
 22.1694 +    private static int toLower(char c) {
 22.1695 +        if ((c >= 'A') && (c <= 'Z'))
 22.1696 +            return c + ('a' - 'A');
 22.1697 +        return c;
 22.1698 +    }
 22.1699 +
 22.1700 +    private static boolean equal(String s, String t) {
 22.1701 +        if (s == t) return true;
 22.1702 +        if ((s != null) && (t != null)) {
 22.1703 +            if (s.length() != t.length())
 22.1704 +                return false;
 22.1705 +            if (s.indexOf('%') < 0)
 22.1706 +                return s.equals(t);
 22.1707 +            int n = s.length();
 22.1708 +            for (int i = 0; i < n;) {
 22.1709 +                char c = s.charAt(i);
 22.1710 +                char d = t.charAt(i);
 22.1711 +                if (c != '%') {
 22.1712 +                    if (c != d)
 22.1713 +                        return false;
 22.1714 +                    i++;
 22.1715 +                    continue;
 22.1716 +                }
 22.1717 +                i++;
 22.1718 +                if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
 22.1719 +                    return false;
 22.1720 +                i++;
 22.1721 +                if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
 22.1722 +                    return false;
 22.1723 +                i++;
 22.1724 +            }
 22.1725 +            return true;
 22.1726 +        }
 22.1727 +        return false;
 22.1728 +    }
 22.1729 +
 22.1730 +    // US-ASCII only
 22.1731 +    private static boolean equalIgnoringCase(String s, String t) {
 22.1732 +        if (s == t) return true;
 22.1733 +        if ((s != null) && (t != null)) {
 22.1734 +            int n = s.length();
 22.1735 +            if (t.length() != n)
 22.1736 +                return false;
 22.1737 +            for (int i = 0; i < n; i++) {
 22.1738 +                if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
 22.1739 +                    return false;
 22.1740 +            }
 22.1741 +            return true;
 22.1742 +        }
 22.1743 +        return false;
 22.1744 +    }
 22.1745 +
 22.1746 +    private static int hash(int hash, String s) {
 22.1747 +        if (s == null) return hash;
 22.1748 +        return hash * 127 + s.hashCode();
 22.1749 +    }
 22.1750 +
 22.1751 +    // US-ASCII only
 22.1752 +    private static int hashIgnoringCase(int hash, String s) {
 22.1753 +        if (s == null) return hash;
 22.1754 +        int h = hash;
 22.1755 +        int n = s.length();
 22.1756 +        for (int i = 0; i < n; i++)
 22.1757 +            h = 31 * h + toLower(s.charAt(i));
 22.1758 +        return h;
 22.1759 +    }
 22.1760 +
 22.1761 +    private static int compare(String s, String t) {
 22.1762 +        if (s == t) return 0;
 22.1763 +        if (s != null) {
 22.1764 +            if (t != null)
 22.1765 +                return s.compareTo(t);
 22.1766 +            else
 22.1767 +                return +1;
 22.1768 +        } else {
 22.1769 +            return -1;
 22.1770 +        }
 22.1771 +    }
 22.1772 +
 22.1773 +    // US-ASCII only
 22.1774 +    private static int compareIgnoringCase(String s, String t) {
 22.1775 +        if (s == t) return 0;
 22.1776 +        if (s != null) {
 22.1777 +            if (t != null) {
 22.1778 +                int sn = s.length();
 22.1779 +                int tn = t.length();
 22.1780 +                int n = sn < tn ? sn : tn;
 22.1781 +                for (int i = 0; i < n; i++) {
 22.1782 +                    int c = toLower(s.charAt(i)) - toLower(t.charAt(i));
 22.1783 +                    if (c != 0)
 22.1784 +                        return c;
 22.1785 +                }
 22.1786 +                return sn - tn;
 22.1787 +            }
 22.1788 +            return +1;
 22.1789 +        } else {
 22.1790 +            return -1;
 22.1791 +        }
 22.1792 +    }
 22.1793 +
 22.1794 +
 22.1795 +    // -- String construction --
 22.1796 +
 22.1797 +    // If a scheme is given then the path, if given, must be absolute
 22.1798 +    //
 22.1799 +    private static void checkPath(String s, String scheme, String path)
 22.1800 +        throws URISyntaxException
 22.1801 +    {
 22.1802 +        if (scheme != null) {
 22.1803 +            if ((path != null)
 22.1804 +                && ((path.length() > 0) && (path.charAt(0) != '/')))
 22.1805 +                throw new URISyntaxException(s,
 22.1806 +                                             "Relative path in absolute URI");
 22.1807 +        }
 22.1808 +    }
 22.1809 +
 22.1810 +    private void appendAuthority(StringBuffer sb,
 22.1811 +                                 String authority,
 22.1812 +                                 String userInfo,
 22.1813 +                                 String host,
 22.1814 +                                 int port)
 22.1815 +    {
 22.1816 +        if (host != null) {
 22.1817 +            sb.append("//");
 22.1818 +            if (userInfo != null) {
 22.1819 +                sb.append(quote(userInfo, L_USERINFO, H_USERINFO));
 22.1820 +                sb.append('@');
 22.1821 +            }
 22.1822 +            boolean needBrackets = ((host.indexOf(':') >= 0)
 22.1823 +                                    && !host.startsWith("[")
 22.1824 +                                    && !host.endsWith("]"));
 22.1825 +            if (needBrackets) sb.append('[');
 22.1826 +            sb.append(host);
 22.1827 +            if (needBrackets) sb.append(']');
 22.1828 +            if (port != -1) {
 22.1829 +                sb.append(':');
 22.1830 +                sb.append(port);
 22.1831 +            }
 22.1832 +        } else if (authority != null) {
 22.1833 +            sb.append("//");
 22.1834 +            if (authority.startsWith("[")) {
 22.1835 +                // authority should (but may not) contain an embedded IPv6 address
 22.1836 +                int end = authority.indexOf("]");
 22.1837 +                String doquote = authority, dontquote = "";
 22.1838 +                if (end != -1 && authority.indexOf(":") != -1) {
 22.1839 +                    // the authority contains an IPv6 address
 22.1840 +                    if (end == authority.length()) {
 22.1841 +                        dontquote = authority;
 22.1842 +                        doquote = "";
 22.1843 +                    } else {
 22.1844 +                        dontquote = authority.substring(0 , end + 1);
 22.1845 +                        doquote = authority.substring(end + 1);
 22.1846 +                    }
 22.1847 +                }
 22.1848 +                sb.append(dontquote);
 22.1849 +                sb.append(quote(doquote,
 22.1850 +                            L_REG_NAME | L_SERVER,
 22.1851 +                            H_REG_NAME | H_SERVER));
 22.1852 +            } else {
 22.1853 +                sb.append(quote(authority,
 22.1854 +                            L_REG_NAME | L_SERVER,
 22.1855 +                            H_REG_NAME | H_SERVER));
 22.1856 +            }
 22.1857 +        }
 22.1858 +    }
 22.1859 +
 22.1860 +    private void appendSchemeSpecificPart(StringBuffer sb,
 22.1861 +                                          String opaquePart,
 22.1862 +                                          String authority,
 22.1863 +                                          String userInfo,
 22.1864 +                                          String host,
 22.1865 +                                          int port,
 22.1866 +                                          String path,
 22.1867 +                                          String query)
 22.1868 +    {
 22.1869 +        if (opaquePart != null) {
 22.1870 +            /* check if SSP begins with an IPv6 address
 22.1871 +             * because we must not quote a literal IPv6 address
 22.1872 +             */
 22.1873 +            if (opaquePart.startsWith("//[")) {
 22.1874 +                int end =  opaquePart.indexOf("]");
 22.1875 +                if (end != -1 && opaquePart.indexOf(":")!=-1) {
 22.1876 +                    String doquote, dontquote;
 22.1877 +                    if (end == opaquePart.length()) {
 22.1878 +                        dontquote = opaquePart;
 22.1879 +                        doquote = "";
 22.1880 +                    } else {
 22.1881 +                        dontquote = opaquePart.substring(0,end+1);
 22.1882 +                        doquote = opaquePart.substring(end+1);
 22.1883 +                    }
 22.1884 +                    sb.append (dontquote);
 22.1885 +                    sb.append(quote(doquote, L_URIC, H_URIC));
 22.1886 +                }
 22.1887 +            } else {
 22.1888 +                sb.append(quote(opaquePart, L_URIC, H_URIC));
 22.1889 +            }
 22.1890 +        } else {
 22.1891 +            appendAuthority(sb, authority, userInfo, host, port);
 22.1892 +            if (path != null)
 22.1893 +                sb.append(quote(path, L_PATH, H_PATH));
 22.1894 +            if (query != null) {
 22.1895 +                sb.append('?');
 22.1896 +                sb.append(quote(query, L_URIC, H_URIC));
 22.1897 +            }
 22.1898 +        }
 22.1899 +    }
 22.1900 +
 22.1901 +    private void appendFragment(StringBuffer sb, String fragment) {
 22.1902 +        if (fragment != null) {
 22.1903 +            sb.append('#');
 22.1904 +            sb.append(quote(fragment, L_URIC, H_URIC));
 22.1905 +        }
 22.1906 +    }
 22.1907 +
 22.1908 +    private String toString(String scheme,
 22.1909 +                            String opaquePart,
 22.1910 +                            String authority,
 22.1911 +                            String userInfo,
 22.1912 +                            String host,
 22.1913 +                            int port,
 22.1914 +                            String path,
 22.1915 +                            String query,
 22.1916 +                            String fragment)
 22.1917 +    {
 22.1918 +        StringBuffer sb = new StringBuffer();
 22.1919 +        if (scheme != null) {
 22.1920 +            sb.append(scheme);
 22.1921 +            sb.append(':');
 22.1922 +        }
 22.1923 +        appendSchemeSpecificPart(sb, opaquePart,
 22.1924 +                                 authority, userInfo, host, port,
 22.1925 +                                 path, query);
 22.1926 +        appendFragment(sb, fragment);
 22.1927 +        return sb.toString();
 22.1928 +    }
 22.1929 +
 22.1930 +    private void defineSchemeSpecificPart() {
 22.1931 +        if (schemeSpecificPart != null) return;
 22.1932 +        StringBuffer sb = new StringBuffer();
 22.1933 +        appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
 22.1934 +                                 host, port, getPath(), getQuery());
 22.1935 +        if (sb.length() == 0) return;
 22.1936 +        schemeSpecificPart = sb.toString();
 22.1937 +    }
 22.1938 +
 22.1939 +    private void defineString() {
 22.1940 +        if (string != null) return;
 22.1941 +
 22.1942 +        StringBuffer sb = new StringBuffer();
 22.1943 +        if (scheme != null) {
 22.1944 +            sb.append(scheme);
 22.1945 +            sb.append(':');
 22.1946 +        }
 22.1947 +        if (isOpaque()) {
 22.1948 +            sb.append(schemeSpecificPart);
 22.1949 +        } else {
 22.1950 +            if (host != null) {
 22.1951 +                sb.append("//");
 22.1952 +                if (userInfo != null) {
 22.1953 +                    sb.append(userInfo);
 22.1954 +                    sb.append('@');
 22.1955 +                }
 22.1956 +                boolean needBrackets = ((host.indexOf(':') >= 0)
 22.1957 +                                    && !host.startsWith("[")
 22.1958 +                                    && !host.endsWith("]"));
 22.1959 +                if (needBrackets) sb.append('[');
 22.1960 +                sb.append(host);
 22.1961 +                if (needBrackets) sb.append(']');
 22.1962 +                if (port != -1) {
 22.1963 +                    sb.append(':');
 22.1964 +                    sb.append(port);
 22.1965 +                }
 22.1966 +            } else if (authority != null) {
 22.1967 +                sb.append("//");
 22.1968 +                sb.append(authority);
 22.1969 +            }
 22.1970 +            if (path != null)
 22.1971 +                sb.append(path);
 22.1972 +            if (query != null) {
 22.1973 +                sb.append('?');
 22.1974 +                sb.append(query);
 22.1975 +            }
 22.1976 +        }
 22.1977 +        if (fragment != null) {
 22.1978 +            sb.append('#');
 22.1979 +            sb.append(fragment);
 22.1980 +        }
 22.1981 +        string = sb.toString();
 22.1982 +    }
 22.1983 +
 22.1984 +
 22.1985 +    // -- Normalization, resolution, and relativization --
 22.1986 +
 22.1987 +    // RFC2396 5.2 (6)
 22.1988 +    private static String resolvePath(String base, String child,
 22.1989 +                                      boolean absolute)
 22.1990 +    {
 22.1991 +        int i = base.lastIndexOf('/');
 22.1992 +        int cn = child.length();
 22.1993 +        String path = "";
 22.1994 +
 22.1995 +        if (cn == 0) {
 22.1996 +            // 5.2 (6a)
 22.1997 +            if (i >= 0)
 22.1998 +                path = base.substring(0, i + 1);
 22.1999 +        } else {
 22.2000 +            StringBuffer sb = new StringBuffer(base.length() + cn);
 22.2001 +            // 5.2 (6a)
 22.2002 +            if (i >= 0)
 22.2003 +                sb.append(base.substring(0, i + 1));
 22.2004 +            // 5.2 (6b)
 22.2005 +            sb.append(child);
 22.2006 +            path = sb.toString();
 22.2007 +        }
 22.2008 +
 22.2009 +        // 5.2 (6c-f)
 22.2010 +        String np = normalize(path);
 22.2011 +
 22.2012 +        // 5.2 (6g): If the result is absolute but the path begins with "../",
 22.2013 +        // then we simply leave the path as-is
 22.2014 +
 22.2015 +        return np;
 22.2016 +    }
 22.2017 +
 22.2018 +    // RFC2396 5.2
 22.2019 +    private static URI resolve(URI base, URI child) {
 22.2020 +        // check if child if opaque first so that NPE is thrown
 22.2021 +        // if child is null.
 22.2022 +        if (child.isOpaque() || base.isOpaque())
 22.2023 +            return child;
 22.2024 +
 22.2025 +        // 5.2 (2): Reference to current document (lone fragment)
 22.2026 +        if ((child.scheme == null) && (child.authority == null)
 22.2027 +            && child.path.equals("") && (child.fragment != null)
 22.2028 +            && (child.query == null)) {
 22.2029 +            if ((base.fragment != null)
 22.2030 +                && child.fragment.equals(base.fragment)) {
 22.2031 +                return base;
 22.2032 +            }
 22.2033 +            URI ru = new URI();
 22.2034 +            ru.scheme = base.scheme;
 22.2035 +            ru.authority = base.authority;
 22.2036 +            ru.userInfo = base.userInfo;
 22.2037 +            ru.host = base.host;
 22.2038 +            ru.port = base.port;
 22.2039 +            ru.path = base.path;
 22.2040 +            ru.fragment = child.fragment;
 22.2041 +            ru.query = base.query;
 22.2042 +            return ru;
 22.2043 +        }
 22.2044 +
 22.2045 +        // 5.2 (3): Child is absolute
 22.2046 +        if (child.scheme != null)
 22.2047 +            return child;
 22.2048 +
 22.2049 +        URI ru = new URI();             // Resolved URI
 22.2050 +        ru.scheme = base.scheme;
 22.2051 +        ru.query = child.query;
 22.2052 +        ru.fragment = child.fragment;
 22.2053 +
 22.2054 +        // 5.2 (4): Authority
 22.2055 +        if (child.authority == null) {
 22.2056 +            ru.authority = base.authority;
 22.2057 +            ru.host = base.host;
 22.2058 +            ru.userInfo = base.userInfo;
 22.2059 +            ru.port = base.port;
 22.2060 +
 22.2061 +            String cp = (child.path == null) ? "" : child.path;
 22.2062 +            if ((cp.length() > 0) && (cp.charAt(0) == '/')) {
 22.2063 +                // 5.2 (5): Child path is absolute
 22.2064 +                ru.path = child.path;
 22.2065 +            } else {
 22.2066 +                // 5.2 (6): Resolve relative path
 22.2067 +                ru.path = resolvePath(base.path, cp, base.isAbsolute());
 22.2068 +            }
 22.2069 +        } else {
 22.2070 +            ru.authority = child.authority;
 22.2071 +            ru.host = child.host;
 22.2072 +            ru.userInfo = child.userInfo;
 22.2073 +            ru.host = child.host;
 22.2074 +            ru.port = child.port;
 22.2075 +            ru.path = child.path;
 22.2076 +        }
 22.2077 +
 22.2078 +        // 5.2 (7): Recombine (nothing to do here)
 22.2079 +        return ru;
 22.2080 +    }
 22.2081 +
 22.2082 +    // If the given URI's path is normal then return the URI;
 22.2083 +    // o.w., return a new URI containing the normalized path.
 22.2084 +    //
 22.2085 +    private static URI normalize(URI u) {
 22.2086 +        if (u.isOpaque() || (u.path == null) || (u.path.length() == 0))
 22.2087 +            return u;
 22.2088 +
 22.2089 +        String np = normalize(u.path);
 22.2090 +        if (np == u.path)
 22.2091 +            return u;
 22.2092 +
 22.2093 +        URI v = new URI();
 22.2094 +        v.scheme = u.scheme;
 22.2095 +        v.fragment = u.fragment;
 22.2096 +        v.authority = u.authority;
 22.2097 +        v.userInfo = u.userInfo;
 22.2098 +        v.host = u.host;
 22.2099 +        v.port = u.port;
 22.2100 +        v.path = np;
 22.2101 +        v.query = u.query;
 22.2102 +        return v;
 22.2103 +    }
 22.2104 +
 22.2105 +    // If both URIs are hierarchical, their scheme and authority components are
 22.2106 +    // identical, and the base path is a prefix of the child's path, then
 22.2107 +    // return a relative URI that, when resolved against the base, yields the
 22.2108 +    // child; otherwise, return the child.
 22.2109 +    //
 22.2110 +    private static URI relativize(URI base, URI child) {
 22.2111 +        // check if child if opaque first so that NPE is thrown
 22.2112 +        // if child is null.
 22.2113 +        if (child.isOpaque() || base.isOpaque())
 22.2114 +            return child;
 22.2115 +        if (!equalIgnoringCase(base.scheme, child.scheme)
 22.2116 +            || !equal(base.authority, child.authority))
 22.2117 +            return child;
 22.2118 +
 22.2119 +        String bp = normalize(base.path);
 22.2120 +        String cp = normalize(child.path);
 22.2121 +        if (!bp.equals(cp)) {
 22.2122 +            if (!bp.endsWith("/"))
 22.2123 +                bp = bp + "/";
 22.2124 +            if (!cp.startsWith(bp))
 22.2125 +                return child;
 22.2126 +        }
 22.2127 +
 22.2128 +        URI v = new URI();
 22.2129 +        v.path = cp.substring(bp.length());
 22.2130 +        v.query = child.query;
 22.2131 +        v.fragment = child.fragment;
 22.2132 +        return v;
 22.2133 +    }
 22.2134 +
 22.2135 +
 22.2136 +
 22.2137 +    // -- Path normalization --
 22.2138 +
 22.2139 +    // The following algorithm for path normalization avoids the creation of a
 22.2140 +    // string object for each segment, as well as the use of a string buffer to
 22.2141 +    // compute the final result, by using a single char array and editing it in
 22.2142 +    // place.  The array is first split into segments, replacing each slash
 22.2143 +    // with '\0' and creating a segment-index array, each element of which is
 22.2144 +    // the index of the first char in the corresponding segment.  We then walk
 22.2145 +    // through both arrays, removing ".", "..", and other segments as necessary
 22.2146 +    // by setting their entries in the index array to -1.  Finally, the two
 22.2147 +    // arrays are used to rejoin the segments and compute the final result.
 22.2148 +    //
 22.2149 +    // This code is based upon src/solaris/native/java/io/canonicalize_md.c
 22.2150 +
 22.2151 +
 22.2152 +    // Check the given path to see if it might need normalization.  A path
 22.2153 +    // might need normalization if it contains duplicate slashes, a "."
 22.2154 +    // segment, or a ".." segment.  Return -1 if no further normalization is
 22.2155 +    // possible, otherwise return the number of segments found.
 22.2156 +    //
 22.2157 +    // This method takes a string argument rather than a char array so that
 22.2158 +    // this test can be performed without invoking path.toCharArray().
 22.2159 +    //
 22.2160 +    static private int needsNormalization(String path) {
 22.2161 +        boolean normal = true;
 22.2162 +        int ns = 0;                     // Number of segments
 22.2163 +        int end = path.length() - 1;    // Index of last char in path
 22.2164 +        int p = 0;                      // Index of next char in path
 22.2165 +
 22.2166 +        // Skip initial slashes
 22.2167 +        while (p <= end) {
 22.2168 +            if (path.charAt(p) != '/') break;
 22.2169 +            p++;
 22.2170 +        }
 22.2171 +        if (p > 1) normal = false;
 22.2172 +
 22.2173 +        // Scan segments
 22.2174 +        while (p <= end) {
 22.2175 +
 22.2176 +            // Looking at "." or ".." ?
 22.2177 +            if ((path.charAt(p) == '.')
 22.2178 +                && ((p == end)
 22.2179 +                    || ((path.charAt(p + 1) == '/')
 22.2180 +                        || ((path.charAt(p + 1) == '.')
 22.2181 +                            && ((p + 1 == end)
 22.2182 +                                || (path.charAt(p + 2) == '/')))))) {
 22.2183 +                normal = false;
 22.2184 +            }
 22.2185 +            ns++;
 22.2186 +
 22.2187 +            // Find beginning of next segment
 22.2188 +            while (p <= end) {
 22.2189 +                if (path.charAt(p++) != '/')
 22.2190 +                    continue;
 22.2191 +
 22.2192 +                // Skip redundant slashes
 22.2193 +                while (p <= end) {
 22.2194 +                    if (path.charAt(p) != '/') break;
 22.2195 +                    normal = false;
 22.2196 +                    p++;
 22.2197 +                }
 22.2198 +
 22.2199 +                break;
 22.2200 +            }
 22.2201 +        }
 22.2202 +
 22.2203 +        return normal ? -1 : ns;
 22.2204 +    }
 22.2205 +
 22.2206 +
 22.2207 +    // Split the given path into segments, replacing slashes with nulls and
 22.2208 +    // filling in the given segment-index array.
 22.2209 +    //
 22.2210 +    // Preconditions:
 22.2211 +    //   segs.length == Number of segments in path
 22.2212 +    //
 22.2213 +    // Postconditions:
 22.2214 +    //   All slashes in path replaced by '\0'
 22.2215 +    //   segs[i] == Index of first char in segment i (0 <= i < segs.length)
 22.2216 +    //
 22.2217 +    static private void split(char[] path, int[] segs) {
 22.2218 +        int end = path.length - 1;      // Index of last char in path
 22.2219 +        int p = 0;                      // Index of next char in path
 22.2220 +        int i = 0;                      // Index of current segment
 22.2221 +
 22.2222 +        // Skip initial slashes
 22.2223 +        while (p <= end) {
 22.2224 +            if (path[p] != '/') break;
 22.2225 +            path[p] = '\0';
 22.2226 +            p++;
 22.2227 +        }
 22.2228 +
 22.2229 +        while (p <= end) {
 22.2230 +
 22.2231 +            // Note start of segment
 22.2232 +            segs[i++] = p++;
 22.2233 +
 22.2234 +            // Find beginning of next segment
 22.2235 +            while (p <= end) {
 22.2236 +                if (path[p++] != '/')
 22.2237 +                    continue;
 22.2238 +                path[p - 1] = '\0';
 22.2239 +
 22.2240 +                // Skip redundant slashes
 22.2241 +                while (p <= end) {
 22.2242 +                    if (path[p] != '/') break;
 22.2243 +                    path[p++] = '\0';
 22.2244 +                }
 22.2245 +                break;
 22.2246 +            }
 22.2247 +        }
 22.2248 +
 22.2249 +        if (i != segs.length)
 22.2250 +            throw new InternalError();  // ASSERT
 22.2251 +    }
 22.2252 +
 22.2253 +
 22.2254 +    // Join the segments in the given path according to the given segment-index
 22.2255 +    // array, ignoring those segments whose index entries have been set to -1,
 22.2256 +    // and inserting slashes as needed.  Return the length of the resulting
 22.2257 +    // path.
 22.2258 +    //
 22.2259 +    // Preconditions:
 22.2260 +    //   segs[i] == -1 implies segment i is to be ignored
 22.2261 +    //   path computed by split, as above, with '\0' having replaced '/'
 22.2262 +    //
 22.2263 +    // Postconditions:
 22.2264 +    //   path[0] .. path[return value] == Resulting path
 22.2265 +    //
 22.2266 +    static private int join(char[] path, int[] segs) {
 22.2267 +        int ns = segs.length;           // Number of segments
 22.2268 +        int end = path.length - 1;      // Index of last char in path
 22.2269 +        int p = 0;                      // Index of next path char to write
 22.2270 +
 22.2271 +        if (path[p] == '\0') {
 22.2272 +            // Restore initial slash for absolute paths
 22.2273 +            path[p++] = '/';
 22.2274 +        }
 22.2275 +
 22.2276 +        for (int i = 0; i < ns; i++) {
 22.2277 +            int q = segs[i];            // Current segment
 22.2278 +            if (q == -1)
 22.2279 +                // Ignore this segment
 22.2280 +                continue;
 22.2281 +
 22.2282 +            if (p == q) {
 22.2283 +                // We're already at this segment, so just skip to its end
 22.2284 +                while ((p <= end) && (path[p] != '\0'))
 22.2285 +                    p++;
 22.2286 +                if (p <= end) {
 22.2287 +                    // Preserve trailing slash
 22.2288 +                    path[p++] = '/';
 22.2289 +                }
 22.2290 +            } else if (p < q) {
 22.2291 +                // Copy q down to p
 22.2292 +                while ((q <= end) && (path[q] != '\0'))
 22.2293 +                    path[p++] = path[q++];
 22.2294 +                if (q <= end) {
 22.2295 +                    // Preserve trailing slash
 22.2296 +                    path[p++] = '/';
 22.2297 +                }
 22.2298 +            } else
 22.2299 +                throw new InternalError(); // ASSERT false
 22.2300 +        }
 22.2301 +
 22.2302 +        return p;
 22.2303 +    }
 22.2304 +
 22.2305 +
 22.2306 +    // Remove "." segments from the given path, and remove segment pairs
 22.2307 +    // consisting of a non-".." segment followed by a ".." segment.
 22.2308 +    //
 22.2309 +    private static void removeDots(char[] path, int[] segs) {
 22.2310 +        int ns = segs.length;
 22.2311 +        int end = path.length - 1;
 22.2312 +
 22.2313 +        for (int i = 0; i < ns; i++) {
 22.2314 +            int dots = 0;               // Number of dots found (0, 1, or 2)
 22.2315 +
 22.2316 +            // Find next occurrence of "." or ".."
 22.2317 +            do {
 22.2318 +                int p = segs[i];
 22.2319 +                if (path[p] == '.') {
 22.2320 +                    if (p == end) {
 22.2321 +                        dots = 1;
 22.2322 +                        break;
 22.2323 +                    } else if (path[p + 1] == '\0') {
 22.2324 +                        dots = 1;
 22.2325 +                        break;
 22.2326 +                    } else if ((path[p + 1] == '.')
 22.2327 +                               && ((p + 1 == end)
 22.2328 +                                   || (path[p + 2] == '\0'))) {
 22.2329 +                        dots = 2;
 22.2330 +                        break;
 22.2331 +                    }
 22.2332 +                }
 22.2333 +                i++;
 22.2334 +            } while (i < ns);
 22.2335 +            if ((i > ns) || (dots == 0))
 22.2336 +                break;
 22.2337 +
 22.2338 +            if (dots == 1) {
 22.2339 +                // Remove this occurrence of "."
 22.2340 +                segs[i] = -1;
 22.2341 +            } else {
 22.2342 +                // If there is a preceding non-".." segment, remove both that
 22.2343 +                // segment and this occurrence of ".."; otherwise, leave this
 22.2344 +                // ".." segment as-is.
 22.2345 +                int j;
 22.2346 +                for (j = i - 1; j >= 0; j--) {
 22.2347 +                    if (segs[j] != -1) break;
 22.2348 +                }
 22.2349 +                if (j >= 0) {
 22.2350 +                    int q = segs[j];
 22.2351 +                    if (!((path[q] == '.')
 22.2352 +                          && (path[q + 1] == '.')
 22.2353 +                          && (path[q + 2] == '\0'))) {
 22.2354 +                        segs[i] = -1;
 22.2355 +                        segs[j] = -1;
 22.2356 +                    }
 22.2357 +                }
 22.2358 +            }
 22.2359 +        }
 22.2360 +    }
 22.2361 +
 22.2362 +
 22.2363 +    // DEVIATION: If the normalized path is relative, and if the first
 22.2364 +    // segment could be parsed as a scheme name, then prepend a "." segment
 22.2365 +    //
 22.2366 +    private static void maybeAddLeadingDot(char[] path, int[] segs) {
 22.2367 +
 22.2368 +        if (path[0] == '\0')
 22.2369 +            // The path is absolute
 22.2370 +            return;
 22.2371 +
 22.2372 +        int ns = segs.length;
 22.2373 +        int f = 0;                      // Index of first segment
 22.2374 +        while (f < ns) {
 22.2375 +            if (segs[f] >= 0)
 22.2376 +                break;
 22.2377 +            f++;
 22.2378 +        }
 22.2379 +        if ((f >= ns) || (f == 0))
 22.2380 +            // The path is empty, or else the original first segment survived,
 22.2381 +            // in which case we already know that no leading "." is needed
 22.2382 +            return;
 22.2383 +
 22.2384 +        int p = segs[f];
 22.2385 +        while ((p < path.length) && (path[p] != ':') && (path[p] != '\0')) p++;
 22.2386 +        if (p >= path.length || path[p] == '\0')
 22.2387 +            // No colon in first segment, so no "." needed
 22.2388 +            return;
 22.2389 +
 22.2390 +        // At this point we know that the first segment is unused,
 22.2391 +        // hence we can insert a "." segment at that position
 22.2392 +        path[0] = '.';
 22.2393 +        path[1] = '\0';
 22.2394 +        segs[0] = 0;
 22.2395 +    }
 22.2396 +
 22.2397 +
 22.2398 +    // Normalize the given path string.  A normal path string has no empty
 22.2399 +    // segments (i.e., occurrences of "//"), no segments equal to ".", and no
 22.2400 +    // segments equal to ".." that are preceded by a segment not equal to "..".
 22.2401 +    // In contrast to Unix-style pathname normalization, for URI paths we
 22.2402 +    // always retain trailing slashes.
 22.2403 +    //
 22.2404 +    private static String normalize(String ps) {
 22.2405 +
 22.2406 +        // Does this path need normalization?
 22.2407 +        int ns = needsNormalization(ps);        // Number of segments
 22.2408 +        if (ns < 0)
 22.2409 +            // Nope -- just return it
 22.2410 +            return ps;
 22.2411 +
 22.2412 +        char[] path = ps.toCharArray();         // Path in char-array form
 22.2413 +
 22.2414 +        // Split path into segments
 22.2415 +        int[] segs = new int[ns];               // Segment-index array
 22.2416 +        split(path, segs);
 22.2417 +
 22.2418 +        // Remove dots
 22.2419 +        removeDots(path, segs);
 22.2420 +
 22.2421 +        // Prevent scheme-name confusion
 22.2422 +        maybeAddLeadingDot(path, segs);
 22.2423 +
 22.2424 +        // Join the remaining segments and return the result
 22.2425 +        String s = new String(path, 0, join(path, segs));
 22.2426 +        if (s.equals(ps)) {
 22.2427 +            // string was already normalized
 22.2428 +            return ps;
 22.2429 +        }
 22.2430 +        return s;
 22.2431 +    }
 22.2432 +
 22.2433 +
 22.2434 +
 22.2435 +    // -- Character classes for parsing --
 22.2436 +
 22.2437 +    // RFC2396 precisely specifies which characters in the US-ASCII charset are
 22.2438 +    // permissible in the various components of a URI reference.  We here
 22.2439 +    // define a set of mask pairs to aid in enforcing these restrictions.  Each
 22.2440 +    // mask pair consists of two longs, a low mask and a high mask.  Taken
 22.2441 +    // together they represent a 128-bit mask, where bit i is set iff the
 22.2442 +    // character with value i is permitted.
 22.2443 +    //
 22.2444 +    // This approach is more efficient than sequentially searching arrays of
 22.2445 +    // permitted characters.  It could be made still more efficient by
 22.2446 +    // precompiling the mask information so that a character's presence in a
 22.2447 +    // given mask could be determined by a single table lookup.
 22.2448 +
 22.2449 +    // Compute the low-order mask for the characters in the given string
 22.2450 +    private static long lowMask(String chars) {
 22.2451 +        int n = chars.length();
 22.2452 +        long m = 0;
 22.2453 +        for (int i = 0; i < n; i++) {
 22.2454 +            char c = chars.charAt(i);
 22.2455 +            if (c < 64)
 22.2456 +                m |= (1L << c);
 22.2457 +        }
 22.2458 +        return m;
 22.2459 +    }
 22.2460 +
 22.2461 +    // Compute the high-order mask for the characters in the given string
 22.2462 +    private static long highMask(String chars) {
 22.2463 +        int n = chars.length();
 22.2464 +        long m = 0;
 22.2465 +        for (int i = 0; i < n; i++) {
 22.2466 +            char c = chars.charAt(i);
 22.2467 +            if ((c >= 64) && (c < 128))
 22.2468 +                m |= (1L << (c - 64));
 22.2469 +        }
 22.2470 +        return m;
 22.2471 +    }
 22.2472 +
 22.2473 +    // Compute a low-order mask for the characters
 22.2474 +    // between first and last, inclusive
 22.2475 +    private static long lowMask(char first, char last) {
 22.2476 +        long m = 0;
 22.2477 +        int f = Math.max(Math.min(first, 63), 0);
 22.2478 +        int l = Math.max(Math.min(last, 63), 0);
 22.2479 +        for (int i = f; i <= l; i++)
 22.2480 +            m |= 1L << i;
 22.2481 +        return m;
 22.2482 +    }
 22.2483 +
 22.2484 +    // Compute a high-order mask for the characters
 22.2485 +    // between first and last, inclusive
 22.2486 +    private static long highMask(char first, char last) {
 22.2487 +        long m = 0;
 22.2488 +        int f = Math.max(Math.min(first, 127), 64) - 64;
 22.2489 +        int l = Math.max(Math.min(last, 127), 64) - 64;
 22.2490 +        for (int i = f; i <= l; i++)
 22.2491 +            m |= 1L << i;
 22.2492 +        return m;
 22.2493 +    }
 22.2494 +
 22.2495 +    // Tell whether the given character is permitted by the given mask pair
 22.2496 +    private static boolean match(char c, long lowMask, long highMask) {
 22.2497 +        if (c == 0) // 0 doesn't have a slot in the mask. So, it never matches.
 22.2498 +            return false;
 22.2499 +        if (c < 64)
 22.2500 +            return ((1L << c) & lowMask) != 0;
 22.2501 +        if (c < 128)
 22.2502 +            return ((1L << (c - 64)) & highMask) != 0;
 22.2503 +        return false;
 22.2504 +    }
 22.2505 +
 22.2506 +    // Character-class masks, in reverse order from RFC2396 because
 22.2507 +    // initializers for static fields cannot make forward references.
 22.2508 +
 22.2509 +    // digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
 22.2510 +    //            "8" | "9"
 22.2511 +    private static final long L_DIGIT = lowMask('0', '9');
 22.2512 +    private static final long H_DIGIT = 0L;
 22.2513 +
 22.2514 +    // upalpha  = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
 22.2515 +    //            "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
 22.2516 +    //            "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
 22.2517 +    private static final long L_UPALPHA = 0L;
 22.2518 +    private static final long H_UPALPHA = highMask('A', 'Z');
 22.2519 +
 22.2520 +    // lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
 22.2521 +    //            "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
 22.2522 +    //            "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
 22.2523 +    private static final long L_LOWALPHA = 0L;
 22.2524 +    private static final long H_LOWALPHA = highMask('a', 'z');
 22.2525 +
 22.2526 +    // alpha         = lowalpha | upalpha
 22.2527 +    private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA;
 22.2528 +    private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA;
 22.2529 +
 22.2530 +    // alphanum      = alpha | digit
 22.2531 +    private static final long L_ALPHANUM = L_DIGIT | L_ALPHA;
 22.2532 +    private static final long H_ALPHANUM = H_DIGIT | H_ALPHA;
 22.2533 +
 22.2534 +    // hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
 22.2535 +    //                         "a" | "b" | "c" | "d" | "e" | "f"
 22.2536 +    private static final long L_HEX = L_DIGIT;
 22.2537 +    private static final long H_HEX = highMask('A', 'F') | highMask('a', 'f');
 22.2538 +
 22.2539 +    // mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
 22.2540 +    //                 "(" | ")"
 22.2541 +    private static final long L_MARK = lowMask("-_.!~*'()");
 22.2542 +    private static final long H_MARK = highMask("-_.!~*'()");
 22.2543 +
 22.2544 +    // unreserved    = alphanum | mark
 22.2545 +    private static final long L_UNRESERVED = L_ALPHANUM | L_MARK;
 22.2546 +    private static final long H_UNRESERVED = H_ALPHANUM | H_MARK;
 22.2547 +
 22.2548 +    // reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
 22.2549 +    //                 "$" | "," | "[" | "]"
 22.2550 +    // Added per RFC2732: "[", "]"
 22.2551 +    private static final long L_RESERVED = lowMask(";/?:@&=+$,[]");
 22.2552 +    private static final long H_RESERVED = highMask(";/?:@&=+$,[]");
 22.2553 +
 22.2554 +    // The zero'th bit is used to indicate that escape pairs and non-US-ASCII
 22.2555 +    // characters are allowed; this is handled by the scanEscape method below.
 22.2556 +    private static final long L_ESCAPED = 1L;
 22.2557 +    private static final long H_ESCAPED = 0L;
 22.2558 +
 22.2559 +    // uric          = reserved | unreserved | escaped
 22.2560 +    private static final long L_URIC = L_RESERVED | L_UNRESERVED | L_ESCAPED;
 22.2561 +    private static final long H_URIC = H_RESERVED | H_UNRESERVED | H_ESCAPED;
 22.2562 +
 22.2563 +    // pchar         = unreserved | escaped |
 22.2564 +    //                 ":" | "@" | "&" | "=" | "+" | "$" | ","
 22.2565 +    private static final long L_PCHAR
 22.2566 +        = L_UNRESERVED | L_ESCAPED | lowMask(":@&=+$,");
 22.2567 +    private static final long H_PCHAR
 22.2568 +        = H_UNRESERVED | H_ESCAPED | highMask(":@&=+$,");
 22.2569 +
 22.2570 +    // All valid path characters
 22.2571 +    private static final long L_PATH = L_PCHAR | lowMask(";/");
 22.2572 +    private static final long H_PATH = H_PCHAR | highMask(";/");
 22.2573 +
 22.2574 +    // Dash, for use in domainlabel and toplabel
 22.2575 +    private static final long L_DASH = lowMask("-");
 22.2576 +    private static final long H_DASH = highMask("-");
 22.2577 +
 22.2578 +    // Dot, for use in hostnames
 22.2579 +    private static final long L_DOT = lowMask(".");
 22.2580 +    private static final long H_DOT = highMask(".");
 22.2581 +
 22.2582 +    // userinfo      = *( unreserved | escaped |
 22.2583 +    //                    ";" | ":" | "&" | "=" | "+" | "$" | "," )
 22.2584 +    private static final long L_USERINFO
 22.2585 +        = L_UNRESERVED | L_ESCAPED | lowMask(";:&=+$,");
 22.2586 +    private static final long H_USERINFO
 22.2587 +        = H_UNRESERVED | H_ESCAPED | highMask(";:&=+$,");
 22.2588 +
 22.2589 +    // reg_name      = 1*( unreserved | escaped | "$" | "," |
 22.2590 +    //                     ";" | ":" | "@" | "&" | "=" | "+" )
 22.2591 +    private static final long L_REG_NAME
 22.2592 +        = L_UNRESERVED | L_ESCAPED | lowMask("$,;:@&=+");
 22.2593 +    private static final long H_REG_NAME
 22.2594 +        = H_UNRESERVED | H_ESCAPED | highMask("$,;:@&=+");
 22.2595 +
 22.2596 +    // All valid characters for server-based authorities
 22.2597 +    private static final long L_SERVER
 22.2598 +        = L_USERINFO | L_ALPHANUM | L_DASH | lowMask(".:@[]");
 22.2599 +    private static final long H_SERVER
 22.2600 +        = H_USERINFO | H_ALPHANUM | H_DASH | highMask(".:@[]");
 22.2601 +
 22.2602 +    // Special case of server authority that represents an IPv6 address
 22.2603 +    // In this case, a % does not signify an escape sequence
 22.2604 +    private static final long L_SERVER_PERCENT
 22.2605 +        = L_SERVER | lowMask("%");
 22.2606 +    private static final long H_SERVER_PERCENT
 22.2607 +        = H_SERVER | highMask("%");
 22.2608 +    private static final long L_LEFT_BRACKET = lowMask("[");
 22.2609 +    private static final long H_LEFT_BRACKET = highMask("[");
 22.2610 +
 22.2611 +    // scheme        = alpha *( alpha | digit | "+" | "-" | "." )
 22.2612 +    private static final long L_SCHEME = L_ALPHA | L_DIGIT | lowMask("+-.");
 22.2613 +    private static final long H_SCHEME = H_ALPHA | H_DIGIT | highMask("+-.");
 22.2614 +
 22.2615 +    // uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
 22.2616 +    //                 "&" | "=" | "+" | "$" | ","
 22.2617 +    private static final long L_URIC_NO_SLASH
 22.2618 +        = L_UNRESERVED | L_ESCAPED | lowMask(";?:@&=+$,");
 22.2619 +    private static final long H_URIC_NO_SLASH
 22.2620 +        = H_UNRESERVED | H_ESCAPED | highMask(";?:@&=+$,");
 22.2621 +
 22.2622 +
 22.2623 +    // -- Escaping and encoding --
 22.2624 +
 22.2625 +    private final static char[] hexDigits = {
 22.2626 +        '0', '1', '2', '3', '4', '5', '6', '7',
 22.2627 +        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
 22.2628 +    };
 22.2629 +
 22.2630 +    private static void appendEscape(StringBuffer sb, byte b) {
 22.2631 +        sb.append('%');
 22.2632 +        sb.append(hexDigits[(b >> 4) & 0x0f]);
 22.2633 +        sb.append(hexDigits[(b >> 0) & 0x0f]);
 22.2634 +    }
 22.2635 +
 22.2636 +    private static void appendEncoded(StringBuffer sb, char c) {
 22.2637 +        ByteBuffer bb = null;
 22.2638 +        try {
 22.2639 +            bb = ThreadLocalCoders.encoderFor("UTF-8")
 22.2640 +                .encode(CharBuffer.wrap("" + c));
 22.2641 +        } catch (CharacterCodingException x) {
 22.2642 +            assert false;
 22.2643 +        }
 22.2644 +        while (bb.hasRemaining()) {
 22.2645 +            int b = bb.get() & 0xff;
 22.2646 +            if (b >= 0x80)
 22.2647 +                appendEscape(sb, (byte)b);
 22.2648 +            else
 22.2649 +                sb.append((char)b);
 22.2650 +        }
 22.2651 +    }
 22.2652 +
 22.2653 +    // Quote any characters in s that are not permitted
 22.2654 +    // by the given mask pair
 22.2655 +    //
 22.2656 +    private static String quote(String s, long lowMask, long highMask) {
 22.2657 +        int n = s.length();
 22.2658 +        StringBuffer sb = null;
 22.2659 +        boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
 22.2660 +        for (int i = 0; i < s.length(); i++) {
 22.2661 +            char c = s.charAt(i);
 22.2662 +            if (c < '\u0080') {
 22.2663 +                if (!match(c, lowMask, highMask)) {
 22.2664 +                    if (sb == null) {
 22.2665 +                        sb = new StringBuffer();
 22.2666 +                        sb.append(s.substring(0, i));
 22.2667 +                    }
 22.2668 +                    appendEscape(sb, (byte)c);
 22.2669 +                } else {
 22.2670 +                    if (sb != null)
 22.2671 +                        sb.append(c);
 22.2672 +                }
 22.2673 +            } else if (allowNonASCII
 22.2674 +                       && (Character.isSpaceChar(c)
 22.2675 +                           || Character.isISOControl(c))) {
 22.2676 +                if (sb == null) {
 22.2677 +                    sb = new StringBuffer();
 22.2678 +                    sb.append(s.substring(0, i));
 22.2679 +                }
 22.2680 +                appendEncoded(sb, c);
 22.2681 +            } else {
 22.2682 +                if (sb != null)
 22.2683 +                    sb.append(c);
 22.2684 +            }
 22.2685 +        }
 22.2686 +        return (sb == null) ? s : sb.toString();
 22.2687 +    }
 22.2688 +
 22.2689 +    // Encodes all characters >= \u0080 into escaped, normalized UTF-8 octets,
 22.2690 +    // assuming that s is otherwise legal
 22.2691 +    //
 22.2692 +    private static String encode(String s) {
 22.2693 +        int n = s.length();
 22.2694 +        if (n == 0)
 22.2695 +            return s;
 22.2696 +
 22.2697 +        // First check whether we actually need to encode
 22.2698 +        for (int i = 0;;) {
 22.2699 +            if (s.charAt(i) >= '\u0080')
 22.2700 +                break;
 22.2701 +            if (++i >= n)
 22.2702 +                return s;
 22.2703 +        }
 22.2704 +
 22.2705 +        String ns = Normalizer.normalize(s, Normalizer.Form.NFC);
 22.2706 +        ByteBuffer bb = null;
 22.2707 +        try {
 22.2708 +            bb = ThreadLocalCoders.encoderFor("UTF-8")
 22.2709 +                .encode(CharBuffer.wrap(ns));
 22.2710 +        } catch (CharacterCodingException x) {
 22.2711 +            assert false;
 22.2712 +        }
 22.2713 +
 22.2714 +        StringBuffer sb = new StringBuffer();
 22.2715 +        while (bb.hasRemaining()) {
 22.2716 +            int b = bb.get() & 0xff;
 22.2717 +            if (b >= 0x80)
 22.2718 +                appendEscape(sb, (byte)b);
 22.2719 +            else
 22.2720 +                sb.append((char)b);
 22.2721 +        }
 22.2722 +        return sb.toString();
 22.2723 +    }
 22.2724 +
 22.2725 +    private static int decode(char c) {
 22.2726 +        if ((c >= '0') && (c <= '9'))
 22.2727 +            return c - '0';
 22.2728 +        if ((c >= 'a') && (c <= 'f'))
 22.2729 +            return c - 'a' + 10;
 22.2730 +        if ((c >= 'A') && (c <= 'F'))
 22.2731 +            return c - 'A' + 10;
 22.2732 +        assert false;
 22.2733 +        return -1;
 22.2734 +    }
 22.2735 +
 22.2736 +    private static byte decode(char c1, char c2) {
 22.2737 +        return (byte)(  ((decode(c1) & 0xf) << 4)
 22.2738 +                      | ((decode(c2) & 0xf) << 0));
 22.2739 +    }
 22.2740 +
 22.2741 +    // Evaluates all escapes in s, applying UTF-8 decoding if needed.  Assumes
 22.2742 +    // that escapes are well-formed syntactically, i.e., of the form %XX.  If a
 22.2743 +    // sequence of escaped octets is not valid UTF-8 then the erroneous octets
 22.2744 +    // are replaced with '\uFFFD'.
 22.2745 +    // Exception: any "%" found between "[]" is left alone. It is an IPv6 literal
 22.2746 +    //            with a scope_id
 22.2747 +    //
 22.2748 +    private static String decode(String s) {
 22.2749 +        if (s == null)
 22.2750 +            return s;
 22.2751 +        int n = s.length();
 22.2752 +        if (n == 0)
 22.2753 +            return s;
 22.2754 +        if (s.indexOf('%') < 0)
 22.2755 +            return s;
 22.2756 +
 22.2757 +        StringBuffer sb = new StringBuffer(n);
 22.2758 +        ByteBuffer bb = ByteBuffer.allocate(n);
 22.2759 +        CharBuffer cb = CharBuffer.allocate(n);
 22.2760 +        CharsetDecoder dec = ThreadLocalCoders.decoderFor("UTF-8")
 22.2761 +            .onMalformedInput(CodingErrorAction.REPLACE)
 22.2762 +            .onUnmappableCharacter(CodingErrorAction.REPLACE);
 22.2763 +
 22.2764 +        // This is not horribly efficient, but it will do for now
 22.2765 +        char c = s.charAt(0);
 22.2766 +        boolean betweenBrackets = false;
 22.2767 +
 22.2768 +        for (int i = 0; i < n;) {
 22.2769 +            assert c == s.charAt(i);    // Loop invariant
 22.2770 +            if (c == '[') {
 22.2771 +                betweenBrackets = true;
 22.2772 +            } else if (betweenBrackets && c == ']') {
 22.2773 +                betweenBrackets = false;
 22.2774 +            }
 22.2775 +            if (c != '%' || betweenBrackets) {
 22.2776 +                sb.append(c);
 22.2777 +                if (++i >= n)
 22.2778 +                    break;
 22.2779 +                c = s.charAt(i);
 22.2780 +                continue;
 22.2781 +            }
 22.2782 +            bb.clear();
 22.2783 +            int ui = i;
 22.2784 +            for (;;) {
 22.2785 +                assert (n - i >= 2);
 22.2786 +                bb.put(decode(s.charAt(++i), s.charAt(++i)));
 22.2787 +                if (++i >= n)
 22.2788 +                    break;
 22.2789 +                c = s.charAt(i);
 22.2790 +                if (c != '%')
 22.2791 +                    break;
 22.2792 +            }
 22.2793 +            bb.flip();
 22.2794 +            cb.clear();
 22.2795 +            dec.reset();
 22.2796 +            CoderResult cr = dec.decode(bb, cb, true);
 22.2797 +            assert cr.isUnderflow();
 22.2798 +            cr = dec.flush(cb);
 22.2799 +            assert cr.isUnderflow();
 22.2800 +            sb.append(cb.flip().toString());
 22.2801 +        }
 22.2802 +
 22.2803 +        return sb.toString();
 22.2804 +    }
 22.2805 +
 22.2806 +
 22.2807 +    // -- Parsing --
 22.2808 +
 22.2809 +    // For convenience we wrap the input URI string in a new instance of the
 22.2810 +    // following internal class.  This saves always having to pass the input
 22.2811 +    // string as an argument to each internal scan/parse method.
 22.2812 +
 22.2813 +    private class Parser {
 22.2814 +
 22.2815 +        private String input;           // URI input string
 22.2816 +        private boolean requireServerAuthority = false;
 22.2817 +
 22.2818 +        Parser(String s) {
 22.2819 +            input = s;
 22.2820 +            string = s;
 22.2821 +        }
 22.2822 +
 22.2823 +        // -- Methods for throwing URISyntaxException in various ways --
 22.2824 +
 22.2825 +        private void fail(String reason) throws URISyntaxException {
 22.2826 +            throw new URISyntaxException(input, reason);
 22.2827 +        }
 22.2828 +
 22.2829 +        private void fail(String reason, int p) throws URISyntaxException {
 22.2830 +            throw new URISyntaxException(input, reason, p);
 22.2831 +        }
 22.2832 +
 22.2833 +        private void failExpecting(String expected, int p)
 22.2834 +            throws URISyntaxException
 22.2835 +        {
 22.2836 +            fail("Expected " + expected, p);
 22.2837 +        }
 22.2838 +
 22.2839 +        private void failExpecting(String expected, String prior, int p)
 22.2840 +            throws URISyntaxException
 22.2841 +        {
 22.2842 +            fail("Expected " + expected + " following " + prior, p);
 22.2843 +        }
 22.2844 +
 22.2845 +
 22.2846 +        // -- Simple access to the input string --
 22.2847 +
 22.2848 +        // Return a substring of the input string
 22.2849 +        //
 22.2850 +        private String substring(int start, int end) {
 22.2851 +            return input.substring(start, end);
 22.2852 +        }
 22.2853 +
 22.2854 +        // Return the char at position p,
 22.2855 +        // assuming that p < input.length()
 22.2856 +        //
 22.2857 +        private char charAt(int p) {
 22.2858 +            return input.charAt(p);
 22.2859 +        }
 22.2860 +
 22.2861 +        // Tells whether start < end and, if so, whether charAt(start) == c
 22.2862 +        //
 22.2863 +        private boolean at(int start, int end, char c) {
 22.2864 +            return (start < end) && (charAt(start) == c);
 22.2865 +        }
 22.2866 +
 22.2867 +        // Tells whether start + s.length() < end and, if so,
 22.2868 +        // whether the chars at the start position match s exactly
 22.2869 +        //
 22.2870 +        private boolean at(int start, int end, String s) {
 22.2871 +            int p = start;
 22.2872 +            int sn = s.length();
 22.2873 +            if (sn > end - p)
 22.2874 +                return false;
 22.2875 +            int i = 0;
 22.2876 +            while (i < sn) {
 22.2877 +                if (charAt(p++) != s.charAt(i)) {
 22.2878 +                    break;
 22.2879 +                }
 22.2880 +                i++;
 22.2881 +            }
 22.2882 +            return (i == sn);
 22.2883 +        }
 22.2884 +
 22.2885 +
 22.2886 +        // -- Scanning --
 22.2887 +
 22.2888 +        // The various scan and parse methods that follow use a uniform
 22.2889 +        // convention of taking the current start position and end index as
 22.2890 +        // their first two arguments.  The start is inclusive while the end is
 22.2891 +        // exclusive, just as in the String class, i.e., a start/end pair
 22.2892 +        // denotes the left-open interval [start, end) of the input string.
 22.2893 +        //
 22.2894 +        // These methods never proceed past the end position.  They may return
 22.2895 +        // -1 to indicate outright failure, but more often they simply return
 22.2896 +        // the position of the first char after the last char scanned.  Thus
 22.2897 +        // a typical idiom is
 22.2898 +        //
 22.2899 +        //     int p = start;
 22.2900 +        //     int q = scan(p, end, ...);
 22.2901 +        //     if (q > p)
 22.2902 +        //         // We scanned something
 22.2903 +        //         ...;
 22.2904 +        //     else if (q == p)
 22.2905 +        //         // We scanned nothing
 22.2906 +        //         ...;
 22.2907 +        //     else if (q == -1)
 22.2908 +        //         // Something went wrong
 22.2909 +        //         ...;
 22.2910 +
 22.2911 +
 22.2912 +        // Scan a specific char: If the char at the given start position is
 22.2913 +        // equal to c, return the index of the next char; otherwise, return the
 22.2914 +        // start position.
 22.2915 +        //
 22.2916 +        private int scan(int start, int end, char c) {
 22.2917 +            if ((start < end) && (charAt(start) == c))
 22.2918 +                return start + 1;
 22.2919 +            return start;
 22.2920 +        }
 22.2921 +
 22.2922 +        // Scan forward from the given start position.  Stop at the first char
 22.2923 +        // in the err string (in which case -1 is returned), or the first char
 22.2924 +        // in the stop string (in which case the index of the preceding char is
 22.2925 +        // returned), or the end of the input string (in which case the length
 22.2926 +        // of the input string is returned).  May return the start position if
 22.2927 +        // nothing matches.
 22.2928 +        //
 22.2929 +        private int scan(int start, int end, String err, String stop) {
 22.2930 +            int p = start;
 22.2931 +            while (p < end) {
 22.2932 +                char c = charAt(p);
 22.2933 +                if (err.indexOf(c) >= 0)
 22.2934 +                    return -1;
 22.2935 +                if (stop.indexOf(c) >= 0)
 22.2936 +                    break;
 22.2937 +                p++;
 22.2938 +            }
 22.2939 +            return p;
 22.2940 +        }
 22.2941 +
 22.2942 +        // Scan a potential escape sequence, starting at the given position,
 22.2943 +        // with the given first char (i.e., charAt(start) == c).
 22.2944 +        //
 22.2945 +        // This method assumes that if escapes are allowed then visible
 22.2946 +        // non-US-ASCII chars are also allowed.
 22.2947 +        //
 22.2948 +        private int scanEscape(int start, int n, char first)
 22.2949 +            throws URISyntaxException
 22.2950 +        {
 22.2951 +            int p = start;
 22.2952 +            char c = first;
 22.2953 +            if (c == '%') {
 22.2954 +                // Process escape pair
 22.2955 +                if ((p + 3 <= n)
 22.2956 +                    && match(charAt(p + 1), L_HEX, H_HEX)
 22.2957 +                    && match(charAt(p + 2), L_HEX, H_HEX)) {
 22.2958 +                    return p + 3;
 22.2959 +                }
 22.2960 +                fail("Malformed escape pair", p);
 22.2961 +            } else if ((c > 128)
 22.2962 +                       && !Character.isSpaceChar(c)
 22.2963 +                       && !Character.isISOControl(c)) {
 22.2964 +                // Allow unescaped but visible non-US-ASCII chars
 22.2965 +                return p + 1;
 22.2966 +            }
 22.2967 +            return p;
 22.2968 +        }
 22.2969 +
 22.2970 +        // Scan chars that match the given mask pair
 22.2971 +        //
 22.2972 +        private int scan(int start, int n, long lowMask, long highMask)
 22.2973 +            throws URISyntaxException
 22.2974 +        {
 22.2975 +            int p = start;
 22.2976 +            while (p < n) {
 22.2977 +                char c = charAt(p);
 22.2978 +                if (match(c, lowMask, highMask)) {
 22.2979 +                    p++;
 22.2980 +                    continue;
 22.2981 +                }
 22.2982 +                if ((lowMask & L_ESCAPED) != 0) {
 22.2983 +                    int q = scanEscape(p, n, c);
 22.2984 +                    if (q > p) {
 22.2985 +                        p = q;
 22.2986 +                        continue;
 22.2987 +                    }
 22.2988 +                }
 22.2989 +                break;
 22.2990 +            }
 22.2991 +            return p;
 22.2992 +        }
 22.2993 +
 22.2994 +        // Check that each of the chars in [start, end) matches the given mask
 22.2995 +        //
 22.2996 +        private void checkChars(int start, int end,
 22.2997 +                                long lowMask, long highMask,
 22.2998 +                                String what)
 22.2999 +            throws URISyntaxException
 22.3000 +        {
 22.3001 +            int p = scan(start, end, lowMask, highMask);
 22.3002 +            if (p < end)
 22.3003 +                fail("Illegal character in " + what, p);
 22.3004 +        }
 22.3005 +
 22.3006 +        // Check that the char at position p matches the given mask
 22.3007 +        //
 22.3008 +        private void checkChar(int p,
 22.3009 +                               long lowMask, long highMask,
 22.3010 +                               String what)
 22.3011 +            throws URISyntaxException
 22.3012 +        {
 22.3013 +            checkChars(p, p + 1, lowMask, highMask, what);
 22.3014 +        }
 22.3015 +
 22.3016 +
 22.3017 +        // -- Parsing --
 22.3018 +
 22.3019 +        // [<scheme>:]<scheme-specific-part>[#<fragment>]
 22.3020 +        //
 22.3021 +        void parse(boolean rsa) throws URISyntaxException {
 22.3022 +            requireServerAuthority = rsa;
 22.3023 +            int ssp;                    // Start of scheme-specific part
 22.3024 +            int n = input.length();
 22.3025 +            int p = scan(0, n, "/?#", ":");
 22.3026 +            if ((p >= 0) && at(p, n, ':')) {
 22.3027 +                if (p == 0)
 22.3028 +                    failExpecting("scheme name", 0);
 22.3029 +                checkChar(0, L_ALPHA, H_ALPHA, "scheme name");
 22.3030 +                checkChars(1, p, L_SCHEME, H_SCHEME, "scheme name");
 22.3031 +                scheme = substring(0, p);
 22.3032 +                p++;                    // Skip ':'
 22.3033 +                ssp = p;
 22.3034 +                if (at(p, n, '/')) {
 22.3035 +                    p = parseHierarchical(p, n);
 22.3036 +                } else {
 22.3037 +                    int q = scan(p, n, "", "#");
 22.3038 +                    if (q <= p)
 22.3039 +                        failExpecting("scheme-specific part", p);
 22.3040 +                    checkChars(p, q, L_URIC, H_URIC, "opaque part");
 22.3041 +                    p = q;
 22.3042 +                }
 22.3043 +            } else {
 22.3044 +                ssp = 0;
 22.3045 +                p = parseHierarchical(0, n);
 22.3046 +            }
 22.3047 +            schemeSpecificPart = substring(ssp, p);
 22.3048 +            if (at(p, n, '#')) {
 22.3049 +                checkChars(p + 1, n, L_URIC, H_URIC, "fragment");
 22.3050 +                fragment = substring(p + 1, n);
 22.3051 +                p = n;
 22.3052 +            }
 22.3053 +            if (p < n)
 22.3054 +                fail("end of URI", p);
 22.3055 +        }
 22.3056 +
 22.3057 +        // [//authority]<path>[?<query>]
 22.3058 +        //
 22.3059 +        // DEVIATION from RFC2396: We allow an empty authority component as
 22.3060 +        // long as it's followed by a non-empty path, query component, or
 22.3061 +        // fragment component.  This is so that URIs such as "file:///foo/bar"
 22.3062 +        // will parse.  This seems to be the intent of RFC2396, though the
 22.3063 +        // grammar does not permit it.  If the authority is empty then the
 22.3064 +        // userInfo, host, and port components are undefined.
 22.3065 +        //
 22.3066 +        // DEVIATION from RFC2396: We allow empty relative paths.  This seems
 22.3067 +        // to be the intent of RFC2396, but the grammar does not permit it.
 22.3068 +        // The primary consequence of this deviation is that "#f" parses as a
 22.3069 +        // relative URI with an empty path.
 22.3070 +        //
 22.3071 +        private int parseHierarchical(int start, int n)
 22.3072 +            throws URISyntaxException
 22.3073 +        {
 22.3074 +            int p = start;
 22.3075 +            if (at(p, n, '/') && at(p + 1, n, '/')) {
 22.3076 +                p += 2;
 22.3077 +                int q = scan(p, n, "", "/?#");
 22.3078 +                if (q > p) {
 22.3079 +                    p = parseAuthority(p, q);
 22.3080 +                } else if (q < n) {
 22.3081 +                    // DEVIATION: Allow empty authority prior to non-empty
 22.3082 +                    // path, query component or fragment identifier
 22.3083 +                } else
 22.3084 +                    failExpecting("authority", p);
 22.3085 +            }
 22.3086 +            int q = scan(p, n, "", "?#"); // DEVIATION: May be empty
 22.3087 +            checkChars(p, q, L_PATH, H_PATH, "path");
 22.3088 +            path = substring(p, q);
 22.3089 +            p = q;
 22.3090 +            if (at(p, n, '?')) {
 22.3091 +                p++;
 22.3092 +                q = scan(p, n, "", "#");
 22.3093 +                checkChars(p, q, L_URIC, H_URIC, "query");
 22.3094 +                query = substring(p, q);
 22.3095 +                p = q;
 22.3096 +            }
 22.3097 +            return p;
 22.3098 +        }
 22.3099 +
 22.3100 +        // authority     = server | reg_name
 22.3101 +        //
 22.3102 +        // Ambiguity: An authority that is a registry name rather than a server
 22.3103 +        // might have a prefix that parses as a server.  We use the fact that
 22.3104 +        // the authority component is always followed by '/' or the end of the
 22.3105 +        // input string to resolve this: If the complete authority did not
 22.3106 +        // parse as a server then we try to parse it as a registry name.
 22.3107 +        //
 22.3108 +        private int parseAuthority(int start, int n)
 22.3109 +            throws URISyntaxException
 22.3110 +        {
 22.3111 +            int p = start;
 22.3112 +            int q = p;
 22.3113 +            URISyntaxException ex = null;
 22.3114 +
 22.3115 +            boolean serverChars;
 22.3116 +            boolean regChars;
 22.3117 +
 22.3118 +            if (scan(p, n, "", "]") > p) {
 22.3119 +                // contains a literal IPv6 address, therefore % is allowed
 22.3120 +                serverChars = (scan(p, n, L_SERVER_PERCENT, H_SERVER_PERCENT) == n);
 22.3121 +            } else {
 22.3122 +                serverChars = (scan(p, n, L_SERVER, H_SERVER) == n);
 22.3123 +            }
 22.3124 +            regChars = (scan(p, n, L_REG_NAME, H_REG_NAME) == n);
 22.3125 +
 22.3126 +            if (regChars && !serverChars) {
 22.3127 +                // Must be a registry-based authority
 22.3128 +                authority = substring(p, n);
 22.3129 +                return n;
 22.3130 +            }
 22.3131 +
 22.3132 +            if (serverChars) {
 22.3133 +                // Might be (probably is) a server-based authority, so attempt
 22.3134 +                // to parse it as such.  If the attempt fails, try to treat it
 22.3135 +                // as a registry-based authority.
 22.3136 +                try {
 22.3137 +                    q = parseServer(p, n);
 22.3138 +                    if (q < n)
 22.3139 +                        failExpecting("end of authority", q);
 22.3140 +                    authority = substring(p, n);
 22.3141 +                } catch (URISyntaxException x) {
 22.3142 +                    // Undo results of failed parse
 22.3143 +                    userInfo = null;
 22.3144 +                    host = null;
 22.3145 +                    port = -1;
 22.3146 +                    if (requireServerAuthority) {
 22.3147 +                        // If we're insisting upon a server-based authority,
 22.3148 +                        // then just re-throw the exception
 22.3149 +                        throw x;
 22.3150 +                    } else {
 22.3151 +                        // Save the exception in case it doesn't parse as a
 22.3152 +                        // registry either
 22.3153 +                        ex = x;
 22.3154 +                        q = p;
 22.3155 +                    }
 22.3156 +                }
 22.3157 +            }
 22.3158 +
 22.3159 +            if (q < n) {
 22.3160 +                if (regChars) {
 22.3161 +                    // Registry-based authority
 22.3162 +                    authority = substring(p, n);
 22.3163 +                } else if (ex != null) {
 22.3164 +                    // Re-throw exception; it was probably due to
 22.3165 +                    // a malformed IPv6 address
 22.3166 +                    throw ex;
 22.3167 +                } else {
 22.3168 +                    fail("Illegal character in authority", q);
 22.3169 +                }
 22.3170 +            }
 22.3171 +
 22.3172 +            return n;
 22.3173 +        }
 22.3174 +
 22.3175 +
 22.3176 +        // [<userinfo>@]<host>[:<port>]
 22.3177 +        //
 22.3178 +        private int parseServer(int start, int n)
 22.3179 +            throws URISyntaxException
 22.3180 +        {
 22.3181 +            int p = start;
 22.3182 +            int q;
 22.3183 +
 22.3184 +            // userinfo
 22.3185 +            q = scan(p, n, "/?#", "@");
 22.3186 +            if ((q >= p) && at(q, n, '@')) {
 22.3187 +                checkChars(p, q, L_USERINFO, H_USERINFO, "user info");
 22.3188 +                userInfo = substring(p, q);
 22.3189 +                p = q + 1;              // Skip '@'
 22.3190 +            }
 22.3191 +
 22.3192 +            // hostname, IPv4 address, or IPv6 address
 22.3193 +            if (at(p, n, '[')) {
 22.3194 +                // DEVIATION from RFC2396: Support IPv6 addresses, per RFC2732
 22.3195 +                p++;
 22.3196 +                q = scan(p, n, "/?#", "]");
 22.3197 +                if ((q > p) && at(q, n, ']')) {
 22.3198 +                    // look for a "%" scope id
 22.3199 +                    int r = scan (p, q, "", "%");
 22.3200 +                    if (r > p) {
 22.3201 +                        parseIPv6Reference(p, r);
 22.3202 +                        if (r+1 == q) {
 22.3203 +                            fail ("scope id expected");
 22.3204 +                        }
 22.3205 +                        checkChars (r+1, q, L_ALPHANUM, H_ALPHANUM,
 22.3206 +                                                "scope id");
 22.3207 +                    } else {
 22.3208 +                        parseIPv6Reference(p, q);
 22.3209 +                    }
 22.3210 +                    host = substring(p-1, q+1);
 22.3211 +                    p = q + 1;
 22.3212 +                } else {
 22.3213 +                    failExpecting("closing bracket for IPv6 address", q);
 22.3214 +                }
 22.3215 +            } else {
 22.3216 +                q = parseIPv4Address(p, n);
 22.3217 +                if (q <= p)
 22.3218 +                    q = parseHostname(p, n);
 22.3219 +                p = q;
 22.3220 +            }
 22.3221 +
 22.3222 +            // port
 22.3223 +            if (at(p, n, ':')) {
 22.3224 +                p++;
 22.3225 +                q = scan(p, n, "", "/");
 22.3226 +                if (q > p) {
 22.3227 +                    checkChars(p, q, L_DIGIT, H_DIGIT, "port number");
 22.3228 +                    try {
 22.3229 +                        port = Integer.parseInt(substring(p, q));
 22.3230 +                    } catch (NumberFormatException x) {
 22.3231 +                        fail("Malformed port number", p);
 22.3232 +                    }
 22.3233 +                    p = q;
 22.3234 +                }
 22.3235 +            }
 22.3236 +            if (p < n)
 22.3237 +                failExpecting("port number", p);
 22.3238 +
 22.3239 +            return p;
 22.3240 +        }
 22.3241 +
 22.3242 +        // Scan a string of decimal digits whose value fits in a byte
 22.3243 +        //
 22.3244 +        private int scanByte(int start, int n)
 22.3245 +            throws URISyntaxException
 22.3246 +        {
 22.3247 +            int p = start;
 22.3248 +            int q = scan(p, n, L_DIGIT, H_DIGIT);
 22.3249 +            if (q <= p) return q;
 22.3250 +            if (Integer.parseInt(substring(p, q)) > 255) return p;
 22.3251 +            return q;
 22.3252 +        }
 22.3253 +
 22.3254 +        // Scan an IPv4 address.
 22.3255 +        //
 22.3256 +        // If the strict argument is true then we require that the given
 22.3257 +        // interval contain nothing besides an IPv4 address; if it is false
 22.3258 +        // then we only require that it start with an IPv4 address.
 22.3259 +        //
 22.3260 +        // If the interval does not contain or start with (depending upon the
 22.3261 +        // strict argument) a legal IPv4 address characters then we return -1
 22.3262 +        // immediately; otherwise we insist that these characters parse as a
 22.3263 +        // legal IPv4 address and throw an exception on failure.
 22.3264 +        //
 22.3265 +        // We assume that any string of decimal digits and dots must be an IPv4
 22.3266 +        // address.  It won't parse as a hostname anyway, so making that
 22.3267 +        // assumption here allows more meaningful exceptions to be thrown.
 22.3268 +        //
 22.3269 +        private int scanIPv4Address(int start, int n, boolean strict)
 22.3270 +            throws URISyntaxException
 22.3271 +        {
 22.3272 +            int p = start;
 22.3273 +            int q;
 22.3274 +            int m = scan(p, n, L_DIGIT | L_DOT, H_DIGIT | H_DOT);
 22.3275 +            if ((m <= p) || (strict && (m != n)))
 22.3276 +                return -1;
 22.3277 +            for (;;) {
 22.3278 +                // Per RFC2732: At most three digits per byte
 22.3279 +                // Further constraint: Each element fits in a byte
 22.3280 +                if ((q = scanByte(p, m)) <= p) break;   p = q;
 22.3281 +                if ((q = scan(p, m, '.')) <= p) break;  p = q;
 22.3282 +                if ((q = scanByte(p, m)) <= p) break;   p = q;
 22.3283 +                if ((q = scan(p, m, '.')) <= p) break;  p = q;
 22.3284 +                if ((q = scanByte(p, m)) <= p) break;   p = q;
 22.3285 +                if ((q = scan(p, m, '.')) <= p) break;  p = q;
 22.3286 +                if ((q = scanByte(p, m)) <= p) break;   p = q;
 22.3287 +                if (q < m) break;
 22.3288 +                return q;
 22.3289 +            }
 22.3290 +            fail("Malformed IPv4 address", q);
 22.3291 +            return -1;
 22.3292 +        }
 22.3293 +
 22.3294 +        // Take an IPv4 address: Throw an exception if the given interval
 22.3295 +        // contains anything except an IPv4 address
 22.3296 +        //
 22.3297 +        private int takeIPv4Address(int start, int n, String expected)
 22.3298 +            throws URISyntaxException
 22.3299 +        {
 22.3300 +            int p = scanIPv4Address(start, n, true);
 22.3301 +            if (p <= start)
 22.3302 +                failExpecting(expected, start);
 22.3303 +            return p;
 22.3304 +        }
 22.3305 +
 22.3306 +        // Attempt to parse an IPv4 address, returning -1 on failure but
 22.3307 +        // allowing the given interval to contain [:<characters>] after
 22.3308 +        // the IPv4 address.
 22.3309 +        //
 22.3310 +        private int parseIPv4Address(int start, int n) {
 22.3311 +            int p;
 22.3312 +
 22.3313 +            try {
 22.3314 +                p = scanIPv4Address(start, n, false);
 22.3315 +            } catch (URISyntaxException x) {
 22.3316 +                return -1;
 22.3317 +            } catch (NumberFormatException nfe) {
 22.3318 +                return -1;
 22.3319 +            }
 22.3320 +
 22.3321 +            if (p > start && p < n) {
 22.3322 +                // IPv4 address is followed by something - check that
 22.3323 +                // it's a ":" as this is the only valid character to
 22.3324 +                // follow an address.
 22.3325 +                if (charAt(p) != ':') {
 22.3326 +                    p = -1;
 22.3327 +                }
 22.3328 +            }
 22.3329 +
 22.3330 +            if (p > start)
 22.3331 +                host = substring(start, p);
 22.3332 +
 22.3333 +            return p;
 22.3334 +        }
 22.3335 +
 22.3336 +        // hostname      = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
 22.3337 +        // domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
 22.3338 +        // toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
 22.3339 +        //
 22.3340 +        private int parseHostname(int start, int n)
 22.3341 +            throws URISyntaxException
 22.3342 +        {
 22.3343 +            int p = start;
 22.3344 +            int q;
 22.3345 +            int l = -1;                 // Start of last parsed label
 22.3346 +
 22.3347 +            do {
 22.3348 +                // domainlabel = alphanum [ *( alphanum | "-" ) alphanum ]
 22.3349 +                q = scan(p, n, L_ALPHANUM, H_ALPHANUM);
 22.3350 +                if (q <= p)
 22.3351 +                    break;
 22.3352 +                l = p;
 22.3353 +                if (q > p) {
 22.3354 +                    p = q;
 22.3355 +                    q = scan(p, n, L_ALPHANUM | L_DASH, H_ALPHANUM | H_DASH);
 22.3356 +                    if (q > p) {
 22.3357 +                        if (charAt(q - 1) == '-')
 22.3358 +                            fail("Illegal character in hostname", q - 1);
 22.3359 +                        p = q;
 22.3360 +                    }
 22.3361 +                }
 22.3362 +                q = scan(p, n, '.');
 22.3363 +                if (q <= p)
 22.3364 +                    break;
 22.3365 +                p = q;
 22.3366 +            } while (p < n);
 22.3367 +
 22.3368 +            if ((p < n) && !at(p, n, ':'))
 22.3369 +                fail("Illegal character in hostname", p);
 22.3370 +
 22.3371 +            if (l < 0)
 22.3372 +                failExpecting("hostname", start);
 22.3373 +
 22.3374 +            // for a fully qualified hostname check that the rightmost
 22.3375 +            // label starts with an alpha character.
 22.3376 +            if (l > start && !match(charAt(l), L_ALPHA, H_ALPHA)) {
 22.3377 +                fail("Illegal character in hostname", l);
 22.3378 +            }
 22.3379 +
 22.3380 +            host = substring(start, p);
 22.3381 +            return p;
 22.3382 +        }
 22.3383 +
 22.3384 +
 22.3385 +        // IPv6 address parsing, from RFC2373: IPv6 Addressing Architecture
 22.3386 +        //
 22.3387 +        // Bug: The grammar in RFC2373 Appendix B does not allow addresses of
 22.3388 +        // the form ::12.34.56.78, which are clearly shown in the examples
 22.3389 +        // earlier in the document.  Here is the original grammar:
 22.3390 +        //
 22.3391 +        //   IPv6address = hexpart [ ":" IPv4address ]
 22.3392 +        //   hexpart     = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
 22.3393 +        //   hexseq      = hex4 *( ":" hex4)
 22.3394 +        //   hex4        = 1*4HEXDIG
 22.3395 +        //
 22.3396 +        // We therefore use the following revised grammar:
 22.3397 +        //
 22.3398 +        //   IPv6address = hexseq [ ":" IPv4address ]
 22.3399 +        //                 | hexseq [ "::" [ hexpost ] ]
 22.3400 +        //                 | "::" [ hexpost ]
 22.3401 +        //   hexpost     = hexseq | hexseq ":" IPv4address | IPv4address
 22.3402 +        //   hexseq      = hex4 *( ":" hex4)
 22.3403 +        //   hex4        = 1*4HEXDIG
 22.3404 +        //
 22.3405 +        // This covers all and only the following cases:
 22.3406 +        //
 22.3407 +        //   hexseq
 22.3408 +        //   hexseq : IPv4address
 22.3409 +        //   hexseq ::
 22.3410 +        //   hexseq :: hexseq
 22.3411 +        //   hexseq :: hexseq : IPv4address
 22.3412 +        //   hexseq :: IPv4address
 22.3413 +        //   :: hexseq
 22.3414 +        //   :: hexseq : IPv4address
 22.3415 +        //   :: IPv4address
 22.3416 +        //   ::
 22.3417 +        //
 22.3418 +        // Additionally we constrain the IPv6 address as follows :-
 22.3419 +        //
 22.3420 +        //  i.  IPv6 addresses without compressed zeros should contain
 22.3421 +        //      exactly 16 bytes.
 22.3422 +        //
 22.3423 +        //  ii. IPv6 addresses with compressed zeros should contain
 22.3424 +        //      less than 16 bytes.
 22.3425 +
 22.3426 +        private int ipv6byteCount = 0;
 22.3427 +
 22.3428 +        private int parseIPv6Reference(int start, int n)
 22.3429 +            throws URISyntaxException
 22.3430 +        {
 22.3431 +            int p = start;
 22.3432 +            int q;
 22.3433 +            boolean compressedZeros = false;
 22.3434 +
 22.3435 +            q = scanHexSeq(p, n);
 22.3436 +
 22.3437 +            if (q > p) {
 22.3438 +                p = q;
 22.3439 +                if (at(p, n, "::")) {
 22.3440 +                    compressedZeros = true;
 22.3441 +                    p = scanHexPost(p + 2, n);
 22.3442 +                } else if (at(p, n, ':')) {
 22.3443 +                    p = takeIPv4Address(p + 1,  n, "IPv4 address");
 22.3444 +                    ipv6byteCount += 4;
 22.3445 +                }
 22.3446 +            } else if (at(p, n, "::")) {
 22.3447 +                compressedZeros = true;
 22.3448 +                p = scanHexPost(p + 2, n);
 22.3449 +            }
 22.3450 +            if (p < n)
 22.3451 +                fail("Malformed IPv6 address", start);
 22.3452 +            if (ipv6byteCount > 16)
 22.3453 +                fail("IPv6 address too long", start);
 22.3454 +            if (!compressedZeros && ipv6byteCount < 16)
 22.3455 +                fail("IPv6 address too short", start);
 22.3456 +            if (compressedZeros && ipv6byteCount == 16)
 22.3457 +                fail("Malformed IPv6 address", start);
 22.3458 +
 22.3459 +            return p;
 22.3460 +        }
 22.3461 +
 22.3462 +        private int scanHexPost(int start, int n)
 22.3463 +            throws URISyntaxException
 22.3464 +        {
 22.3465 +            int p = start;
 22.3466 +            int q;
 22.3467 +
 22.3468 +            if (p == n)
 22.3469 +                return p;
 22.3470 +
 22.3471 +            q = scanHexSeq(p, n);
 22.3472 +            if (q > p) {
 22.3473 +                p = q;
 22.3474 +                if (at(p, n, ':')) {
 22.3475 +                    p++;
 22.3476 +                    p = takeIPv4Address(p, n, "hex digits or IPv4 address");
 22.3477 +                    ipv6byteCount += 4;
 22.3478 +                }
 22.3479 +            } else {
 22.3480 +                p = takeIPv4Address(p, n, "hex digits or IPv4 address");
 22.3481 +                ipv6byteCount += 4;
 22.3482 +            }
 22.3483 +            return p;
 22.3484 +        }
 22.3485 +
 22.3486 +        // Scan a hex sequence; return -1 if one could not be scanned
 22.3487 +        //
 22.3488 +        private int scanHexSeq(int start, int n)
 22.3489 +            throws URISyntaxException
 22.3490 +        {
 22.3491 +            int p = start;
 22.3492 +            int q;
 22.3493 +
 22.3494 +            q = scan(p, n, L_HEX, H_HEX);
 22.3495 +            if (q <= p)
 22.3496 +                return -1;
 22.3497 +            if (at(q, n, '.'))          // Beginning of IPv4 address
 22.3498 +                return -1;
 22.3499 +            if (q > p + 4)
 22.3500 +                fail("IPv6 hexadecimal digit sequence too long", p);
 22.3501 +            ipv6byteCount += 2;
 22.3502 +            p = q;
 22.3503 +            while (p < n) {
 22.3504 +                if (!at(p, n, ':'))
 22.3505 +                    break;
 22.3506 +                if (at(p + 1, n, ':'))
 22.3507 +                    break;              // "::"
 22.3508 +                p++;
 22.3509 +                q = scan(p, n, L_HEX, H_HEX);
 22.3510 +                if (q <= p)
 22.3511 +                    failExpecting("digits for an IPv6 address", p);
 22.3512 +                if (at(q, n, '.')) {    // Beginning of IPv4 address
 22.3513 +                    p--;
 22.3514 +                    break;
 22.3515 +                }
 22.3516 +                if (q > p + 4)
 22.3517 +                    fail("IPv6 hexadecimal digit sequence too long", p);
 22.3518 +                ipv6byteCount += 2;
 22.3519 +                p = q;
 22.3520 +            }
 22.3521 +
 22.3522 +            return p;
 22.3523 +        }
 22.3524 +
 22.3525 +    }
 22.3526 +
 22.3527 +}
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/rt/emul/compact/src/main/java/java/net/URISyntaxException.java	Sat Sep 07 13:55:09 2013 +0200
    23.3 @@ -0,0 +1,135 @@
    23.4 +/*
    23.5 + * Copyright (c) 2000, 2008, 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.net;
   23.30 +
   23.31 +
   23.32 +/**
   23.33 + * Checked exception thrown to indicate that a string could not be parsed as a
   23.34 + * URI reference.
   23.35 + *
   23.36 + * @author Mark Reinhold
   23.37 + * @see URI
   23.38 + * @since 1.4
   23.39 + */
   23.40 +
   23.41 +public class URISyntaxException
   23.42 +    extends Exception
   23.43 +{
   23.44 +    private static final long serialVersionUID = 2137979680897488891L;
   23.45 +
   23.46 +    private String input;
   23.47 +    private int index;
   23.48 +
   23.49 +    /**
   23.50 +     * Constructs an instance from the given input string, reason, and error
   23.51 +     * index.
   23.52 +     *
   23.53 +     * @param  input   The input string
   23.54 +     * @param  reason  A string explaining why the input could not be parsed
   23.55 +     * @param  index   The index at which the parse error occurred,
   23.56 +     *                 or <tt>-1</tt> if the index is not known
   23.57 +     *
   23.58 +     * @throws  NullPointerException
   23.59 +     *          If either the input or reason strings are <tt>null</tt>
   23.60 +     *
   23.61 +     * @throws  IllegalArgumentException
   23.62 +     *          If the error index is less than <tt>-1</tt>
   23.63 +     */
   23.64 +    public URISyntaxException(String input, String reason, int index) {
   23.65 +        super(reason);
   23.66 +        if ((input == null) || (reason == null))
   23.67 +            throw new NullPointerException();
   23.68 +        if (index < -1)
   23.69 +            throw new IllegalArgumentException();
   23.70 +        this.input = input;
   23.71 +        this.index = index;
   23.72 +    }
   23.73 +
   23.74 +    /**
   23.75 +     * Constructs an instance from the given input string and reason.  The
   23.76 +     * resulting object will have an error index of <tt>-1</tt>.
   23.77 +     *
   23.78 +     * @param  input   The input string
   23.79 +     * @param  reason  A string explaining why the input could not be parsed
   23.80 +     *
   23.81 +     * @throws  NullPointerException
   23.82 +     *          If either the input or reason strings are <tt>null</tt>
   23.83 +     */
   23.84 +    public URISyntaxException(String input, String reason) {
   23.85 +        this(input, reason, -1);
   23.86 +    }
   23.87 +
   23.88 +    /**
   23.89 +     * Returns the input string.
   23.90 +     *
   23.91 +     * @return  The input string
   23.92 +     */
   23.93 +    public String getInput() {
   23.94 +        return input;
   23.95 +    }
   23.96 +
   23.97 +    /**
   23.98 +     * Returns a string explaining why the input string could not be parsed.
   23.99 +     *
  23.100 +     * @return  The reason string
  23.101 +     */
  23.102 +    public String getReason() {
  23.103 +        return super.getMessage();
  23.104 +    }
  23.105 +
  23.106 +    /**
  23.107 +     * Returns an index into the input string of the position at which the
  23.108 +     * parse error occurred, or <tt>-1</tt> if this position is not known.
  23.109 +     *
  23.110 +     * @return  The error index
  23.111 +     */
  23.112 +    public int getIndex() {
  23.113 +        return index;
  23.114 +    }
  23.115 +
  23.116 +    /**
  23.117 +     * Returns a string describing the parse error.  The resulting string
  23.118 +     * consists of the reason string followed by a colon character
  23.119 +     * (<tt>':'</tt>), a space, and the input string.  If the error index is
  23.120 +     * defined then the string <tt>" at index "</tt> followed by the index, in
  23.121 +     * decimal, is inserted after the reason string and before the colon
  23.122 +     * character.
  23.123 +     *
  23.124 +     * @return  A string describing the parse error
  23.125 +     */
  23.126 +    public String getMessage() {
  23.127 +        StringBuffer sb = new StringBuffer();
  23.128 +        sb.append(getReason());
  23.129 +        if (index > -1) {
  23.130 +            sb.append(" at index ");
  23.131 +            sb.append(index);
  23.132 +        }
  23.133 +        sb.append(": ");
  23.134 +        sb.append(input);
  23.135 +        return sb.toString();
  23.136 +    }
  23.137 +
  23.138 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/rt/emul/compact/src/main/java/java/util/IdentityHashMap.java	Sat Sep 07 13:55:09 2013 +0200
    24.3 @@ -0,0 +1,1243 @@
    24.4 +/*
    24.5 + * Copyright (c) 2000, 2011, 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.util;
   24.30 +import java.io.*;
   24.31 +
   24.32 +/**
   24.33 + * This class implements the <tt>Map</tt> interface with a hash table, using
   24.34 + * reference-equality in place of object-equality when comparing keys (and
   24.35 + * values).  In other words, in an <tt>IdentityHashMap</tt>, two keys
   24.36 + * <tt>k1</tt> and <tt>k2</tt> are considered equal if and only if
   24.37 + * <tt>(k1==k2)</tt>.  (In normal <tt>Map</tt> implementations (like
   24.38 + * <tt>HashMap</tt>) two keys <tt>k1</tt> and <tt>k2</tt> are considered equal
   24.39 + * if and only if <tt>(k1==null ? k2==null : k1.equals(k2))</tt>.)
   24.40 + *
   24.41 + * <p><b>This class is <i>not</i> a general-purpose <tt>Map</tt>
   24.42 + * implementation!  While this class implements the <tt>Map</tt> interface, it
   24.43 + * intentionally violates <tt>Map's</tt> general contract, which mandates the
   24.44 + * use of the <tt>equals</tt> method when comparing objects.  This class is
   24.45 + * designed for use only in the rare cases wherein reference-equality
   24.46 + * semantics are required.</b>
   24.47 + *
   24.48 + * <p>A typical use of this class is <i>topology-preserving object graph
   24.49 + * transformations</i>, such as serialization or deep-copying.  To perform such
   24.50 + * a transformation, a program must maintain a "node table" that keeps track
   24.51 + * of all the object references that have already been processed.  The node
   24.52 + * table must not equate distinct objects even if they happen to be equal.
   24.53 + * Another typical use of this class is to maintain <i>proxy objects</i>.  For
   24.54 + * example, a debugging facility might wish to maintain a proxy object for
   24.55 + * each object in the program being debugged.
   24.56 + *
   24.57 + * <p>This class provides all of the optional map operations, and permits
   24.58 + * <tt>null</tt> values and the <tt>null</tt> key.  This class makes no
   24.59 + * guarantees as to the order of the map; in particular, it does not guarantee
   24.60 + * that the order will remain constant over time.
   24.61 + *
   24.62 + * <p>This class provides constant-time performance for the basic
   24.63 + * operations (<tt>get</tt> and <tt>put</tt>), assuming the system
   24.64 + * identity hash function ({@link System#identityHashCode(Object)})
   24.65 + * disperses elements properly among the buckets.
   24.66 + *
   24.67 + * <p>This class has one tuning parameter (which affects performance but not
   24.68 + * semantics): <i>expected maximum size</i>.  This parameter is the maximum
   24.69 + * number of key-value mappings that the map is expected to hold.  Internally,
   24.70 + * this parameter is used to determine the number of buckets initially
   24.71 + * comprising the hash table.  The precise relationship between the expected
   24.72 + * maximum size and the number of buckets is unspecified.
   24.73 + *
   24.74 + * <p>If the size of the map (the number of key-value mappings) sufficiently
   24.75 + * exceeds the expected maximum size, the number of buckets is increased
   24.76 + * Increasing the number of buckets ("rehashing") may be fairly expensive, so
   24.77 + * it pays to create identity hash maps with a sufficiently large expected
   24.78 + * maximum size.  On the other hand, iteration over collection views requires
   24.79 + * time proportional to the number of buckets in the hash table, so it
   24.80 + * pays not to set the expected maximum size too high if you are especially
   24.81 + * concerned with iteration performance or memory usage.
   24.82 + *
   24.83 + * <p><strong>Note that this implementation is not synchronized.</strong>
   24.84 + * If multiple threads access an identity hash map concurrently, and at
   24.85 + * least one of the threads modifies the map structurally, it <i>must</i>
   24.86 + * be synchronized externally.  (A structural modification is any operation
   24.87 + * that adds or deletes one or more mappings; merely changing the value
   24.88 + * associated with a key that an instance already contains is not a
   24.89 + * structural modification.)  This is typically accomplished by
   24.90 + * synchronizing on some object that naturally encapsulates the map.
   24.91 + *
   24.92 + * If no such object exists, the map should be "wrapped" using the
   24.93 + * {@link Collections#synchronizedMap Collections.synchronizedMap}
   24.94 + * method.  This is best done at creation time, to prevent accidental
   24.95 + * unsynchronized access to the map:<pre>
   24.96 + *   Map m = Collections.synchronizedMap(new IdentityHashMap(...));</pre>
   24.97 + *
   24.98 + * <p>The iterators returned by the <tt>iterator</tt> method of the
   24.99 + * collections returned by all of this class's "collection view
  24.100 + * methods" are <i>fail-fast</i>: if the map is structurally modified
  24.101 + * at any time after the iterator is created, in any way except
  24.102 + * through the iterator's own <tt>remove</tt> method, the iterator
  24.103 + * will throw a {@link ConcurrentModificationException}.  Thus, in the
  24.104 + * face of concurrent modification, the iterator fails quickly and
  24.105 + * cleanly, rather than risking arbitrary, non-deterministic behavior
  24.106 + * at an undetermined time in the future.
  24.107 + *
  24.108 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  24.109 + * as it is, generally speaking, impossible to make any hard guarantees in the
  24.110 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
  24.111 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  24.112 + * Therefore, it would be wrong to write a program that depended on this
  24.113 + * exception for its correctness: <i>fail-fast iterators should be used only
  24.114 + * to detect bugs.</i>
  24.115 + *
  24.116 + * <p>Implementation note: This is a simple <i>linear-probe</i> hash table,
  24.117 + * as described for example in texts by Sedgewick and Knuth.  The array
  24.118 + * alternates holding keys and values.  (This has better locality for large
  24.119 + * tables than does using separate arrays.)  For many JRE implementations
  24.120 + * and operation mixes, this class will yield better performance than
  24.121 + * {@link HashMap} (which uses <i>chaining</i> rather than linear-probing).
  24.122 + *
  24.123 + * <p>This class is a member of the
  24.124 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  24.125 + * Java Collections Framework</a>.
  24.126 + *
  24.127 + * @see     System#identityHashCode(Object)
  24.128 + * @see     Object#hashCode()
  24.129 + * @see     Collection
  24.130 + * @see     Map
  24.131 + * @see     HashMap
  24.132 + * @see     TreeMap
  24.133 + * @author  Doug Lea and Josh Bloch
  24.134 + * @since   1.4
  24.135 + */
  24.136 +
  24.137 +public class IdentityHashMap<K,V>
  24.138 +    extends AbstractMap<K,V>
  24.139 +    implements Map<K,V>, java.io.Serializable, Cloneable
  24.140 +{
  24.141 +    /**
  24.142 +     * The initial capacity used by the no-args constructor.
  24.143 +     * MUST be a power of two.  The value 32 corresponds to the
  24.144 +     * (specified) expected maximum size of 21, given a load factor
  24.145 +     * of 2/3.
  24.146 +     */
  24.147 +    private static final int DEFAULT_CAPACITY = 32;
  24.148 +
  24.149 +    /**
  24.150 +     * The minimum capacity, used if a lower value is implicitly specified
  24.151 +     * by either of the constructors with arguments.  The value 4 corresponds
  24.152 +     * to an expected maximum size of 2, given a load factor of 2/3.
  24.153 +     * MUST be a power of two.
  24.154 +     */
  24.155 +    private static final int MINIMUM_CAPACITY = 4;
  24.156 +
  24.157 +    /**
  24.158 +     * The maximum capacity, used if a higher value is implicitly specified
  24.159 +     * by either of the constructors with arguments.
  24.160 +     * MUST be a power of two <= 1<<29.
  24.161 +     */
  24.162 +    private static final int MAXIMUM_CAPACITY = 1 << 29;
  24.163 +
  24.164 +    /**
  24.165 +     * The table, resized as necessary. Length MUST always be a power of two.
  24.166 +     */
  24.167 +    private transient Object[] table;
  24.168 +
  24.169 +    /**
  24.170 +     * The number of key-value mappings contained in this identity hash map.
  24.171 +     *
  24.172 +     * @serial
  24.173 +     */
  24.174 +    private int size;
  24.175 +
  24.176 +    /**
  24.177 +     * The number of modifications, to support fast-fail iterators
  24.178 +     */
  24.179 +    private transient int modCount;
  24.180 +
  24.181 +    /**
  24.182 +     * The next size value at which to resize (capacity * load factor).
  24.183 +     */
  24.184 +    private transient int threshold;
  24.185 +
  24.186 +    /**
  24.187 +     * Value representing null keys inside tables.
  24.188 +     */
  24.189 +    private static final Object NULL_KEY = new Object();
  24.190 +
  24.191 +    /**
  24.192 +     * Use NULL_KEY for key if it is null.
  24.193 +     */
  24.194 +    private static Object maskNull(Object key) {
  24.195 +        return (key == null ? NULL_KEY : key);
  24.196 +    }
  24.197 +
  24.198 +    /**
  24.199 +     * Returns internal representation of null key back to caller as null.
  24.200 +     */
  24.201 +    private static Object unmaskNull(Object key) {
  24.202 +        return (key == NULL_KEY ? null : key);
  24.203 +    }
  24.204 +
  24.205 +    /**
  24.206 +     * Constructs a new, empty identity hash map with a default expected
  24.207 +     * maximum size (21).
  24.208 +     */
  24.209 +    public IdentityHashMap() {
  24.210 +        init(DEFAULT_CAPACITY);
  24.211 +    }
  24.212 +
  24.213 +    /**
  24.214 +     * Constructs a new, empty map with the specified expected maximum size.
  24.215 +     * Putting more than the expected number of key-value mappings into
  24.216 +     * the map may cause the internal data structure to grow, which may be
  24.217 +     * somewhat time-consuming.
  24.218 +     *
  24.219 +     * @param expectedMaxSize the expected maximum size of the map
  24.220 +     * @throws IllegalArgumentException if <tt>expectedMaxSize</tt> is negative
  24.221 +     */
  24.222 +    public IdentityHashMap(int expectedMaxSize) {
  24.223 +        if (expectedMaxSize < 0)
  24.224 +            throw new IllegalArgumentException("expectedMaxSize is negative: "
  24.225 +                                               + expectedMaxSize);
  24.226 +        init(capacity(expectedMaxSize));
  24.227 +    }
  24.228 +
  24.229 +    /**
  24.230 +     * Returns the appropriate capacity for the specified expected maximum
  24.231 +     * size.  Returns the smallest power of two between MINIMUM_CAPACITY
  24.232 +     * and MAXIMUM_CAPACITY, inclusive, that is greater than
  24.233 +     * (3 * expectedMaxSize)/2, if such a number exists.  Otherwise
  24.234 +     * returns MAXIMUM_CAPACITY.  If (3 * expectedMaxSize)/2 is negative, it
  24.235 +     * is assumed that overflow has occurred, and MAXIMUM_CAPACITY is returned.
  24.236 +     */
  24.237 +    private int capacity(int expectedMaxSize) {
  24.238 +        // Compute min capacity for expectedMaxSize given a load factor of 2/3
  24.239 +        int minCapacity = (3 * expectedMaxSize)/2;
  24.240 +
  24.241 +        // Compute the appropriate capacity
  24.242 +        int result;
  24.243 +        if (minCapacity > MAXIMUM_CAPACITY || minCapacity < 0) {
  24.244 +            result = MAXIMUM_CAPACITY;
  24.245 +        } else {
  24.246 +            result = MINIMUM_CAPACITY;
  24.247 +            while (result < minCapacity)
  24.248 +                result <<= 1;
  24.249 +        }
  24.250 +        return result;
  24.251 +    }
  24.252 +
  24.253 +    /**
  24.254 +     * Initializes object to be an empty map with the specified initial
  24.255 +     * capacity, which is assumed to be a power of two between
  24.256 +     * MINIMUM_CAPACITY and MAXIMUM_CAPACITY inclusive.
  24.257 +     */
  24.258 +    private void init(int initCapacity) {
  24.259 +        // assert (initCapacity & -initCapacity) == initCapacity; // power of 2
  24.260 +        // assert initCapacity >= MINIMUM_CAPACITY;
  24.261 +        // assert initCapacity <= MAXIMUM_CAPACITY;
  24.262 +
  24.263 +        threshold = (initCapacity * 2)/3;
  24.264 +        table = new Object[2 * initCapacity];
  24.265 +    }
  24.266 +
  24.267 +    /**
  24.268 +     * Constructs a new identity hash map containing the keys-value mappings
  24.269 +     * in the specified map.
  24.270 +     *
  24.271 +     * @param m the map whose mappings are to be placed into this map
  24.272 +     * @throws NullPointerException if the specified map is null
  24.273 +     */
  24.274 +    public IdentityHashMap(Map<? extends K, ? extends V> m) {
  24.275 +        // Allow for a bit of growth
  24.276 +        this((int) ((1 + m.size()) * 1.1));
  24.277 +        putAll(m);
  24.278 +    }
  24.279 +
  24.280 +    /**
  24.281 +     * Returns the number of key-value mappings in this identity hash map.
  24.282 +     *
  24.283 +     * @return the number of key-value mappings in this map
  24.284 +     */
  24.285 +    public int size() {
  24.286 +        return size;
  24.287 +    }
  24.288 +
  24.289 +    /**
  24.290 +     * Returns <tt>true</tt> if this identity hash map contains no key-value
  24.291 +     * mappings.
  24.292 +     *
  24.293 +     * @return <tt>true</tt> if this identity hash map contains no key-value
  24.294 +     *         mappings
  24.295 +     */
  24.296 +    public boolean isEmpty() {
  24.297 +        return size == 0;
  24.298 +    }
  24.299 +
  24.300 +    /**
  24.301 +     * Returns index for Object x.
  24.302 +     */
  24.303 +    private static int hash(Object x, int length) {
  24.304 +        int h = System.identityHashCode(x);
  24.305 +        // Multiply by -127, and left-shift to use least bit as part of hash
  24.306 +        return ((h << 1) - (h << 8)) & (length - 1);
  24.307 +    }
  24.308 +
  24.309 +    /**
  24.310 +     * Circularly traverses table of size len.
  24.311 +     */
  24.312 +    private static int nextKeyIndex(int i, int len) {
  24.313 +        return (i + 2 < len ? i + 2 : 0);
  24.314 +    }
  24.315 +
  24.316 +    /**
  24.317 +     * Returns the value to which the specified key is mapped,
  24.318 +     * or {@code null} if this map contains no mapping for the key.
  24.319 +     *
  24.320 +     * <p>More formally, if this map contains a mapping from a key
  24.321 +     * {@code k} to a value {@code v} such that {@code (key == k)},
  24.322 +     * then this method returns {@code v}; otherwise it returns
  24.323 +     * {@code null}.  (There can be at most one such mapping.)
  24.324 +     *
  24.325 +     * <p>A return value of {@code null} does not <i>necessarily</i>
  24.326 +     * indicate that the map contains no mapping for the key; it's also
  24.327 +     * possible that the map explicitly maps the key to {@code null}.
  24.328 +     * The {@link #containsKey containsKey} operation may be used to
  24.329 +     * distinguish these two cases.
  24.330 +     *
  24.331 +     * @see #put(Object, Object)
  24.332 +     */
  24.333 +    public V get(Object key) {
  24.334 +        Object k = maskNull(key);
  24.335 +        Object[] tab = table;
  24.336 +        int len = tab.length;
  24.337 +        int i = hash(k, len);
  24.338 +        while (true) {
  24.339 +            Object item = tab[i];
  24.340 +            if (item == k)
  24.341 +                return (V) tab[i + 1];
  24.342 +            if (item == null)
  24.343 +                return null;
  24.344 +            i = nextKeyIndex(i, len);
  24.345 +        }
  24.346 +    }
  24.347 +
  24.348 +    /**
  24.349 +     * Tests whether the specified object reference is a key in this identity
  24.350 +     * hash map.
  24.351 +     *
  24.352 +     * @param   key   possible key
  24.353 +     * @return  <code>true</code> if the specified object reference is a key
  24.354 +     *          in this map
  24.355 +     * @see     #containsValue(Object)
  24.356 +     */
  24.357 +    public boolean containsKey(Object key) {
  24.358 +        Object k = maskNull(key);
  24.359 +        Object[] tab = table;
  24.360 +        int len = tab.length;
  24.361 +        int i = hash(k, len);
  24.362 +        while (true) {
  24.363 +            Object item = tab[i];
  24.364 +            if (item == k)
  24.365 +                return true;
  24.366 +            if (item == null)
  24.367 +                return false;
  24.368 +            i = nextKeyIndex(i, len);
  24.369 +        }
  24.370 +    }
  24.371 +
  24.372 +    /**
  24.373 +     * Tests whether the specified object reference is a value in this identity
  24.374 +     * hash map.
  24.375 +     *
  24.376 +     * @param value value whose presence in this map is to be tested
  24.377 +     * @return <tt>true</tt> if this map maps one or more keys to the
  24.378 +     *         specified object reference
  24.379 +     * @see     #containsKey(Object)
  24.380 +     */
  24.381 +    public boolean containsValue(Object value) {
  24.382 +        Object[] tab = table;
  24.383 +        for (int i = 1; i < tab.length; i += 2)
  24.384 +            if (tab[i] == value && tab[i - 1] != null)
  24.385 +                return true;
  24.386 +
  24.387 +        return false;
  24.388 +    }
  24.389 +
  24.390 +    /**
  24.391 +     * Tests if the specified key-value mapping is in the map.
  24.392 +     *
  24.393 +     * @param   key   possible key
  24.394 +     * @param   value possible value
  24.395 +     * @return  <code>true</code> if and only if the specified key-value
  24.396 +     *          mapping is in the map
  24.397 +     */
  24.398 +    private boolean containsMapping(Object key, Object value) {
  24.399 +        Object k = maskNull(key);
  24.400 +        Object[] tab = table;
  24.401 +        int len = tab.length;
  24.402 +        int i = hash(k, len);
  24.403 +        while (true) {
  24.404 +            Object item = tab[i];
  24.405 +            if (item == k)
  24.406 +                return tab[i + 1] == value;
  24.407 +            if (item == null)
  24.408 +                return false;
  24.409 +            i = nextKeyIndex(i, len);
  24.410 +        }
  24.411 +    }
  24.412 +
  24.413 +    /**
  24.414 +     * Associates the specified value with the specified key in this identity
  24.415 +     * hash map.  If the map previously contained a mapping for the key, the
  24.416 +     * old value is replaced.
  24.417 +     *
  24.418 +     * @param key the key with which the specified value is to be associated
  24.419 +     * @param value the value to be associated with the specified key
  24.420 +     * @return the previous value associated with <tt>key</tt>, or
  24.421 +     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
  24.422 +     *         (A <tt>null</tt> return can also indicate that the map
  24.423 +     *         previously associated <tt>null</tt> with <tt>key</tt>.)
  24.424 +     * @see     Object#equals(Object)
  24.425 +     * @see     #get(Object)
  24.426 +     * @see     #containsKey(Object)
  24.427 +     */
  24.428 +    public V put(K key, V value) {
  24.429 +        Object k = maskNull(key);
  24.430 +        Object[] tab = table;
  24.431 +        int len = tab.length;
  24.432 +        int i = hash(k, len);
  24.433 +
  24.434 +        Object item;
  24.435 +        while ( (item = tab[i]) != null) {
  24.436 +            if (item == k) {
  24.437 +                V oldValue = (V) tab[i + 1];
  24.438 +                tab[i + 1] = value;
  24.439 +                return oldValue;
  24.440 +            }
  24.441 +            i = nextKeyIndex(i, len);
  24.442 +        }
  24.443 +
  24.444 +        modCount++;
  24.445 +        tab[i] = k;
  24.446 +        tab[i + 1] = value;
  24.447 +        if (++size >= threshold)
  24.448 +            resize(len); // len == 2 * current capacity.
  24.449 +        return null;
  24.450 +    }
  24.451 +
  24.452 +    /**
  24.453 +     * Resize the table to hold given capacity.
  24.454 +     *
  24.455 +     * @param newCapacity the new capacity, must be a power of two.
  24.456 +     */
  24.457 +    private void resize(int newCapacity) {
  24.458 +        // assert (newCapacity & -newCapacity) == newCapacity; // power of 2
  24.459 +        int newLength = newCapacity * 2;
  24.460 +
  24.461 +        Object[] oldTable = table;
  24.462 +        int oldLength = oldTable.length;
  24.463 +        if (oldLength == 2*MAXIMUM_CAPACITY) { // can't expand any further
  24.464 +            if (threshold == MAXIMUM_CAPACITY-1)
  24.465 +                throw new IllegalStateException("Capacity exhausted.");
  24.466 +            threshold = MAXIMUM_CAPACITY-1;  // Gigantic map!
  24.467 +            return;
  24.468 +        }
  24.469 +        if (oldLength >= newLength)
  24.470 +            return;
  24.471 +
  24.472 +        Object[] newTable = new Object[newLength];
  24.473 +        threshold = newLength / 3;
  24.474 +
  24.475 +        for (int j = 0; j < oldLength; j += 2) {
  24.476 +            Object key = oldTable[j];
  24.477 +            if (key != null) {
  24.478 +                Object value = oldTable[j+1];
  24.479 +                oldTable[j] = null;
  24.480 +                oldTable[j+1] = null;
  24.481 +                int i = hash(key, newLength);
  24.482 +                while (newTable[i] != null)
  24.483 +                    i = nextKeyIndex(i, newLength);
  24.484 +                newTable[i] = key;
  24.485 +                newTable[i + 1] = value;
  24.486 +            }
  24.487 +        }
  24.488 +        table = newTable;
  24.489 +    }
  24.490 +
  24.491 +    /**
  24.492 +     * Copies all of the mappings from the specified map to this map.
  24.493 +     * These mappings will replace any mappings that this map had for
  24.494 +     * any of the keys currently in the specified map.
  24.495 +     *
  24.496 +     * @param m mappings to be stored in this map
  24.497 +     * @throws NullPointerException if the specified map is null
  24.498 +     */
  24.499 +    public void putAll(Map<? extends K, ? extends V> m) {
  24.500 +        int n = m.size();
  24.501 +        if (n == 0)
  24.502 +            return;
  24.503 +        if (n > threshold) // conservatively pre-expand
  24.504 +            resize(capacity(n));
  24.505 +
  24.506 +        for (Entry<? extends K, ? extends V> e : m.entrySet())
  24.507 +            put(e.getKey(), e.getValue());
  24.508 +    }
  24.509 +
  24.510 +    /**
  24.511 +     * Removes the mapping for this key from this map if present.
  24.512 +     *
  24.513 +     * @param key key whose mapping is to be removed from the map
  24.514 +     * @return the previous value associated with <tt>key</tt>, or
  24.515 +     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
  24.516 +     *         (A <tt>null</tt> return can also indicate that the map
  24.517 +     *         previously associated <tt>null</tt> with <tt>key</tt>.)
  24.518 +     */
  24.519 +    public V remove(Object key) {
  24.520 +        Object k = maskNull(key);
  24.521 +        Object[] tab = table;
  24.522 +        int len = tab.length;
  24.523 +        int i = hash(k, len);
  24.524 +
  24.525 +        while (true) {
  24.526 +            Object item = tab[i];
  24.527 +            if (item == k) {
  24.528 +                modCount++;
  24.529 +                size--;
  24.530 +                V oldValue = (V) tab[i + 1];
  24.531 +                tab[i + 1] = null;
  24.532 +                tab[i] = null;
  24.533 +                closeDeletion(i);
  24.534 +                return oldValue;
  24.535 +            }
  24.536 +            if (item == null)
  24.537 +                return null;
  24.538 +            i = nextKeyIndex(i, len);
  24.539 +        }
  24.540 +
  24.541 +    }
  24.542 +
  24.543 +    /**
  24.544 +     * Removes the specified key-value mapping from the map if it is present.
  24.545 +     *
  24.546 +     * @param   key   possible key
  24.547 +     * @param   value possible value
  24.548 +     * @return  <code>true</code> if and only if the specified key-value
  24.549 +     *          mapping was in the map
  24.550 +     */
  24.551 +    private boolean removeMapping(Object key, Object value) {
  24.552 +        Object k = maskNull(key);
  24.553 +        Object[] tab = table;
  24.554 +        int len = tab.length;
  24.555 +        int i = hash(k, len);
  24.556 +
  24.557 +        while (true) {
  24.558 +            Object item = tab[i];
  24.559 +            if (item == k) {
  24.560 +                if (tab[i + 1] != value)
  24.561 +                    return false;
  24.562 +                modCount++;
  24.563 +                size--;
  24.564 +                tab[i] = null;
  24.565 +                tab[i + 1] = null;
  24.566 +                closeDeletion(i);
  24.567 +                return true;
  24.568 +            }
  24.569 +            if (item == null)
  24.570 +                return false;
  24.571 +            i = nextKeyIndex(i, len);
  24.572 +        }
  24.573 +    }
  24.574 +
  24.575 +    /**
  24.576 +     * Rehash all possibly-colliding entries following a
  24.577 +     * deletion. This preserves the linear-probe
  24.578 +     * collision properties required by get, put, etc.
  24.579 +     *
  24.580 +     * @param d the index of a newly empty deleted slot
  24.581 +     */
  24.582 +    private void closeDeletion(int d) {
  24.583 +        // Adapted from Knuth Section 6.4 Algorithm R
  24.584 +        Object[] tab = table;
  24.585 +        int len = tab.length;
  24.586 +
  24.587 +        // Look for items to swap into newly vacated slot
  24.588 +        // starting at index immediately following deletion,
  24.589 +        // and continuing until a null slot is seen, indicating
  24.590 +        // the end of a run of possibly-colliding keys.
  24.591 +        Object item;
  24.592 +        for (int i = nextKeyIndex(d, len); (item = tab[i]) != null;
  24.593 +             i = nextKeyIndex(i, len) ) {
  24.594 +            // The following test triggers if the item at slot i (which
  24.595 +            // hashes to be at slot r) should take the spot vacated by d.
  24.596 +            // If so, we swap it in, and then continue with d now at the
  24.597 +            // newly vacated i.  This process will terminate when we hit
  24.598 +            // the null slot at the end of this run.
  24.599 +            // The test is messy because we are using a circular table.
  24.600 +            int r = hash(item, len);
  24.601 +            if ((i < r && (r <= d || d <= i)) || (r <= d && d <= i)) {
  24.602 +                tab[d] = item;
  24.603 +                tab[d + 1] = tab[i + 1];
  24.604 +                tab[i] = null;
  24.605 +                tab[i + 1] = null;
  24.606 +                d = i;
  24.607 +            }
  24.608 +        }
  24.609 +    }
  24.610 +
  24.611 +    /**
  24.612 +     * Removes all of the mappings from this map.
  24.613 +     * The map will be empty after this call returns.
  24.614 +     */
  24.615 +    public void clear() {
  24.616 +        modCount++;
  24.617 +        Object[] tab = table;
  24.618 +        for (int i = 0; i < tab.length; i++)
  24.619 +            tab[i] = null;
  24.620 +        size = 0;
  24.621 +    }
  24.622 +
  24.623 +    /**
  24.624 +     * Compares the specified object with this map for equality.  Returns
  24.625 +     * <tt>true</tt> if the given object is also a map and the two maps
  24.626 +     * represent identical object-reference mappings.  More formally, this
  24.627 +     * map is equal to another map <tt>m</tt> if and only if
  24.628 +     * <tt>this.entrySet().equals(m.entrySet())</tt>.
  24.629 +     *
  24.630 +     * <p><b>Owing to the reference-equality-based semantics of this map it is
  24.631 +     * possible that the symmetry and transitivity requirements of the
  24.632 +     * <tt>Object.equals</tt> contract may be violated if this map is compared
  24.633 +     * to a normal map.  However, the <tt>Object.equals</tt> contract is
  24.634 +     * guaranteed to hold among <tt>IdentityHashMap</tt> instances.</b>
  24.635 +     *
  24.636 +     * @param  o object to be compared for equality with this map
  24.637 +     * @return <tt>true</tt> if the specified object is equal to this map
  24.638 +     * @see Object#equals(Object)
  24.639 +     */
  24.640 +    public boolean equals(Object o) {
  24.641 +        if (o == this) {
  24.642 +            return true;
  24.643 +        } else if (o instanceof IdentityHashMap) {
  24.644 +            IdentityHashMap m = (IdentityHashMap) o;
  24.645 +            if (m.size() != size)
  24.646 +                return false;
  24.647 +
  24.648 +            Object[] tab = m.table;
  24.649 +            for (int i = 0; i < tab.length; i+=2) {
  24.650 +                Object k = tab[i];
  24.651 +                if (k != null && !containsMapping(k, tab[i + 1]))
  24.652 +                    return false;
  24.653 +            }
  24.654 +            return true;
  24.655 +        } else if (o instanceof Map) {
  24.656 +            Map m = (Map)o;
  24.657 +            return entrySet().equals(m.entrySet());
  24.658 +        } else {
  24.659 +            return false;  // o is not a Map
  24.660 +        }
  24.661 +    }
  24.662 +
  24.663 +    /**
  24.664 +     * Returns the hash code value for this map.  The hash code of a map is
  24.665 +     * defined to be the sum of the hash codes of each entry in the map's
  24.666 +     * <tt>entrySet()</tt> view.  This ensures that <tt>m1.equals(m2)</tt>
  24.667 +     * implies that <tt>m1.hashCode()==m2.hashCode()</tt> for any two
  24.668 +     * <tt>IdentityHashMap</tt> instances <tt>m1</tt> and <tt>m2</tt>, as
  24.669 +     * required by the general contract of {@link Object#hashCode}.
  24.670 +     *
  24.671 +     * <p><b>Owing to the reference-equality-based semantics of the
  24.672 +     * <tt>Map.Entry</tt> instances in the set returned by this map's
  24.673 +     * <tt>entrySet</tt> method, it is possible that the contractual
  24.674 +     * requirement of <tt>Object.hashCode</tt> mentioned in the previous
  24.675 +     * paragraph will be violated if one of the two objects being compared is
  24.676 +     * an <tt>IdentityHashMap</tt> instance and the other is a normal map.</b>
  24.677 +     *
  24.678 +     * @return the hash code value for this map
  24.679 +     * @see Object#equals(Object)
  24.680 +     * @see #equals(Object)
  24.681 +     */
  24.682 +    public int hashCode() {
  24.683 +        int result = 0;
  24.684 +        Object[] tab = table;
  24.685 +        for (int i = 0; i < tab.length; i +=2) {
  24.686 +            Object key = tab[i];
  24.687 +            if (key != null) {
  24.688 +                Object k = unmaskNull(key);
  24.689 +                result += System.identityHashCode(k) ^
  24.690 +                          System.identityHashCode(tab[i + 1]);
  24.691 +            }
  24.692 +        }
  24.693 +        return result;
  24.694 +    }
  24.695 +
  24.696 +    /**
  24.697 +     * Returns a shallow copy of this identity hash map: the keys and values
  24.698 +     * themselves are not cloned.
  24.699 +     *
  24.700 +     * @return a shallow copy of this map
  24.701 +     */
  24.702 +    public Object clone() {
  24.703 +        try {
  24.704 +            IdentityHashMap<K,V> m = (IdentityHashMap<K,V>) super.clone();
  24.705 +            m.entrySet = null;
  24.706 +            m.table = table.clone();
  24.707 +            return m;
  24.708 +        } catch (CloneNotSupportedException e) {
  24.709 +            throw new InternalError();
  24.710 +        }
  24.711 +    }
  24.712 +
  24.713 +    private abstract class IdentityHashMapIterator<T> implements Iterator<T> {
  24.714 +        int index = (size != 0 ? 0 : table.length); // current slot.
  24.715 +        int expectedModCount = modCount; // to support fast-fail
  24.716 +        int lastReturnedIndex = -1;      // to allow remove()
  24.717 +        boolean indexValid; // To avoid unnecessary next computation
  24.718 +        Object[] traversalTable = table; // reference to main table or copy
  24.719 +
  24.720 +        public boolean hasNext() {
  24.721 +            Object[] tab = traversalTable;
  24.722 +            for (int i = index; i < tab.length; i+=2) {
  24.723 +                Object key = tab[i];
  24.724 +                if (key != null) {
  24.725 +                    index = i;
  24.726 +                    return indexValid = true;
  24.727 +                }
  24.728 +            }
  24.729 +            index = tab.length;
  24.730 +            return false;
  24.731 +        }
  24.732 +
  24.733 +        protected int nextIndex() {
  24.734 +            if (modCount != expectedModCount)
  24.735 +                throw new ConcurrentModificationException();
  24.736 +            if (!indexValid && !hasNext())
  24.737 +                throw new NoSuchElementException();
  24.738 +
  24.739 +            indexValid = false;
  24.740 +            lastReturnedIndex = index;
  24.741 +            index += 2;
  24.742 +            return lastReturnedIndex;
  24.743 +        }
  24.744 +
  24.745 +        public void remove() {
  24.746 +            if (lastReturnedIndex == -1)
  24.747 +                throw new IllegalStateException();
  24.748 +            if (modCount != expectedModCount)
  24.749 +                throw new ConcurrentModificationException();
  24.750 +
  24.751 +            expectedModCount = ++modCount;
  24.752 +            int deletedSlot = lastReturnedIndex;
  24.753 +            lastReturnedIndex = -1;
  24.754 +            // back up index to revisit new contents after deletion
  24.755 +            index = deletedSlot;
  24.756 +            indexValid = false;
  24.757 +
  24.758 +            // Removal code proceeds as in closeDeletion except that
  24.759 +            // it must catch the rare case where an element already
  24.760 +            // seen is swapped into a vacant slot that will be later
  24.761 +            // traversed by this iterator. We cannot allow future
  24.762 +            // next() calls to return it again.  The likelihood of
  24.763 +            // this occurring under 2/3 load factor is very slim, but
  24.764 +            // when it does happen, we must make a copy of the rest of
  24.765 +            // the table to use for the rest of the traversal. Since
  24.766 +            // this can only happen when we are near the end of the table,
  24.767 +            // even in these rare cases, this is not very expensive in
  24.768 +            // time or space.
  24.769 +
  24.770 +            Object[] tab = traversalTable;
  24.771 +            int len = tab.length;
  24.772 +
  24.773 +            int d = deletedSlot;
  24.774 +            K key = (K) tab[d];
  24.775 +            tab[d] = null;        // vacate the slot
  24.776 +            tab[d + 1] = null;
  24.777 +
  24.778 +            // If traversing a copy, remove in real table.
  24.779 +            // We can skip gap-closure on copy.
  24.780 +            if (tab != IdentityHashMap.this.table) {
  24.781 +                IdentityHashMap.this.remove(key);
  24.782 +                expectedModCount = modCount;
  24.783 +                return;
  24.784 +            }
  24.785 +
  24.786 +            size--;
  24.787 +
  24.788 +            Object item;
  24.789 +            for (int i = nextKeyIndex(d, len); (item = tab[i]) != null;
  24.790 +                 i = nextKeyIndex(i, len)) {
  24.791 +                int r = hash(item, len);
  24.792 +                // See closeDeletion for explanation of this conditional
  24.793 +                if ((i < r && (r <= d || d <= i)) ||
  24.794 +                    (r <= d && d <= i)) {
  24.795 +
  24.796 +                    // If we are about to swap an already-seen element
  24.797 +                    // into a slot that may later be returned by next(),
  24.798 +                    // then clone the rest of table for use in future
  24.799 +                    // next() calls. It is OK that our copy will have
  24.800 +                    // a gap in the "wrong" place, since it will never
  24.801 +                    // be used for searching anyway.
  24.802 +
  24.803 +                    if (i < deletedSlot && d >= deletedSlot &&
  24.804 +                        traversalTable == IdentityHashMap.this.table) {
  24.805 +                        int remaining = len - deletedSlot;
  24.806 +                        Object[] newTable = new Object[remaining];
  24.807 +                        System.arraycopy(tab, deletedSlot,
  24.808 +                                         newTable, 0, remaining);
  24.809 +                        traversalTable = newTable;
  24.810 +                        index = 0;
  24.811 +                    }
  24.812 +
  24.813 +                    tab[d] = item;
  24.814 +                    tab[d + 1] = tab[i + 1];
  24.815 +                    tab[i] = null;
  24.816 +                    tab[i + 1] = null;
  24.817 +                    d = i;
  24.818 +                }
  24.819 +            }
  24.820 +        }
  24.821 +    }
  24.822 +
  24.823 +    private class KeyIterator extends IdentityHashMapIterator<K> {
  24.824 +        public K next() {
  24.825 +            return (K) unmaskNull(traversalTable[nextIndex()]);
  24.826 +        }
  24.827 +    }
  24.828 +
  24.829 +    private class ValueIterator extends IdentityHashMapIterator<V> {
  24.830 +        public V next() {
  24.831 +            return (V) traversalTable[nextIndex() + 1];
  24.832 +        }
  24.833 +    }
  24.834 +
  24.835 +    private class EntryIterator
  24.836 +        extends IdentityHashMapIterator<Map.Entry<K,V>>
  24.837 +    {
  24.838 +        private Entry lastReturnedEntry = null;
  24.839 +
  24.840 +        public Map.Entry<K,V> next() {
  24.841 +            lastReturnedEntry = new Entry(nextIndex());
  24.842 +            return lastReturnedEntry;
  24.843 +        }
  24.844 +
  24.845 +        public void remove() {
  24.846 +            lastReturnedIndex =
  24.847 +                ((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
  24.848 +            super.remove();
  24.849 +            lastReturnedEntry.index = lastReturnedIndex;
  24.850 +            lastReturnedEntry = null;
  24.851 +        }
  24.852 +
  24.853 +        private class Entry implements Map.Entry<K,V> {
  24.854 +            private int index;
  24.855 +
  24.856 +            private Entry(int index) {
  24.857 +                this.index = index;
  24.858 +            }
  24.859 +
  24.860 +            public K getKey() {
  24.861 +                checkIndexForEntryUse();
  24.862 +                return (K) unmaskNull(traversalTable[index]);
  24.863 +            }
  24.864 +
  24.865 +            public V getValue() {
  24.866 +                checkIndexForEntryUse();
  24.867 +                return (V) traversalTable[index+1];
  24.868 +            }
  24.869 +
  24.870 +            public V setValue(V value) {
  24.871 +                checkIndexForEntryUse();
  24.872 +                V oldValue = (V) traversalTable[index+1];
  24.873 +                traversalTable[index+1] = value;
  24.874 +                // if shadowing, force into main table
  24.875 +                if (traversalTable != IdentityHashMap.this.table)
  24.876 +                    put((K) traversalTable[index], value);
  24.877 +                return oldValue;
  24.878 +            }
  24.879 +
  24.880 +            public boolean equals(Object o) {
  24.881 +                if (index < 0)
  24.882 +                    return super.equals(o);
  24.883 +
  24.884 +                if (!(o instanceof Map.Entry))
  24.885 +                    return false;
  24.886 +                Map.Entry e = (Map.Entry)o;
  24.887 +                return (e.getKey() == unmaskNull(traversalTable[index]) &&
  24.888 +                       e.getValue() == traversalTable[index+1]);
  24.889 +            }
  24.890 +
  24.891 +            public int hashCode() {
  24.892 +                if (lastReturnedIndex < 0)
  24.893 +                    return super.hashCode();
  24.894 +
  24.895 +                return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
  24.896 +                       System.identityHashCode(traversalTable[index+1]));
  24.897 +            }
  24.898 +
  24.899 +            public String toString() {
  24.900 +                if (index < 0)
  24.901 +                    return super.toString();
  24.902 +
  24.903 +                return (unmaskNull(traversalTable[index]) + "="
  24.904 +                        + traversalTable[index+1]);
  24.905 +            }
  24.906 +
  24.907 +            private void checkIndexForEntryUse() {
  24.908 +                if (index < 0)
  24.909 +                    throw new IllegalStateException("Entry was removed");
  24.910 +            }
  24.911 +        }
  24.912 +    }
  24.913 +
  24.914 +    // Views
  24.915 +
  24.916 +    /**
  24.917 +     * This field is initialized to contain an instance of the entry set
  24.918 +     * view the first time this view is requested.  The view is stateless,
  24.919 +     * so there's no reason to create more than one.
  24.920 +     */
  24.921 +    private transient Set<Map.Entry<K,V>> entrySet = null;
  24.922 +
  24.923 +    /**
  24.924 +     * Returns an identity-based set view of the keys contained in this map.
  24.925 +     * The set is backed by the map, so changes to the map are reflected in
  24.926 +     * the set, and vice-versa.  If the map is modified while an iteration
  24.927 +     * over the set is in progress, the results of the iteration are
  24.928 +     * undefined.  The set supports element removal, which removes the
  24.929 +     * corresponding mapping from the map, via the <tt>Iterator.remove</tt>,
  24.930 +     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
  24.931 +     * <tt>clear</tt> methods.  It does not support the <tt>add</tt> or
  24.932 +     * <tt>addAll</tt> methods.
  24.933 +     *
  24.934 +     * <p><b>While the object returned by this method implements the
  24.935 +     * <tt>Set</tt> interface, it does <i>not</i> obey <tt>Set's</tt> general
  24.936 +     * contract.  Like its backing map, the set returned by this method
  24.937 +     * defines element equality as reference-equality rather than
  24.938 +     * object-equality.  This affects the behavior of its <tt>contains</tt>,
  24.939 +     * <tt>remove</tt>, <tt>containsAll</tt>, <tt>equals</tt>, and
  24.940 +     * <tt>hashCode</tt> methods.</b>
  24.941 +     *
  24.942 +     * <p><b>The <tt>equals</tt> method of the returned set returns <tt>true</tt>
  24.943 +     * only if the specified object is a set containing exactly the same
  24.944 +     * object references as the returned set.  The symmetry and transitivity
  24.945 +     * requirements of the <tt>Object.equals</tt> contract may be violated if
  24.946 +     * the set returned by this method is compared to a normal set.  However,
  24.947 +     * the <tt>Object.equals</tt> contract is guaranteed to hold among sets
  24.948 +     * returned by this method.</b>
  24.949 +     *
  24.950 +     * <p>The <tt>hashCode</tt> method of the returned set returns the sum of
  24.951 +     * the <i>identity hashcodes</i> of the elements in the set, rather than
  24.952 +     * the sum of their hashcodes.  This is mandated by the change in the
  24.953 +     * semantics of the <tt>equals</tt> method, in order to enforce the
  24.954 +     * general contract of the <tt>Object.hashCode</tt> method among sets
  24.955 +     * returned by this method.
  24.956 +     *
  24.957 +     * @return an identity-based set view of the keys contained in this map
  24.958 +     * @see Object#equals(Object)
  24.959 +     * @see System#identityHashCode(Object)
  24.960 +     */
  24.961 +    public Set<K> keySet() {
  24.962 +        Set<K> ks = keySet;
  24.963 +        if (ks != null)
  24.964 +            return ks;
  24.965 +        else
  24.966 +            return keySet = new KeySet();
  24.967 +    }
  24.968 +
  24.969 +    private class KeySet extends AbstractSet<K> {
  24.970 +        public Iterator<K> iterator() {
  24.971 +            return new KeyIterator();
  24.972 +        }
  24.973 +        public int size() {
  24.974 +            return size;
  24.975 +        }
  24.976 +        public boolean contains(Object o) {
  24.977 +            return containsKey(o);
  24.978 +        }
  24.979 +        public boolean remove(Object o) {
  24.980 +            int oldSize = size;
  24.981 +            IdentityHashMap.this.remove(o);
  24.982 +            return size != oldSize;
  24.983 +        }
  24.984 +        /*
  24.985 +         * Must revert from AbstractSet's impl to AbstractCollection's, as
  24.986 +         * the former contains an optimization that results in incorrect
  24.987 +         * behavior when c is a smaller "normal" (non-identity-based) Set.
  24.988 +         */
  24.989 +        public boolean removeAll(Collection<?> c) {
  24.990 +            boolean modified = false;
  24.991 +            for (Iterator<K> i = iterator(); i.hasNext(); ) {
  24.992 +                if (c.contains(i.next())) {
  24.993 +                    i.remove();
  24.994 +                    modified = true;
  24.995 +                }
  24.996 +            }
  24.997 +            return modified;
  24.998 +        }
  24.999 +        public void clear() {
 24.1000 +            IdentityHashMap.this.clear();
 24.1001 +        }
 24.1002 +        public int hashCode() {
 24.1003 +            int result = 0;
 24.1004 +            for (K key : this)
 24.1005 +                result += System.identityHashCode(key);
 24.1006 +            return result;
 24.1007 +        }
 24.1008 +    }
 24.1009 +
 24.1010 +    /**
 24.1011 +     * Returns a {@link Collection} view of the values contained in this map.
 24.1012 +     * The collection is backed by the map, so changes to the map are
 24.1013 +     * reflected in the collection, and vice-versa.  If the map is
 24.1014 +     * modified while an iteration over the collection is in progress,
 24.1015 +     * the results of the iteration are undefined.  The collection
 24.1016 +     * supports element removal, which removes the corresponding
 24.1017 +     * mapping from the map, via the <tt>Iterator.remove</tt>,
 24.1018 +     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
 24.1019 +     * <tt>retainAll</tt> and <tt>clear</tt> methods.  It does not
 24.1020 +     * support the <tt>add</tt> or <tt>addAll</tt> methods.
 24.1021 +     *
 24.1022 +     * <p><b>While the object returned by this method implements the
 24.1023 +     * <tt>Collection</tt> interface, it does <i>not</i> obey
 24.1024 +     * <tt>Collection's</tt> general contract.  Like its backing map,
 24.1025 +     * the collection returned by this method defines element equality as
 24.1026 +     * reference-equality rather than object-equality.  This affects the
 24.1027 +     * behavior of its <tt>contains</tt>, <tt>remove</tt> and
 24.1028 +     * <tt>containsAll</tt> methods.</b>
 24.1029 +     */
 24.1030 +    public Collection<V> values() {
 24.1031 +        Collection<V> vs = values;
 24.1032 +        if (vs != null)
 24.1033 +            return vs;
 24.1034 +        else
 24.1035 +            return values = new Values();
 24.1036 +    }
 24.1037 +
 24.1038 +    private class Values extends AbstractCollection<V> {
 24.1039 +        public Iterator<V> iterator() {
 24.1040 +            return new ValueIterator();
 24.1041 +        }
 24.1042 +        public int size() {
 24.1043 +            return size;
 24.1044 +        }
 24.1045 +        public boolean contains(Object o) {
 24.1046 +            return containsValue(o);
 24.1047 +        }
 24.1048 +        public boolean remove(Object o) {
 24.1049 +            for (Iterator<V> i = iterator(); i.hasNext(); ) {
 24.1050 +                if (i.next() == o) {
 24.1051 +                    i.remove();
 24.1052 +                    return true;
 24.1053 +                }
 24.1054 +            }
 24.1055 +            return false;
 24.1056 +        }
 24.1057 +        public void clear() {
 24.1058 +            IdentityHashMap.this.clear();
 24.1059 +        }
 24.1060 +    }
 24.1061 +
 24.1062 +    /**
 24.1063 +     * Returns a {@link Set} view of the mappings contained in this map.
 24.1064 +     * Each element in the returned set is a reference-equality-based
 24.1065 +     * <tt>Map.Entry</tt>.  The set is backed by the map, so changes
 24.1066 +     * to the map are reflected in the set, and vice-versa.  If the
 24.1067 +     * map is modified while an iteration over the set is in progress,
 24.1068 +     * the results of the iteration are undefined.  The set supports
 24.1069 +     * element removal, which removes the corresponding mapping from
 24.1070 +     * the map, via the <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
 24.1071 +     * <tt>removeAll</tt>, <tt>retainAll</tt> and <tt>clear</tt>
 24.1072 +     * methods.  It does not support the <tt>add</tt> or
 24.1073 +     * <tt>addAll</tt> methods.
 24.1074 +     *
 24.1075 +     * <p>Like the backing map, the <tt>Map.Entry</tt> objects in the set
 24.1076 +     * returned by this method define key and value equality as
 24.1077 +     * reference-equality rather than object-equality.  This affects the
 24.1078 +     * behavior of the <tt>equals</tt> and <tt>hashCode</tt> methods of these
 24.1079 +     * <tt>Map.Entry</tt> objects.  A reference-equality based <tt>Map.Entry
 24.1080 +     * e</tt> is equal to an object <tt>o</tt> if and only if <tt>o</tt> is a
 24.1081 +     * <tt>Map.Entry</tt> and <tt>e.getKey()==o.getKey() &amp;&amp;
 24.1082 +     * e.getValue()==o.getValue()</tt>.  To accommodate these equals
 24.1083 +     * semantics, the <tt>hashCode</tt> method returns
 24.1084 +     * <tt>System.identityHashCode(e.getKey()) ^
 24.1085 +     * System.identityHashCode(e.getValue())</tt>.
 24.1086 +     *
 24.1087 +     * <p><b>Owing to the reference-equality-based semantics of the
 24.1088 +     * <tt>Map.Entry</tt> instances in the set returned by this method,
 24.1089 +     * it is possible that the symmetry and transitivity requirements of
 24.1090 +     * the {@link Object#equals(Object)} contract may be violated if any of
 24.1091 +     * the entries in the set is compared to a normal map entry, or if
 24.1092 +     * the set returned by this method is compared to a set of normal map
 24.1093 +     * entries (such as would be returned by a call to this method on a normal
 24.1094 +     * map).  However, the <tt>Object.equals</tt> contract is guaranteed to
 24.1095 +     * hold among identity-based map entries, and among sets of such entries.
 24.1096 +     * </b>
 24.1097 +     *
 24.1098 +     * @return a set view of the identity-mappings contained in this map
 24.1099 +     */
 24.1100 +    public Set<Map.Entry<K,V>> entrySet() {
 24.1101 +        Set<Map.Entry<K,V>> es = entrySet;
 24.1102 +        if (es != null)
 24.1103 +            return es;
 24.1104 +        else
 24.1105 +            return entrySet = new EntrySet();
 24.1106 +    }
 24.1107 +
 24.1108 +    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
 24.1109 +        public Iterator<Map.Entry<K,V>> iterator() {
 24.1110 +            return new EntryIterator();
 24.1111 +        }
 24.1112 +        public boolean contains(Object o) {
 24.1113 +            if (!(o instanceof Map.Entry))
 24.1114 +                return false;
 24.1115 +            Map.Entry entry = (Map.Entry)o;
 24.1116 +            return containsMapping(entry.getKey(), entry.getValue());
 24.1117 +        }
 24.1118 +        public boolean remove(Object o) {
 24.1119 +            if (!(o instanceof Map.Entry))
 24.1120 +                return false;
 24.1121 +            Map.Entry entry = (Map.Entry)o;
 24.1122 +            return removeMapping(entry.getKey(), entry.getValue());
 24.1123 +        }
 24.1124 +        public int size() {
 24.1125 +            return size;
 24.1126 +        }
 24.1127 +        public void clear() {
 24.1128 +            IdentityHashMap.this.clear();
 24.1129 +        }
 24.1130 +        /*
 24.1131 +         * Must revert from AbstractSet's impl to AbstractCollection's, as
 24.1132 +         * the former contains an optimization that results in incorrect
 24.1133 +         * behavior when c is a smaller "normal" (non-identity-based) Set.
 24.1134 +         */
 24.1135 +        public boolean removeAll(Collection<?> c) {
 24.1136 +            boolean modified = false;
 24.1137 +            for (Iterator<Map.Entry<K,V>> i = iterator(); i.hasNext(); ) {
 24.1138 +                if (c.contains(i.next())) {
 24.1139 +                    i.remove();
 24.1140 +                    modified = true;
 24.1141 +                }
 24.1142 +            }
 24.1143 +            return modified;
 24.1144 +        }
 24.1145 +
 24.1146 +        public Object[] toArray() {
 24.1147 +            int size = size();
 24.1148 +            Object[] result = new Object[size];
 24.1149 +            Iterator<Map.Entry<K,V>> it = iterator();
 24.1150 +            for (int i = 0; i < size; i++)
 24.1151 +                result[i] = new AbstractMap.SimpleEntry<>(it.next());
 24.1152 +            return result;
 24.1153 +        }
 24.1154 +
 24.1155 +        @SuppressWarnings("unchecked")
 24.1156 +        public <T> T[] toArray(T[] a) {
 24.1157 +            int size = size();
 24.1158 +            if (a.length < size)
 24.1159 +                a = (T[])java.lang.reflect.Array
 24.1160 +                    .newInstance(a.getClass().getComponentType(), size);
 24.1161 +            Iterator<Map.Entry<K,V>> it = iterator();
 24.1162 +            for (int i = 0; i < size; i++)
 24.1163 +                a[i] = (T) new AbstractMap.SimpleEntry<>(it.next());
 24.1164 +            if (a.length > size)
 24.1165 +                a[size] = null;
 24.1166 +            return a;
 24.1167 +        }
 24.1168 +    }
 24.1169 +
 24.1170 +
 24.1171 +    private static final long serialVersionUID = 8188218128353913216L;
 24.1172 +
 24.1173 +    /**
 24.1174 +     * Save the state of the <tt>IdentityHashMap</tt> instance to a stream
 24.1175 +     * (i.e., serialize it).
 24.1176 +     *
 24.1177 +     * @serialData The <i>size</i> of the HashMap (the number of key-value
 24.1178 +     *          mappings) (<tt>int</tt>), followed by the key (Object) and
 24.1179 +     *          value (Object) for each key-value mapping represented by the
 24.1180 +     *          IdentityHashMap.  The key-value mappings are emitted in no
 24.1181 +     *          particular order.
 24.1182 +     */
 24.1183 +    private void writeObject(java.io.ObjectOutputStream s)
 24.1184 +        throws java.io.IOException  {
 24.1185 +        // Write out and any hidden stuff
 24.1186 +        s.defaultWriteObject();
 24.1187 +
 24.1188 +        // Write out size (number of Mappings)
 24.1189 +        s.writeInt(size);
 24.1190 +
 24.1191 +        // Write out keys and values (alternating)
 24.1192 +        Object[] tab = table;
 24.1193 +        for (int i = 0; i < tab.length; i += 2) {
 24.1194 +            Object key = tab[i];
 24.1195 +            if (key != null) {
 24.1196 +                s.writeObject(unmaskNull(key));
 24.1197 +                s.writeObject(tab[i + 1]);
 24.1198 +            }
 24.1199 +        }
 24.1200 +    }
 24.1201 +
 24.1202 +    /**
 24.1203 +     * Reconstitute the <tt>IdentityHashMap</tt> instance from a stream (i.e.,
 24.1204 +     * deserialize it).
 24.1205 +     */
 24.1206 +    private void readObject(java.io.ObjectInputStream s)
 24.1207 +        throws java.io.IOException, ClassNotFoundException  {
 24.1208 +        // Read in any hidden stuff
 24.1209 +        s.defaultReadObject();
 24.1210 +
 24.1211 +        // Read in size (number of Mappings)
 24.1212 +        int size = s.readInt();
 24.1213 +
 24.1214 +        // Allow for 33% growth (i.e., capacity is >= 2* size()).
 24.1215 +        init(capacity((size*4)/3));
 24.1216 +
 24.1217 +        // Read the keys and values, and put the mappings in the table
 24.1218 +        for (int i=0; i<size; i++) {
 24.1219 +            K key = (K) s.readObject();
 24.1220 +            V value = (V) s.readObject();
 24.1221 +            putForCreate(key, value);
 24.1222 +        }
 24.1223 +    }
 24.1224 +
 24.1225 +    /**
 24.1226 +     * The put method for readObject.  It does not resize the table,
 24.1227 +     * update modCount, etc.
 24.1228 +     */
 24.1229 +    private void putForCreate(K key, V value)
 24.1230 +        throws IOException
 24.1231 +    {
 24.1232 +        K k = (K)maskNull(key);
 24.1233 +        Object[] tab = table;
 24.1234 +        int len = tab.length;
 24.1235 +        int i = hash(k, len);
 24.1236 +
 24.1237 +        Object item;
 24.1238 +        while ( (item = tab[i]) != null) {
 24.1239 +            if (item == k)
 24.1240 +                throw new java.io.StreamCorruptedException();
 24.1241 +            i = nextKeyIndex(i, len);
 24.1242 +        }
 24.1243 +        tab[i] = k;
 24.1244 +        tab[i + 1] = value;
 24.1245 +    }
 24.1246 +}
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/rt/emul/compact/src/main/java/java/util/LinkedHashSet.java	Sat Sep 07 13:55:09 2013 +0200
    25.3 @@ -0,0 +1,171 @@
    25.4 +/*
    25.5 + * Copyright (c) 2000, 2006, 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.util;
   25.30 +
   25.31 +/**
   25.32 + * <p>Hash table and linked list implementation of the <tt>Set</tt> interface,
   25.33 + * with predictable iteration order.  This implementation differs from
   25.34 + * <tt>HashSet</tt> in that it maintains a doubly-linked list running through
   25.35 + * all of its entries.  This linked list defines the iteration ordering,
   25.36 + * which is the order in which elements were inserted into the set
   25.37 + * (<i>insertion-order</i>).  Note that insertion order is <i>not</i> affected
   25.38 + * if an element is <i>re-inserted</i> into the set.  (An element <tt>e</tt>
   25.39 + * is reinserted into a set <tt>s</tt> if <tt>s.add(e)</tt> is invoked when
   25.40 + * <tt>s.contains(e)</tt> would return <tt>true</tt> immediately prior to
   25.41 + * the invocation.)
   25.42 + *
   25.43 + * <p>This implementation spares its clients from the unspecified, generally
   25.44 + * chaotic ordering provided by {@link HashSet}, without incurring the
   25.45 + * increased cost associated with {@link TreeSet}.  It can be used to
   25.46 + * produce a copy of a set that has the same order as the original, regardless
   25.47 + * of the original set's implementation:
   25.48 + * <pre>
   25.49 + *     void foo(Set s) {
   25.50 + *         Set copy = new LinkedHashSet(s);
   25.51 + *         ...
   25.52 + *     }
   25.53 + * </pre>
   25.54 + * This technique is particularly useful if a module takes a set on input,
   25.55 + * copies it, and later returns results whose order is determined by that of
   25.56 + * the copy.  (Clients generally appreciate having things returned in the same
   25.57 + * order they were presented.)
   25.58 + *
   25.59 + * <p>This class provides all of the optional <tt>Set</tt> operations, and
   25.60 + * permits null elements.  Like <tt>HashSet</tt>, it provides constant-time
   25.61 + * performance for the basic operations (<tt>add</tt>, <tt>contains</tt> and
   25.62 + * <tt>remove</tt>), assuming the hash function disperses elements
   25.63 + * properly among the buckets.  Performance is likely to be just slightly
   25.64 + * below that of <tt>HashSet</tt>, due to the added expense of maintaining the
   25.65 + * linked list, with one exception: Iteration over a <tt>LinkedHashSet</tt>
   25.66 + * requires time proportional to the <i>size</i> of the set, regardless of
   25.67 + * its capacity.  Iteration over a <tt>HashSet</tt> is likely to be more
   25.68 + * expensive, requiring time proportional to its <i>capacity</i>.
   25.69 + *
   25.70 + * <p>A linked hash set has two parameters that affect its performance:
   25.71 + * <i>initial capacity</i> and <i>load factor</i>.  They are defined precisely
   25.72 + * as for <tt>HashSet</tt>.  Note, however, that the penalty for choosing an
   25.73 + * excessively high value for initial capacity is less severe for this class
   25.74 + * than for <tt>HashSet</tt>, as iteration times for this class are unaffected
   25.75 + * by capacity.
   25.76 + *
   25.77 + * <p><strong>Note that this implementation is not synchronized.</strong>
   25.78 + * If multiple threads access a linked hash set concurrently, and at least
   25.79 + * one of the threads modifies the set, it <em>must</em> be synchronized
   25.80 + * externally.  This is typically accomplished by synchronizing on some
   25.81 + * object that naturally encapsulates the set.
   25.82 + *
   25.83 + * If no such object exists, the set should be "wrapped" using the
   25.84 + * {@link Collections#synchronizedSet Collections.synchronizedSet}
   25.85 + * method.  This is best done at creation time, to prevent accidental
   25.86 + * unsynchronized access to the set: <pre>
   25.87 + *   Set s = Collections.synchronizedSet(new LinkedHashSet(...));</pre>
   25.88 + *
   25.89 + * <p>The iterators returned by this class's <tt>iterator</tt> method are
   25.90 + * <em>fail-fast</em>: if the set is modified at any time after the iterator
   25.91 + * is created, in any way except through the iterator's own <tt>remove</tt>
   25.92 + * method, the iterator will throw a {@link ConcurrentModificationException}.
   25.93 + * Thus, in the face of concurrent modification, the iterator fails quickly
   25.94 + * and cleanly, rather than risking arbitrary, non-deterministic behavior at
   25.95 + * an undetermined time in the future.
   25.96 + *
   25.97 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   25.98 + * as it is, generally speaking, impossible to make any hard guarantees in the
   25.99 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
  25.100 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  25.101 + * Therefore, it would be wrong to write a program that depended on this
  25.102 + * exception for its correctness:   <i>the fail-fast behavior of iterators
  25.103 + * should be used only to detect bugs.</i>
  25.104 + *
  25.105 + * <p>This class is a member of the
  25.106 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  25.107 + * Java Collections Framework</a>.
  25.108 + *
  25.109 + * @param <E> the type of elements maintained by this set
  25.110 + *
  25.111 + * @author  Josh Bloch
  25.112 + * @see     Object#hashCode()
  25.113 + * @see     Collection
  25.114 + * @see     Set
  25.115 + * @see     HashSet
  25.116 + * @see     TreeSet
  25.117 + * @see     Hashtable
  25.118 + * @since   1.4
  25.119 + */
  25.120 +
  25.121 +public class LinkedHashSet<E>
  25.122 +    extends HashSet<E>
  25.123 +    implements Set<E>, Cloneable, java.io.Serializable {
  25.124 +
  25.125 +    private static final long serialVersionUID = -2851667679971038690L;
  25.126 +
  25.127 +    /**
  25.128 +     * Constructs a new, empty linked hash set with the specified initial
  25.129 +     * capacity and load factor.
  25.130 +     *
  25.131 +     * @param      initialCapacity the initial capacity of the linked hash set
  25.132 +     * @param      loadFactor      the load factor of the linked hash set
  25.133 +     * @throws     IllegalArgumentException  if the initial capacity is less
  25.134 +     *               than zero, or if the load factor is nonpositive
  25.135 +     */
  25.136 +    public LinkedHashSet(int initialCapacity, float loadFactor) {
  25.137 +        super(initialCapacity, loadFactor, true);
  25.138 +    }
  25.139 +
  25.140 +    /**
  25.141 +     * Constructs a new, empty linked hash set with the specified initial
  25.142 +     * capacity and the default load factor (0.75).
  25.143 +     *
  25.144 +     * @param   initialCapacity   the initial capacity of the LinkedHashSet
  25.145 +     * @throws  IllegalArgumentException if the initial capacity is less
  25.146 +     *              than zero
  25.147 +     */
  25.148 +    public LinkedHashSet(int initialCapacity) {
  25.149 +        super(initialCapacity, .75f, true);
  25.150 +    }
  25.151 +
  25.152 +    /**
  25.153 +     * Constructs a new, empty linked hash set with the default initial
  25.154 +     * capacity (16) and load factor (0.75).
  25.155 +     */
  25.156 +    public LinkedHashSet() {
  25.157 +        super(16, .75f, true);
  25.158 +    }
  25.159 +
  25.160 +    /**
  25.161 +     * Constructs a new linked hash set with the same elements as the
  25.162 +     * specified collection.  The linked hash set is created with an initial
  25.163 +     * capacity sufficient to hold the elements in the specified collection
  25.164 +     * and the default load factor (0.75).
  25.165 +     *
  25.166 +     * @param c  the collection whose elements are to be placed into
  25.167 +     *           this set
  25.168 +     * @throws NullPointerException if the specified collection is null
  25.169 +     */
  25.170 +    public LinkedHashSet(Collection<? extends E> c) {
  25.171 +        super(Math.max(2*c.size(), 11), .75f, true);
  25.172 +        addAll(c);
  25.173 +    }
  25.174 +}
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/rt/emul/compact/src/main/java/java/util/NavigableMap.java	Sat Sep 07 13:55:09 2013 +0200
    26.3 @@ -0,0 +1,424 @@
    26.4 +/*
    26.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    26.6 + *
    26.7 + * This code is free software; you can redistribute it and/or modify it
    26.8 + * under the terms of the GNU General Public License version 2 only, as
    26.9 + * published by the Free Software Foundation.  Oracle designates this
   26.10 + * particular file as subject to the "Classpath" exception as provided
   26.11 + * by Oracle in the LICENSE file that accompanied this code.
   26.12 + *
   26.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   26.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   26.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   26.16 + * version 2 for more details (a copy is included in the LICENSE file that
   26.17 + * accompanied this code).
   26.18 + *
   26.19 + * You should have received a copy of the GNU General Public License version
   26.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   26.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   26.22 + *
   26.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   26.24 + * or visit www.oracle.com if you need additional information or have any
   26.25 + * questions.
   26.26 + */
   26.27 +
   26.28 +/*
   26.29 + * This file is available under and governed by the GNU General Public
   26.30 + * License version 2 only, as published by the Free Software Foundation.
   26.31 + * However, the following notice accompanied the original version of this
   26.32 + * file:
   26.33 + *
   26.34 + * Written by Doug Lea and Josh Bloch with assistance from members of JCP
   26.35 + * JSR-166 Expert Group and released to the public domain, as explained at
   26.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   26.37 + */
   26.38 +
   26.39 +package java.util;
   26.40 +
   26.41 +/**
   26.42 + * A {@link SortedMap} extended with navigation methods returning the
   26.43 + * closest matches for given search targets. Methods
   26.44 + * {@code lowerEntry}, {@code floorEntry}, {@code ceilingEntry},
   26.45 + * and {@code higherEntry} return {@code Map.Entry} objects
   26.46 + * associated with keys respectively less than, less than or equal,
   26.47 + * greater than or equal, and greater than a given key, returning
   26.48 + * {@code null} if there is no such key.  Similarly, methods
   26.49 + * {@code lowerKey}, {@code floorKey}, {@code ceilingKey}, and
   26.50 + * {@code higherKey} return only the associated keys. All of these
   26.51 + * methods are designed for locating, not traversing entries.
   26.52 + *
   26.53 + * <p>A {@code NavigableMap} may be accessed and traversed in either
   26.54 + * ascending or descending key order.  The {@code descendingMap}
   26.55 + * method returns a view of the map with the senses of all relational
   26.56 + * and directional methods inverted. The performance of ascending
   26.57 + * operations and views is likely to be faster than that of descending
   26.58 + * ones.  Methods {@code subMap}, {@code headMap},
   26.59 + * and {@code tailMap} differ from the like-named {@code
   26.60 + * SortedMap} methods in accepting additional arguments describing
   26.61 + * whether lower and upper bounds are inclusive versus exclusive.
   26.62 + * Submaps of any {@code NavigableMap} must implement the {@code
   26.63 + * NavigableMap} interface.
   26.64 + *
   26.65 + * <p>This interface additionally defines methods {@code firstEntry},
   26.66 + * {@code pollFirstEntry}, {@code lastEntry}, and
   26.67 + * {@code pollLastEntry} that return and/or remove the least and
   26.68 + * greatest mappings, if any exist, else returning {@code null}.
   26.69 + *
   26.70 + * <p>Implementations of entry-returning methods are expected to
   26.71 + * return {@code Map.Entry} pairs representing snapshots of mappings
   26.72 + * at the time they were produced, and thus generally do <em>not</em>
   26.73 + * support the optional {@code Entry.setValue} method. Note however
   26.74 + * that it is possible to change mappings in the associated map using
   26.75 + * method {@code put}.
   26.76 + *
   26.77 + * <p>Methods
   26.78 + * {@link #subMap(Object, Object) subMap(K, K)},
   26.79 + * {@link #headMap(Object) headMap(K)}, and
   26.80 + * {@link #tailMap(Object) tailMap(K)}
   26.81 + * are specified to return {@code SortedMap} to allow existing
   26.82 + * implementations of {@code SortedMap} to be compatibly retrofitted to
   26.83 + * implement {@code NavigableMap}, but extensions and implementations
   26.84 + * of this interface are encouraged to override these methods to return
   26.85 + * {@code NavigableMap}.  Similarly,
   26.86 + * {@link #keySet()} can be overriden to return {@code NavigableSet}.
   26.87 + *
   26.88 + * <p>This interface is a member of the
   26.89 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   26.90 + * Java Collections Framework</a>.
   26.91 + *
   26.92 + * @author Doug Lea
   26.93 + * @author Josh Bloch
   26.94 + * @param <K> the type of keys maintained by this map
   26.95 + * @param <V> the type of mapped values
   26.96 + * @since 1.6
   26.97 + */
   26.98 +public interface NavigableMap<K,V> extends SortedMap<K,V> {
   26.99 +    /**
  26.100 +     * Returns a key-value mapping associated with the greatest key
  26.101 +     * strictly less than the given key, or {@code null} if there is
  26.102 +     * no such key.
  26.103 +     *
  26.104 +     * @param key the key
  26.105 +     * @return an entry with the greatest key less than {@code key},
  26.106 +     *         or {@code null} if there is no such key
  26.107 +     * @throws ClassCastException if the specified key cannot be compared
  26.108 +     *         with the keys currently in the map
  26.109 +     * @throws NullPointerException if the specified key is null
  26.110 +     *         and this map does not permit null keys
  26.111 +     */
  26.112 +    Map.Entry<K,V> lowerEntry(K key);
  26.113 +
  26.114 +    /**
  26.115 +     * Returns the greatest key strictly less than the given key, or
  26.116 +     * {@code null} if there is no such key.
  26.117 +     *
  26.118 +     * @param key the key
  26.119 +     * @return the greatest key less than {@code key},
  26.120 +     *         or {@code null} if there is no such key
  26.121 +     * @throws ClassCastException if the specified key cannot be compared
  26.122 +     *         with the keys currently in the map
  26.123 +     * @throws NullPointerException if the specified key is null
  26.124 +     *         and this map does not permit null keys
  26.125 +     */
  26.126 +    K lowerKey(K key);
  26.127 +
  26.128 +    /**
  26.129 +     * Returns a key-value mapping associated with the greatest key
  26.130 +     * less than or equal to the given key, or {@code null} if there
  26.131 +     * is no such key.
  26.132 +     *
  26.133 +     * @param key the key
  26.134 +     * @return an entry with the greatest key less than or equal to
  26.135 +     *         {@code key}, or {@code null} if there is no such key
  26.136 +     * @throws ClassCastException if the specified key cannot be compared
  26.137 +     *         with the keys currently in the map
  26.138 +     * @throws NullPointerException if the specified key is null
  26.139 +     *         and this map does not permit null keys
  26.140 +     */
  26.141 +    Map.Entry<K,V> floorEntry(K key);
  26.142 +
  26.143 +    /**
  26.144 +     * Returns the greatest key less than or equal to the given key,
  26.145 +     * or {@code null} if there is no such key.
  26.146 +     *
  26.147 +     * @param key the key
  26.148 +     * @return the greatest key less than or equal to {@code key},
  26.149 +     *         or {@code null} if there is no such key
  26.150 +     * @throws ClassCastException if the specified key cannot be compared
  26.151 +     *         with the keys currently in the map
  26.152 +     * @throws NullPointerException if the specified key is null
  26.153 +     *         and this map does not permit null keys
  26.154 +     */
  26.155 +    K floorKey(K key);
  26.156 +
  26.157 +    /**
  26.158 +     * Returns a key-value mapping associated with the least key
  26.159 +     * greater than or equal to the given key, or {@code null} if
  26.160 +     * there is no such key.
  26.161 +     *
  26.162 +     * @param key the key
  26.163 +     * @return an entry with the least key greater than or equal to
  26.164 +     *         {@code key}, or {@code null} if there is no such key
  26.165 +     * @throws ClassCastException if the specified key cannot be compared
  26.166 +     *         with the keys currently in the map
  26.167 +     * @throws NullPointerException if the specified key is null
  26.168 +     *         and this map does not permit null keys
  26.169 +     */
  26.170 +    Map.Entry<K,V> ceilingEntry(K key);
  26.171 +
  26.172 +    /**
  26.173 +     * Returns the least key greater than or equal to the given key,
  26.174 +     * or {@code null} if there is no such key.
  26.175 +     *
  26.176 +     * @param key the key
  26.177 +     * @return the least key greater than or equal to {@code key},
  26.178 +     *         or {@code null} if there is no such key
  26.179 +     * @throws ClassCastException if the specified key cannot be compared
  26.180 +     *         with the keys currently in the map
  26.181 +     * @throws NullPointerException if the specified key is null
  26.182 +     *         and this map does not permit null keys
  26.183 +     */
  26.184 +    K ceilingKey(K key);
  26.185 +
  26.186 +    /**
  26.187 +     * Returns a key-value mapping associated with the least key
  26.188 +     * strictly greater than the given key, or {@code null} if there
  26.189 +     * is no such key.
  26.190 +     *
  26.191 +     * @param key the key
  26.192 +     * @return an entry with the least key greater than {@code key},
  26.193 +     *         or {@code null} if there is no such key
  26.194 +     * @throws ClassCastException if the specified key cannot be compared
  26.195 +     *         with the keys currently in the map
  26.196 +     * @throws NullPointerException if the specified key is null
  26.197 +     *         and this map does not permit null keys
  26.198 +     */
  26.199 +    Map.Entry<K,V> higherEntry(K key);
  26.200 +
  26.201 +    /**
  26.202 +     * Returns the least key strictly greater than the given key, or
  26.203 +     * {@code null} if there is no such key.
  26.204 +     *
  26.205 +     * @param key the key
  26.206 +     * @return the least key greater than {@code key},
  26.207 +     *         or {@code null} if there is no such key
  26.208 +     * @throws ClassCastException if the specified key cannot be compared
  26.209 +     *         with the keys currently in the map
  26.210 +     * @throws NullPointerException if the specified key is null
  26.211 +     *         and this map does not permit null keys
  26.212 +     */
  26.213 +    K higherKey(K key);
  26.214 +
  26.215 +    /**
  26.216 +     * Returns a key-value mapping associated with the least
  26.217 +     * key in this map, or {@code null} if the map is empty.
  26.218 +     *
  26.219 +     * @return an entry with the least key,
  26.220 +     *         or {@code null} if this map is empty
  26.221 +     */
  26.222 +    Map.Entry<K,V> firstEntry();
  26.223 +
  26.224 +    /**
  26.225 +     * Returns a key-value mapping associated with the greatest
  26.226 +     * key in this map, or {@code null} if the map is empty.
  26.227 +     *
  26.228 +     * @return an entry with the greatest key,
  26.229 +     *         or {@code null} if this map is empty
  26.230 +     */
  26.231 +    Map.Entry<K,V> lastEntry();
  26.232 +
  26.233 +    /**
  26.234 +     * Removes and returns a key-value mapping associated with
  26.235 +     * the least key in this map, or {@code null} if the map is empty.
  26.236 +     *
  26.237 +     * @return the removed first entry of this map,
  26.238 +     *         or {@code null} if this map is empty
  26.239 +     */
  26.240 +    Map.Entry<K,V> pollFirstEntry();
  26.241 +
  26.242 +    /**
  26.243 +     * Removes and returns a key-value mapping associated with
  26.244 +     * the greatest key in this map, or {@code null} if the map is empty.
  26.245 +     *
  26.246 +     * @return the removed last entry of this map,
  26.247 +     *         or {@code null} if this map is empty
  26.248 +     */
  26.249 +    Map.Entry<K,V> pollLastEntry();
  26.250 +
  26.251 +    /**
  26.252 +     * Returns a reverse order view of the mappings contained in this map.
  26.253 +     * The descending map is backed by this map, so changes to the map are
  26.254 +     * reflected in the descending map, and vice-versa.  If either map is
  26.255 +     * modified while an iteration over a collection view of either map
  26.256 +     * is in progress (except through the iterator's own {@code remove}
  26.257 +     * operation), the results of the iteration are undefined.
  26.258 +     *
  26.259 +     * <p>The returned map has an ordering equivalent to
  26.260 +     * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
  26.261 +     * The expression {@code m.descendingMap().descendingMap()} returns a
  26.262 +     * view of {@code m} essentially equivalent to {@code m}.
  26.263 +     *
  26.264 +     * @return a reverse order view of this map
  26.265 +     */
  26.266 +    NavigableMap<K,V> descendingMap();
  26.267 +
  26.268 +    /**
  26.269 +     * Returns a {@link NavigableSet} view of the keys contained in this map.
  26.270 +     * The set's iterator returns the keys in ascending order.
  26.271 +     * The set is backed by the map, so changes to the map are reflected in
  26.272 +     * the set, and vice-versa.  If the map is modified while an iteration
  26.273 +     * over the set is in progress (except through the iterator's own {@code
  26.274 +     * remove} operation), the results of the iteration are undefined.  The
  26.275 +     * set supports element removal, which removes the corresponding mapping
  26.276 +     * from the map, via the {@code Iterator.remove}, {@code Set.remove},
  26.277 +     * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
  26.278 +     * It does not support the {@code add} or {@code addAll} operations.
  26.279 +     *
  26.280 +     * @return a navigable set view of the keys in this map
  26.281 +     */
  26.282 +    NavigableSet<K> navigableKeySet();
  26.283 +
  26.284 +    /**
  26.285 +     * Returns a reverse order {@link NavigableSet} view of the keys contained in this map.
  26.286 +     * The set's iterator returns the keys in descending order.
  26.287 +     * The set is backed by the map, so changes to the map are reflected in
  26.288 +     * the set, and vice-versa.  If the map is modified while an iteration
  26.289 +     * over the set is in progress (except through the iterator's own {@code
  26.290 +     * remove} operation), the results of the iteration are undefined.  The
  26.291 +     * set supports element removal, which removes the corresponding mapping
  26.292 +     * from the map, via the {@code Iterator.remove}, {@code Set.remove},
  26.293 +     * {@code removeAll}, {@code retainAll}, and {@code clear} operations.
  26.294 +     * It does not support the {@code add} or {@code addAll} operations.
  26.295 +     *
  26.296 +     * @return a reverse order navigable set view of the keys in this map
  26.297 +     */
  26.298 +    NavigableSet<K> descendingKeySet();
  26.299 +
  26.300 +    /**
  26.301 +     * Returns a view of the portion of this map whose keys range from
  26.302 +     * {@code fromKey} to {@code toKey}.  If {@code fromKey} and
  26.303 +     * {@code toKey} are equal, the returned map is empty unless
  26.304 +     * {@code fromInclusive} and {@code toInclusive} are both true.  The
  26.305 +     * returned map is backed by this map, so changes in the returned map are
  26.306 +     * reflected in this map, and vice-versa.  The returned map supports all
  26.307 +     * optional map operations that this map supports.
  26.308 +     *
  26.309 +     * <p>The returned map will throw an {@code IllegalArgumentException}
  26.310 +     * on an attempt to insert a key outside of its range, or to construct a
  26.311 +     * submap either of whose endpoints lie outside its range.
  26.312 +     *
  26.313 +     * @param fromKey low endpoint of the keys in the returned map
  26.314 +     * @param fromInclusive {@code true} if the low endpoint
  26.315 +     *        is to be included in the returned view
  26.316 +     * @param toKey high endpoint of the keys in the returned map
  26.317 +     * @param toInclusive {@code true} if the high endpoint
  26.318 +     *        is to be included in the returned view
  26.319 +     * @return a view of the portion of this map whose keys range from
  26.320 +     *         {@code fromKey} to {@code toKey}
  26.321 +     * @throws ClassCastException if {@code fromKey} and {@code toKey}
  26.322 +     *         cannot be compared to one another using this map's comparator
  26.323 +     *         (or, if the map has no comparator, using natural ordering).
  26.324 +     *         Implementations may, but are not required to, throw this
  26.325 +     *         exception if {@code fromKey} or {@code toKey}
  26.326 +     *         cannot be compared to keys currently in the map.
  26.327 +     * @throws NullPointerException if {@code fromKey} or {@code toKey}
  26.328 +     *         is null and this map does not permit null keys
  26.329 +     * @throws IllegalArgumentException if {@code fromKey} is greater than
  26.330 +     *         {@code toKey}; or if this map itself has a restricted
  26.331 +     *         range, and {@code fromKey} or {@code toKey} lies
  26.332 +     *         outside the bounds of the range
  26.333 +     */
  26.334 +    NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
  26.335 +                             K toKey,   boolean toInclusive);
  26.336 +
  26.337 +    /**
  26.338 +     * Returns a view of the portion of this map whose keys are less than (or
  26.339 +     * equal to, if {@code inclusive} is true) {@code toKey}.  The returned
  26.340 +     * map is backed by this map, so changes in the returned map are reflected
  26.341 +     * in this map, and vice-versa.  The returned map supports all optional
  26.342 +     * map operations that this map supports.
  26.343 +     *
  26.344 +     * <p>The returned map will throw an {@code IllegalArgumentException}
  26.345 +     * on an attempt to insert a key outside its range.
  26.346 +     *
  26.347 +     * @param toKey high endpoint of the keys in the returned map
  26.348 +     * @param inclusive {@code true} if the high endpoint
  26.349 +     *        is to be included in the returned view
  26.350 +     * @return a view of the portion of this map whose keys are less than
  26.351 +     *         (or equal to, if {@code inclusive} is true) {@code toKey}
  26.352 +     * @throws ClassCastException if {@code toKey} is not compatible
  26.353 +     *         with this map's comparator (or, if the map has no comparator,
  26.354 +     *         if {@code toKey} does not implement {@link Comparable}).
  26.355 +     *         Implementations may, but are not required to, throw this
  26.356 +     *         exception if {@code toKey} cannot be compared to keys
  26.357 +     *         currently in the map.
  26.358 +     * @throws NullPointerException if {@code toKey} is null
  26.359 +     *         and this map does not permit null keys
  26.360 +     * @throws IllegalArgumentException if this map itself has a
  26.361 +     *         restricted range, and {@code toKey} lies outside the
  26.362 +     *         bounds of the range
  26.363 +     */
  26.364 +    NavigableMap<K,V> headMap(K toKey, boolean inclusive);
  26.365 +
  26.366 +    /**
  26.367 +     * Returns a view of the portion of this map whose keys are greater than (or
  26.368 +     * equal to, if {@code inclusive} is true) {@code fromKey}.  The returned
  26.369 +     * map is backed by this map, so changes in the returned map are reflected
  26.370 +     * in this map, and vice-versa.  The returned map supports all optional
  26.371 +     * map operations that this map supports.
  26.372 +     *
  26.373 +     * <p>The returned map will throw an {@code IllegalArgumentException}
  26.374 +     * on an attempt to insert a key outside its range.
  26.375 +     *
  26.376 +     * @param fromKey low endpoint of the keys in the returned map
  26.377 +     * @param inclusive {@code true} if the low endpoint
  26.378 +     *        is to be included in the returned view
  26.379 +     * @return a view of the portion of this map whose keys are greater than
  26.380 +     *         (or equal to, if {@code inclusive} is true) {@code fromKey}
  26.381 +     * @throws ClassCastException if {@code fromKey} is not compatible
  26.382 +     *         with this map's comparator (or, if the map has no comparator,
  26.383 +     *         if {@code fromKey} does not implement {@link Comparable}).
  26.384 +     *         Implementations may, but are not required to, throw this
  26.385 +     *         exception if {@code fromKey} cannot be compared to keys
  26.386 +     *         currently in the map.
  26.387 +     * @throws NullPointerException if {@code fromKey} is null
  26.388 +     *         and this map does not permit null keys
  26.389 +     * @throws IllegalArgumentException if this map itself has a
  26.390 +     *         restricted range, and {@code fromKey} lies outside the
  26.391 +     *         bounds of the range
  26.392 +     */
  26.393 +    NavigableMap<K,V> tailMap(K fromKey, boolean inclusive);
  26.394 +
  26.395 +    /**
  26.396 +     * {@inheritDoc}
  26.397 +     *
  26.398 +     * <p>Equivalent to {@code subMap(fromKey, true, toKey, false)}.
  26.399 +     *
  26.400 +     * @throws ClassCastException       {@inheritDoc}
  26.401 +     * @throws NullPointerException     {@inheritDoc}
  26.402 +     * @throws IllegalArgumentException {@inheritDoc}
  26.403 +     */
  26.404 +    SortedMap<K,V> subMap(K fromKey, K toKey);
  26.405 +
  26.406 +    /**
  26.407 +     * {@inheritDoc}
  26.408 +     *
  26.409 +     * <p>Equivalent to {@code headMap(toKey, false)}.
  26.410 +     *
  26.411 +     * @throws ClassCastException       {@inheritDoc}
  26.412 +     * @throws NullPointerException     {@inheritDoc}
  26.413 +     * @throws IllegalArgumentException {@inheritDoc}
  26.414 +     */
  26.415 +    SortedMap<K,V> headMap(K toKey);
  26.416 +
  26.417 +    /**
  26.418 +     * {@inheritDoc}
  26.419 +     *
  26.420 +     * <p>Equivalent to {@code tailMap(fromKey, true)}.
  26.421 +     *
  26.422 +     * @throws ClassCastException       {@inheritDoc}
  26.423 +     * @throws NullPointerException     {@inheritDoc}
  26.424 +     * @throws IllegalArgumentException {@inheritDoc}
  26.425 +     */
  26.426 +    SortedMap<K,V> tailMap(K fromKey);
  26.427 +}
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/rt/emul/compact/src/main/java/java/util/NavigableSet.java	Sat Sep 07 13:55:09 2013 +0200
    27.3 @@ -0,0 +1,319 @@
    27.4 +/*
    27.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    27.6 + *
    27.7 + * This code is free software; you can redistribute it and/or modify it
    27.8 + * under the terms of the GNU General Public License version 2 only, as
    27.9 + * published by the Free Software Foundation.  Oracle designates this
   27.10 + * particular file as subject to the "Classpath" exception as provided
   27.11 + * by Oracle in the LICENSE file that accompanied this code.
   27.12 + *
   27.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   27.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   27.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   27.16 + * version 2 for more details (a copy is included in the LICENSE file that
   27.17 + * accompanied this code).
   27.18 + *
   27.19 + * You should have received a copy of the GNU General Public License version
   27.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   27.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   27.22 + *
   27.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   27.24 + * or visit www.oracle.com if you need additional information or have any
   27.25 + * questions.
   27.26 + */
   27.27 +
   27.28 +/*
   27.29 + * This file is available under and governed by the GNU General Public
   27.30 + * License version 2 only, as published by the Free Software Foundation.
   27.31 + * However, the following notice accompanied the original version of this
   27.32 + * file:
   27.33 + *
   27.34 + * Written by Doug Lea and Josh Bloch with assistance from members of JCP
   27.35 + * JSR-166 Expert Group and released to the public domain, as explained at
   27.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   27.37 + */
   27.38 +
   27.39 +package java.util;
   27.40 +
   27.41 +/**
   27.42 + * A {@link SortedSet} extended with navigation methods reporting
   27.43 + * closest matches for given search targets. Methods {@code lower},
   27.44 + * {@code floor}, {@code ceiling}, and {@code higher} return elements
   27.45 + * respectively less than, less than or equal, greater than or equal,
   27.46 + * and greater than a given element, returning {@code null} if there
   27.47 + * is no such element.  A {@code NavigableSet} may be accessed and
   27.48 + * traversed in either ascending or descending order.  The {@code
   27.49 + * descendingSet} method returns a view of the set with the senses of
   27.50 + * all relational and directional methods inverted. The performance of
   27.51 + * ascending operations and views is likely to be faster than that of
   27.52 + * descending ones.  This interface additionally defines methods
   27.53 + * {@code pollFirst} and {@code pollLast} that return and remove the
   27.54 + * lowest and highest element, if one exists, else returning {@code
   27.55 + * null}.  Methods {@code subSet}, {@code headSet},
   27.56 + * and {@code tailSet} differ from the like-named {@code
   27.57 + * SortedSet} methods in accepting additional arguments describing
   27.58 + * whether lower and upper bounds are inclusive versus exclusive.
   27.59 + * Subsets of any {@code NavigableSet} must implement the {@code
   27.60 + * NavigableSet} interface.
   27.61 + *
   27.62 + * <p> The return values of navigation methods may be ambiguous in
   27.63 + * implementations that permit {@code null} elements. However, even
   27.64 + * in this case the result can be disambiguated by checking
   27.65 + * {@code contains(null)}. To avoid such issues, implementations of
   27.66 + * this interface are encouraged to <em>not</em> permit insertion of
   27.67 + * {@code null} elements. (Note that sorted sets of {@link
   27.68 + * Comparable} elements intrinsically do not permit {@code null}.)
   27.69 + *
   27.70 + * <p>Methods
   27.71 + * {@link #subSet(Object, Object) subSet(E, E)},
   27.72 + * {@link #headSet(Object) headSet(E)}, and
   27.73 + * {@link #tailSet(Object) tailSet(E)}
   27.74 + * are specified to return {@code SortedSet} to allow existing
   27.75 + * implementations of {@code SortedSet} to be compatibly retrofitted to
   27.76 + * implement {@code NavigableSet}, but extensions and implementations
   27.77 + * of this interface are encouraged to override these methods to return
   27.78 + * {@code NavigableSet}.
   27.79 + *
   27.80 + * <p>This interface is a member of the
   27.81 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   27.82 + * Java Collections Framework</a>.
   27.83 + *
   27.84 + * @author Doug Lea
   27.85 + * @author Josh Bloch
   27.86 + * @param <E> the type of elements maintained by this set
   27.87 + * @since 1.6
   27.88 + */
   27.89 +public interface NavigableSet<E> extends SortedSet<E> {
   27.90 +    /**
   27.91 +     * Returns the greatest element in this set strictly less than the
   27.92 +     * given element, or {@code null} if there is no such element.
   27.93 +     *
   27.94 +     * @param e the value to match
   27.95 +     * @return the greatest element less than {@code e},
   27.96 +     *         or {@code null} if there is no such element
   27.97 +     * @throws ClassCastException if the specified element cannot be
   27.98 +     *         compared with the elements currently in the set
   27.99 +     * @throws NullPointerException if the specified element is null
  27.100 +     *         and this set does not permit null elements
  27.101 +     */
  27.102 +    E lower(E e);
  27.103 +
  27.104 +    /**
  27.105 +     * Returns the greatest element in this set less than or equal to
  27.106 +     * the given element, or {@code null} if there is no such element.
  27.107 +     *
  27.108 +     * @param e the value to match
  27.109 +     * @return the greatest element less than or equal to {@code e},
  27.110 +     *         or {@code null} if there is no such element
  27.111 +     * @throws ClassCastException if the specified element cannot be
  27.112 +     *         compared with the elements currently in the set
  27.113 +     * @throws NullPointerException if the specified element is null
  27.114 +     *         and this set does not permit null elements
  27.115 +     */
  27.116 +    E floor(E e);
  27.117 +
  27.118 +    /**
  27.119 +     * Returns the least element in this set greater than or equal to
  27.120 +     * the given element, or {@code null} if there is no such element.
  27.121 +     *
  27.122 +     * @param e the value to match
  27.123 +     * @return the least element greater than or equal to {@code e},
  27.124 +     *         or {@code null} if there is no such element
  27.125 +     * @throws ClassCastException if the specified element cannot be
  27.126 +     *         compared with the elements currently in the set
  27.127 +     * @throws NullPointerException if the specified element is null
  27.128 +     *         and this set does not permit null elements
  27.129 +     */
  27.130 +    E ceiling(E e);
  27.131 +
  27.132 +    /**
  27.133 +     * Returns the least element in this set strictly greater than the
  27.134 +     * given element, or {@code null} if there is no such element.
  27.135 +     *
  27.136 +     * @param e the value to match
  27.137 +     * @return the least element greater than {@code e},
  27.138 +     *         or {@code null} if there is no such element
  27.139 +     * @throws ClassCastException if the specified element cannot be
  27.140 +     *         compared with the elements currently in the set
  27.141 +     * @throws NullPointerException if the specified element is null
  27.142 +     *         and this set does not permit null elements
  27.143 +     */
  27.144 +    E higher(E e);
  27.145 +
  27.146 +    /**
  27.147 +     * Retrieves and removes the first (lowest) element,
  27.148 +     * or returns {@code null} if this set is empty.
  27.149 +     *
  27.150 +     * @return the first element, or {@code null} if this set is empty
  27.151 +     */
  27.152 +    E pollFirst();
  27.153 +
  27.154 +    /**
  27.155 +     * Retrieves and removes the last (highest) element,
  27.156 +     * or returns {@code null} if this set is empty.
  27.157 +     *
  27.158 +     * @return the last element, or {@code null} if this set is empty
  27.159 +     */
  27.160 +    E pollLast();
  27.161 +
  27.162 +    /**
  27.163 +     * Returns an iterator over the elements in this set, in ascending order.
  27.164 +     *
  27.165 +     * @return an iterator over the elements in this set, in ascending order
  27.166 +     */
  27.167 +    Iterator<E> iterator();
  27.168 +
  27.169 +    /**
  27.170 +     * Returns a reverse order view of the elements contained in this set.
  27.171 +     * The descending set is backed by this set, so changes to the set are
  27.172 +     * reflected in the descending set, and vice-versa.  If either set is
  27.173 +     * modified while an iteration over either set is in progress (except
  27.174 +     * through the iterator's own {@code remove} operation), the results of
  27.175 +     * the iteration are undefined.
  27.176 +     *
  27.177 +     * <p>The returned set has an ordering equivalent to
  27.178 +     * <tt>{@link Collections#reverseOrder(Comparator) Collections.reverseOrder}(comparator())</tt>.
  27.179 +     * The expression {@code s.descendingSet().descendingSet()} returns a
  27.180 +     * view of {@code s} essentially equivalent to {@code s}.
  27.181 +     *
  27.182 +     * @return a reverse order view of this set
  27.183 +     */
  27.184 +    NavigableSet<E> descendingSet();
  27.185 +
  27.186 +    /**
  27.187 +     * Returns an iterator over the elements in this set, in descending order.
  27.188 +     * Equivalent in effect to {@code descendingSet().iterator()}.
  27.189 +     *
  27.190 +     * @return an iterator over the elements in this set, in descending order
  27.191 +     */
  27.192 +    Iterator<E> descendingIterator();
  27.193 +
  27.194 +    /**
  27.195 +     * Returns a view of the portion of this set whose elements range from
  27.196 +     * {@code fromElement} to {@code toElement}.  If {@code fromElement} and
  27.197 +     * {@code toElement} are equal, the returned set is empty unless {@code
  27.198 +     * fromInclusive} and {@code toInclusive} are both true.  The returned set
  27.199 +     * is backed by this set, so changes in the returned set are reflected in
  27.200 +     * this set, and vice-versa.  The returned set supports all optional set
  27.201 +     * operations that this set supports.
  27.202 +     *
  27.203 +     * <p>The returned set will throw an {@code IllegalArgumentException}
  27.204 +     * on an attempt to insert an element outside its range.
  27.205 +     *
  27.206 +     * @param fromElement low endpoint of the returned set
  27.207 +     * @param fromInclusive {@code true} if the low endpoint
  27.208 +     *        is to be included in the returned view
  27.209 +     * @param toElement high endpoint of the returned set
  27.210 +     * @param toInclusive {@code true} if the high endpoint
  27.211 +     *        is to be included in the returned view
  27.212 +     * @return a view of the portion of this set whose elements range from
  27.213 +     *         {@code fromElement}, inclusive, to {@code toElement}, exclusive
  27.214 +     * @throws ClassCastException if {@code fromElement} and
  27.215 +     *         {@code toElement} cannot be compared to one another using this
  27.216 +     *         set's comparator (or, if the set has no comparator, using
  27.217 +     *         natural ordering).  Implementations may, but are not required
  27.218 +     *         to, throw this exception if {@code fromElement} or
  27.219 +     *         {@code toElement} cannot be compared to elements currently in
  27.220 +     *         the set.
  27.221 +     * @throws NullPointerException if {@code fromElement} or
  27.222 +     *         {@code toElement} is null and this set does
  27.223 +     *         not permit null elements
  27.224 +     * @throws IllegalArgumentException if {@code fromElement} is
  27.225 +     *         greater than {@code toElement}; or if this set itself
  27.226 +     *         has a restricted range, and {@code fromElement} or
  27.227 +     *         {@code toElement} lies outside the bounds of the range.
  27.228 +     */
  27.229 +    NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
  27.230 +                           E toElement,   boolean toInclusive);
  27.231 +
  27.232 +    /**
  27.233 +     * Returns a view of the portion of this set whose elements are less than
  27.234 +     * (or equal to, if {@code inclusive} is true) {@code toElement}.  The
  27.235 +     * returned set is backed by this set, so changes in the returned set are
  27.236 +     * reflected in this set, and vice-versa.  The returned set supports all
  27.237 +     * optional set operations that this set supports.
  27.238 +     *
  27.239 +     * <p>The returned set will throw an {@code IllegalArgumentException}
  27.240 +     * on an attempt to insert an element outside its range.
  27.241 +     *
  27.242 +     * @param toElement high endpoint of the returned set
  27.243 +     * @param inclusive {@code true} if the high endpoint
  27.244 +     *        is to be included in the returned view
  27.245 +     * @return a view of the portion of this set whose elements are less than
  27.246 +     *         (or equal to, if {@code inclusive} is true) {@code toElement}
  27.247 +     * @throws ClassCastException if {@code toElement} is not compatible
  27.248 +     *         with this set's comparator (or, if the set has no comparator,
  27.249 +     *         if {@code toElement} does not implement {@link Comparable}).
  27.250 +     *         Implementations may, but are not required to, throw this
  27.251 +     *         exception if {@code toElement} cannot be compared to elements
  27.252 +     *         currently in the set.
  27.253 +     * @throws NullPointerException if {@code toElement} is null and
  27.254 +     *         this set does not permit null elements
  27.255 +     * @throws IllegalArgumentException if this set itself has a
  27.256 +     *         restricted range, and {@code toElement} lies outside the
  27.257 +     *         bounds of the range
  27.258 +     */
  27.259 +    NavigableSet<E> headSet(E toElement, boolean inclusive);
  27.260 +
  27.261 +    /**
  27.262 +     * Returns a view of the portion of this set whose elements are greater
  27.263 +     * than (or equal to, if {@code inclusive} is true) {@code fromElement}.
  27.264 +     * The returned set is backed by this set, so changes in the returned set
  27.265 +     * are reflected in this set, and vice-versa.  The returned set supports
  27.266 +     * all optional set operations that this set supports.
  27.267 +     *
  27.268 +     * <p>The returned set will throw an {@code IllegalArgumentException}
  27.269 +     * on an attempt to insert an element outside its range.
  27.270 +     *
  27.271 +     * @param fromElement low endpoint of the returned set
  27.272 +     * @param inclusive {@code true} if the low endpoint
  27.273 +     *        is to be included in the returned view
  27.274 +     * @return a view of the portion of this set whose elements are greater
  27.275 +     *         than or equal to {@code fromElement}
  27.276 +     * @throws ClassCastException if {@code fromElement} is not compatible
  27.277 +     *         with this set's comparator (or, if the set has no comparator,
  27.278 +     *         if {@code fromElement} does not implement {@link Comparable}).
  27.279 +     *         Implementations may, but are not required to, throw this
  27.280 +     *         exception if {@code fromElement} cannot be compared to elements
  27.281 +     *         currently in the set.
  27.282 +     * @throws NullPointerException if {@code fromElement} is null
  27.283 +     *         and this set does not permit null elements
  27.284 +     * @throws IllegalArgumentException if this set itself has a
  27.285 +     *         restricted range, and {@code fromElement} lies outside the
  27.286 +     *         bounds of the range
  27.287 +     */
  27.288 +    NavigableSet<E> tailSet(E fromElement, boolean inclusive);
  27.289 +
  27.290 +    /**
  27.291 +     * {@inheritDoc}
  27.292 +     *
  27.293 +     * <p>Equivalent to {@code subSet(fromElement, true, toElement, false)}.
  27.294 +     *
  27.295 +     * @throws ClassCastException       {@inheritDoc}
  27.296 +     * @throws NullPointerException     {@inheritDoc}
  27.297 +     * @throws IllegalArgumentException {@inheritDoc}
  27.298 +     */
  27.299 +    SortedSet<E> subSet(E fromElement, E toElement);
  27.300 +
  27.301 +    /**
  27.302 +     * {@inheritDoc}
  27.303 +     *
  27.304 +     * <p>Equivalent to {@code headSet(toElement, false)}.
  27.305 +     *
  27.306 +     * @throws ClassCastException       {@inheritDoc}
  27.307 +     * @throws NullPointerException     {@inheritDoc}
  27.308 +     * @throws IllegalArgumentException {@inheritDoc}
  27.309 +na     */
  27.310 +    SortedSet<E> headSet(E toElement);
  27.311 +
  27.312 +    /**
  27.313 +     * {@inheritDoc}
  27.314 +     *
  27.315 +     * <p>Equivalent to {@code tailSet(fromElement, true)}.
  27.316 +     *
  27.317 +     * @throws ClassCastException       {@inheritDoc}
  27.318 +     * @throws NullPointerException     {@inheritDoc}
  27.319 +     * @throws IllegalArgumentException {@inheritDoc}
  27.320 +     */
  27.321 +    SortedSet<E> tailSet(E fromElement);
  27.322 +}
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/rt/emul/compact/src/main/java/java/util/TreeMap.java	Sat Sep 07 13:55:09 2013 +0200
    28.3 @@ -0,0 +1,2442 @@
    28.4 +/*
    28.5 + * Copyright (c) 1997, 2011, 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.util;
   28.30 +
   28.31 +/**
   28.32 + * A Red-Black tree based {@link NavigableMap} implementation.
   28.33 + * The map is sorted according to the {@linkplain Comparable natural
   28.34 + * ordering} of its keys, or by a {@link Comparator} provided at map
   28.35 + * creation time, depending on which constructor is used.
   28.36 + *
   28.37 + * <p>This implementation provides guaranteed log(n) time cost for the
   28.38 + * {@code containsKey}, {@code get}, {@code put} and {@code remove}
   28.39 + * operations.  Algorithms are adaptations of those in Cormen, Leiserson, and
   28.40 + * Rivest's <em>Introduction to Algorithms</em>.
   28.41 + *
   28.42 + * <p>Note that the ordering maintained by a tree map, like any sorted map, and
   28.43 + * whether or not an explicit comparator is provided, must be <em>consistent
   28.44 + * with {@code equals}</em> if this sorted map is to correctly implement the
   28.45 + * {@code Map} interface.  (See {@code Comparable} or {@code Comparator} for a
   28.46 + * precise definition of <em>consistent with equals</em>.)  This is so because
   28.47 + * the {@code Map} interface is defined in terms of the {@code equals}
   28.48 + * operation, but a sorted map performs all key comparisons using its {@code
   28.49 + * compareTo} (or {@code compare}) method, so two keys that are deemed equal by
   28.50 + * this method are, from the standpoint of the sorted map, equal.  The behavior
   28.51 + * of a sorted map <em>is</em> well-defined even if its ordering is
   28.52 + * inconsistent with {@code equals}; it just fails to obey the general contract
   28.53 + * of the {@code Map} interface.
   28.54 + *
   28.55 + * <p><strong>Note that this implementation is not synchronized.</strong>
   28.56 + * If multiple threads access a map concurrently, and at least one of the
   28.57 + * threads modifies the map structurally, it <em>must</em> be synchronized
   28.58 + * externally.  (A structural modification is any operation that adds or
   28.59 + * deletes one or more mappings; merely changing the value associated
   28.60 + * with an existing key is not a structural modification.)  This is
   28.61 + * typically accomplished by synchronizing on some object that naturally
   28.62 + * encapsulates the map.
   28.63 + * If no such object exists, the map should be "wrapped" using the
   28.64 + * {@link Collections#synchronizedSortedMap Collections.synchronizedSortedMap}
   28.65 + * method.  This is best done at creation time, to prevent accidental
   28.66 + * unsynchronized access to the map: <pre>
   28.67 + *   SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));</pre>
   28.68 + *
   28.69 + * <p>The iterators returned by the {@code iterator} method of the collections
   28.70 + * returned by all of this class's "collection view methods" are
   28.71 + * <em>fail-fast</em>: if the map is structurally modified at any time after
   28.72 + * the iterator is created, in any way except through the iterator's own
   28.73 + * {@code remove} method, the iterator will throw a {@link
   28.74 + * ConcurrentModificationException}.  Thus, in the face of concurrent
   28.75 + * modification, the iterator fails quickly and cleanly, rather than risking
   28.76 + * arbitrary, non-deterministic behavior at an undetermined time in the future.
   28.77 + *
   28.78 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   28.79 + * as it is, generally speaking, impossible to make any hard guarantees in the
   28.80 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
   28.81 + * throw {@code ConcurrentModificationException} on a best-effort basis.
   28.82 + * Therefore, it would be wrong to write a program that depended on this
   28.83 + * exception for its correctness:   <em>the fail-fast behavior of iterators
   28.84 + * should be used only to detect bugs.</em>
   28.85 + *
   28.86 + * <p>All {@code Map.Entry} pairs returned by methods in this class
   28.87 + * and its views represent snapshots of mappings at the time they were
   28.88 + * produced. They do <strong>not</strong> support the {@code Entry.setValue}
   28.89 + * method. (Note however that it is possible to change mappings in the
   28.90 + * associated map using {@code put}.)
   28.91 + *
   28.92 + * <p>This class is a member of the
   28.93 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   28.94 + * Java Collections Framework</a>.
   28.95 + *
   28.96 + * @param <K> the type of keys maintained by this map
   28.97 + * @param <V> the type of mapped values
   28.98 + *
   28.99 + * @author  Josh Bloch and Doug Lea
  28.100 + * @see Map
  28.101 + * @see HashMap
  28.102 + * @see Hashtable
  28.103 + * @see Comparable
  28.104 + * @see Comparator
  28.105 + * @see Collection
  28.106 + * @since 1.2
  28.107 + */
  28.108 +
  28.109 +public class TreeMap<K,V>
  28.110 +    extends AbstractMap<K,V>
  28.111 +    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
  28.112 +{
  28.113 +    /**
  28.114 +     * The comparator used to maintain order in this tree map, or
  28.115 +     * null if it uses the natural ordering of its keys.
  28.116 +     *
  28.117 +     * @serial
  28.118 +     */
  28.119 +    private final Comparator<? super K> comparator;
  28.120 +
  28.121 +    private transient Entry<K,V> root = null;
  28.122 +
  28.123 +    /**
  28.124 +     * The number of entries in the tree
  28.125 +     */
  28.126 +    private transient int size = 0;
  28.127 +
  28.128 +    /**
  28.129 +     * The number of structural modifications to the tree.
  28.130 +     */
  28.131 +    private transient int modCount = 0;
  28.132 +
  28.133 +    /**
  28.134 +     * Constructs a new, empty tree map, using the natural ordering of its
  28.135 +     * keys.  All keys inserted into the map must implement the {@link
  28.136 +     * Comparable} interface.  Furthermore, all such keys must be
  28.137 +     * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
  28.138 +     * a {@code ClassCastException} for any keys {@code k1} and
  28.139 +     * {@code k2} in the map.  If the user attempts to put a key into the
  28.140 +     * map that violates this constraint (for example, the user attempts to
  28.141 +     * put a string key into a map whose keys are integers), the
  28.142 +     * {@code put(Object key, Object value)} call will throw a
  28.143 +     * {@code ClassCastException}.
  28.144 +     */
  28.145 +    public TreeMap() {
  28.146 +        comparator = null;
  28.147 +    }
  28.148 +
  28.149 +    /**
  28.150 +     * Constructs a new, empty tree map, ordered according to the given
  28.151 +     * comparator.  All keys inserted into the map must be <em>mutually
  28.152 +     * comparable</em> by the given comparator: {@code comparator.compare(k1,
  28.153 +     * k2)} must not throw a {@code ClassCastException} for any keys
  28.154 +     * {@code k1} and {@code k2} in the map.  If the user attempts to put
  28.155 +     * a key into the map that violates this constraint, the {@code put(Object
  28.156 +     * key, Object value)} call will throw a
  28.157 +     * {@code ClassCastException}.
  28.158 +     *
  28.159 +     * @param comparator the comparator that will be used to order this map.
  28.160 +     *        If {@code null}, the {@linkplain Comparable natural
  28.161 +     *        ordering} of the keys will be used.
  28.162 +     */
  28.163 +    public TreeMap(Comparator<? super K> comparator) {
  28.164 +        this.comparator = comparator;
  28.165 +    }
  28.166 +
  28.167 +    /**
  28.168 +     * Constructs a new tree map containing the same mappings as the given
  28.169 +     * map, ordered according to the <em>natural ordering</em> of its keys.
  28.170 +     * All keys inserted into the new map must implement the {@link
  28.171 +     * Comparable} interface.  Furthermore, all such keys must be
  28.172 +     * <em>mutually comparable</em>: {@code k1.compareTo(k2)} must not throw
  28.173 +     * a {@code ClassCastException} for any keys {@code k1} and
  28.174 +     * {@code k2} in the map.  This method runs in n*log(n) time.
  28.175 +     *
  28.176 +     * @param  m the map whose mappings are to be placed in this map
  28.177 +     * @throws ClassCastException if the keys in m are not {@link Comparable},
  28.178 +     *         or are not mutually comparable
  28.179 +     * @throws NullPointerException if the specified map is null
  28.180 +     */
  28.181 +    public TreeMap(Map<? extends K, ? extends V> m) {
  28.182 +        comparator = null;
  28.183 +        putAll(m);
  28.184 +    }
  28.185 +
  28.186 +    /**
  28.187 +     * Constructs a new tree map containing the same mappings and
  28.188 +     * using the same ordering as the specified sorted map.  This
  28.189 +     * method runs in linear time.
  28.190 +     *
  28.191 +     * @param  m the sorted map whose mappings are to be placed in this map,
  28.192 +     *         and whose comparator is to be used to sort this map
  28.193 +     * @throws NullPointerException if the specified map is null
  28.194 +     */
  28.195 +    public TreeMap(SortedMap<K, ? extends V> m) {
  28.196 +        comparator = m.comparator();
  28.197 +        try {
  28.198 +            buildFromSorted(m.size(), m.entrySet().iterator(), null, null);
  28.199 +        } catch (java.io.IOException cannotHappen) {
  28.200 +        } catch (ClassNotFoundException cannotHappen) {
  28.201 +        }
  28.202 +    }
  28.203 +
  28.204 +
  28.205 +    // Query Operations
  28.206 +
  28.207 +    /**
  28.208 +     * Returns the number of key-value mappings in this map.
  28.209 +     *
  28.210 +     * @return the number of key-value mappings in this map
  28.211 +     */
  28.212 +    public int size() {
  28.213 +        return size;
  28.214 +    }
  28.215 +
  28.216 +    /**
  28.217 +     * Returns {@code true} if this map contains a mapping for the specified
  28.218 +     * key.
  28.219 +     *
  28.220 +     * @param key key whose presence in this map is to be tested
  28.221 +     * @return {@code true} if this map contains a mapping for the
  28.222 +     *         specified key
  28.223 +     * @throws ClassCastException if the specified key cannot be compared
  28.224 +     *         with the keys currently in the map
  28.225 +     * @throws NullPointerException if the specified key is null
  28.226 +     *         and this map uses natural ordering, or its comparator
  28.227 +     *         does not permit null keys
  28.228 +     */
  28.229 +    public boolean containsKey(Object key) {
  28.230 +        return getEntry(key) != null;
  28.231 +    }
  28.232 +
  28.233 +    /**
  28.234 +     * Returns {@code true} if this map maps one or more keys to the
  28.235 +     * specified value.  More formally, returns {@code true} if and only if
  28.236 +     * this map contains at least one mapping to a value {@code v} such
  28.237 +     * that {@code (value==null ? v==null : value.equals(v))}.  This
  28.238 +     * operation will probably require time linear in the map size for
  28.239 +     * most implementations.
  28.240 +     *
  28.241 +     * @param value value whose presence in this map is to be tested
  28.242 +     * @return {@code true} if a mapping to {@code value} exists;
  28.243 +     *         {@code false} otherwise
  28.244 +     * @since 1.2
  28.245 +     */
  28.246 +    public boolean containsValue(Object value) {
  28.247 +        for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e))
  28.248 +            if (valEquals(value, e.value))
  28.249 +                return true;
  28.250 +        return false;
  28.251 +    }
  28.252 +
  28.253 +    /**
  28.254 +     * Returns the value to which the specified key is mapped,
  28.255 +     * or {@code null} if this map contains no mapping for the key.
  28.256 +     *
  28.257 +     * <p>More formally, if this map contains a mapping from a key
  28.258 +     * {@code k} to a value {@code v} such that {@code key} compares
  28.259 +     * equal to {@code k} according to the map's ordering, then this
  28.260 +     * method returns {@code v}; otherwise it returns {@code null}.
  28.261 +     * (There can be at most one such mapping.)
  28.262 +     *
  28.263 +     * <p>A return value of {@code null} does not <em>necessarily</em>
  28.264 +     * indicate that the map contains no mapping for the key; it's also
  28.265 +     * possible that the map explicitly maps the key to {@code null}.
  28.266 +     * The {@link #containsKey containsKey} operation may be used to
  28.267 +     * distinguish these two cases.
  28.268 +     *
  28.269 +     * @throws ClassCastException if the specified key cannot be compared
  28.270 +     *         with the keys currently in the map
  28.271 +     * @throws NullPointerException if the specified key is null
  28.272 +     *         and this map uses natural ordering, or its comparator
  28.273 +     *         does not permit null keys
  28.274 +     */
  28.275 +    public V get(Object key) {
  28.276 +        Entry<K,V> p = getEntry(key);
  28.277 +        return (p==null ? null : p.value);
  28.278 +    }
  28.279 +
  28.280 +    public Comparator<? super K> comparator() {
  28.281 +        return comparator;
  28.282 +    }
  28.283 +
  28.284 +    /**
  28.285 +     * @throws NoSuchElementException {@inheritDoc}
  28.286 +     */
  28.287 +    public K firstKey() {
  28.288 +        return key(getFirstEntry());
  28.289 +    }
  28.290 +
  28.291 +    /**
  28.292 +     * @throws NoSuchElementException {@inheritDoc}
  28.293 +     */
  28.294 +    public K lastKey() {
  28.295 +        return key(getLastEntry());
  28.296 +    }
  28.297 +
  28.298 +    /**
  28.299 +     * Copies all of the mappings from the specified map to this map.
  28.300 +     * These mappings replace any mappings that this map had for any
  28.301 +     * of the keys currently in the specified map.
  28.302 +     *
  28.303 +     * @param  map mappings to be stored in this map
  28.304 +     * @throws ClassCastException if the class of a key or value in
  28.305 +     *         the specified map prevents it from being stored in this map
  28.306 +     * @throws NullPointerException if the specified map is null or
  28.307 +     *         the specified map contains a null key and this map does not
  28.308 +     *         permit null keys
  28.309 +     */
  28.310 +    public void putAll(Map<? extends K, ? extends V> map) {
  28.311 +        int mapSize = map.size();
  28.312 +        if (size==0 && mapSize!=0 && map instanceof SortedMap) {
  28.313 +            Comparator c = ((SortedMap)map).comparator();
  28.314 +            if (c == comparator || (c != null && c.equals(comparator))) {
  28.315 +                ++modCount;
  28.316 +                try {
  28.317 +                    buildFromSorted(mapSize, map.entrySet().iterator(),
  28.318 +                                    null, null);
  28.319 +                } catch (java.io.IOException cannotHappen) {
  28.320 +                } catch (ClassNotFoundException cannotHappen) {
  28.321 +                }
  28.322 +                return;
  28.323 +            }
  28.324 +        }
  28.325 +        super.putAll(map);
  28.326 +    }
  28.327 +
  28.328 +    /**
  28.329 +     * Returns this map's entry for the given key, or {@code null} if the map
  28.330 +     * does not contain an entry for the key.
  28.331 +     *
  28.332 +     * @return this map's entry for the given key, or {@code null} if the map
  28.333 +     *         does not contain an entry for the key
  28.334 +     * @throws ClassCastException if the specified key cannot be compared
  28.335 +     *         with the keys currently in the map
  28.336 +     * @throws NullPointerException if the specified key is null
  28.337 +     *         and this map uses natural ordering, or its comparator
  28.338 +     *         does not permit null keys
  28.339 +     */
  28.340 +    final Entry<K,V> getEntry(Object key) {
  28.341 +        // Offload comparator-based version for sake of performance
  28.342 +        if (comparator != null)
  28.343 +            return getEntryUsingComparator(key);
  28.344 +        if (key == null)
  28.345 +            throw new NullPointerException();
  28.346 +        Comparable<? super K> k = (Comparable<? super K>) key;
  28.347 +        Entry<K,V> p = root;
  28.348 +        while (p != null) {
  28.349 +            int cmp = k.compareTo(p.key);
  28.350 +            if (cmp < 0)
  28.351 +                p = p.left;
  28.352 +            else if (cmp > 0)
  28.353 +                p = p.right;
  28.354 +            else
  28.355 +                return p;
  28.356 +        }
  28.357 +        return null;
  28.358 +    }
  28.359 +
  28.360 +    /**
  28.361 +     * Version of getEntry using comparator. Split off from getEntry
  28.362 +     * for performance. (This is not worth doing for most methods,
  28.363 +     * that are less dependent on comparator performance, but is
  28.364 +     * worthwhile here.)
  28.365 +     */
  28.366 +    final Entry<K,V> getEntryUsingComparator(Object key) {
  28.367 +        K k = (K) key;
  28.368 +        Comparator<? super K> cpr = comparator;
  28.369 +        if (cpr != null) {
  28.370 +            Entry<K,V> p = root;
  28.371 +            while (p != null) {
  28.372 +                int cmp = cpr.compare(k, p.key);
  28.373 +                if (cmp < 0)
  28.374 +                    p = p.left;
  28.375 +                else if (cmp > 0)
  28.376 +                    p = p.right;
  28.377 +                else
  28.378 +                    return p;
  28.379 +            }
  28.380 +        }
  28.381 +        return null;
  28.382 +    }
  28.383 +
  28.384 +    /**
  28.385 +     * Gets the entry corresponding to the specified key; if no such entry
  28.386 +     * exists, returns the entry for the least key greater than the specified
  28.387 +     * key; if no such entry exists (i.e., the greatest key in the Tree is less
  28.388 +     * than the specified key), returns {@code null}.
  28.389 +     */
  28.390 +    final Entry<K,V> getCeilingEntry(K key) {
  28.391 +        Entry<K,V> p = root;
  28.392 +        while (p != null) {
  28.393 +            int cmp = compare(key, p.key);
  28.394 +            if (cmp < 0) {
  28.395 +                if (p.left != null)
  28.396 +                    p = p.left;
  28.397 +                else
  28.398 +                    return p;
  28.399 +            } else if (cmp > 0) {
  28.400 +                if (p.right != null) {
  28.401 +                    p = p.right;
  28.402 +                } else {
  28.403 +                    Entry<K,V> parent = p.parent;
  28.404 +                    Entry<K,V> ch = p;
  28.405 +                    while (parent != null && ch == parent.right) {
  28.406 +                        ch = parent;
  28.407 +                        parent = parent.parent;
  28.408 +                    }
  28.409 +                    return parent;
  28.410 +                }
  28.411 +            } else
  28.412 +                return p;
  28.413 +        }
  28.414 +        return null;
  28.415 +    }
  28.416 +
  28.417 +    /**
  28.418 +     * Gets the entry corresponding to the specified key; if no such entry
  28.419 +     * exists, returns the entry for the greatest key less than the specified
  28.420 +     * key; if no such entry exists, returns {@code null}.
  28.421 +     */
  28.422 +    final Entry<K,V> getFloorEntry(K key) {
  28.423 +        Entry<K,V> p = root;
  28.424 +        while (p != null) {
  28.425 +            int cmp = compare(key, p.key);
  28.426 +            if (cmp > 0) {
  28.427 +                if (p.right != null)
  28.428 +                    p = p.right;
  28.429 +                else
  28.430 +                    return p;
  28.431 +            } else if (cmp < 0) {
  28.432 +                if (p.left != null) {
  28.433 +                    p = p.left;
  28.434 +                } else {
  28.435 +                    Entry<K,V> parent = p.parent;
  28.436 +                    Entry<K,V> ch = p;
  28.437 +                    while (parent != null && ch == parent.left) {
  28.438 +                        ch = parent;
  28.439 +                        parent = parent.parent;
  28.440 +                    }
  28.441 +                    return parent;
  28.442 +                }
  28.443 +            } else
  28.444 +                return p;
  28.445 +
  28.446 +        }
  28.447 +        return null;
  28.448 +    }
  28.449 +
  28.450 +    /**
  28.451 +     * Gets the entry for the least key greater than the specified
  28.452 +     * key; if no such entry exists, returns the entry for the least
  28.453 +     * key greater than the specified key; if no such entry exists
  28.454 +     * returns {@code null}.
  28.455 +     */
  28.456 +    final Entry<K,V> getHigherEntry(K key) {
  28.457 +        Entry<K,V> p = root;
  28.458 +        while (p != null) {
  28.459 +            int cmp = compare(key, p.key);
  28.460 +            if (cmp < 0) {
  28.461 +                if (p.left != null)
  28.462 +                    p = p.left;
  28.463 +                else
  28.464 +                    return p;
  28.465 +            } else {
  28.466 +                if (p.right != null) {
  28.467 +                    p = p.right;
  28.468 +                } else {
  28.469 +                    Entry<K,V> parent = p.parent;
  28.470 +                    Entry<K,V> ch = p;
  28.471 +                    while (parent != null && ch == parent.right) {
  28.472 +                        ch = parent;
  28.473 +                        parent = parent.parent;
  28.474 +                    }
  28.475 +                    return parent;
  28.476 +                }
  28.477 +            }
  28.478 +        }
  28.479 +        return null;
  28.480 +    }
  28.481 +
  28.482 +    /**
  28.483 +     * Returns the entry for the greatest key less than the specified key; if
  28.484 +     * no such entry exists (i.e., the least key in the Tree is greater than
  28.485 +     * the specified key), returns {@code null}.
  28.486 +     */
  28.487 +    final Entry<K,V> getLowerEntry(K key) {
  28.488 +        Entry<K,V> p = root;
  28.489 +        while (p != null) {
  28.490 +            int cmp = compare(key, p.key);
  28.491 +            if (cmp > 0) {
  28.492 +                if (p.right != null)
  28.493 +                    p = p.right;
  28.494 +                else
  28.495 +                    return p;
  28.496 +            } else {
  28.497 +                if (p.left != null) {
  28.498 +                    p = p.left;
  28.499 +                } else {
  28.500 +                    Entry<K,V> parent = p.parent;
  28.501 +                    Entry<K,V> ch = p;
  28.502 +                    while (parent != null && ch == parent.left) {
  28.503 +                        ch = parent;
  28.504 +                        parent = parent.parent;
  28.505 +                    }
  28.506 +                    return parent;
  28.507 +                }
  28.508 +            }
  28.509 +        }
  28.510 +        return null;
  28.511 +    }
  28.512 +
  28.513 +    /**
  28.514 +     * Associates the specified value with the specified key in this map.
  28.515 +     * If the map previously contained a mapping for the key, the old
  28.516 +     * value is replaced.
  28.517 +     *
  28.518 +     * @param key key with which the specified value is to be associated
  28.519 +     * @param value value to be associated with the specified key
  28.520 +     *
  28.521 +     * @return the previous value associated with {@code key}, or
  28.522 +     *         {@code null} if there was no mapping for {@code key}.
  28.523 +     *         (A {@code null} return can also indicate that the map
  28.524 +     *         previously associated {@code null} with {@code key}.)
  28.525 +     * @throws ClassCastException if the specified key cannot be compared
  28.526 +     *         with the keys currently in the map
  28.527 +     * @throws NullPointerException if the specified key is null
  28.528 +     *         and this map uses natural ordering, or its comparator
  28.529 +     *         does not permit null keys
  28.530 +     */
  28.531 +    public V put(K key, V value) {
  28.532 +        Entry<K,V> t = root;
  28.533 +        if (t == null) {
  28.534 +            compare(key, key); // type (and possibly null) check
  28.535 +
  28.536 +            root = new Entry<>(key, value, null);
  28.537 +            size = 1;
  28.538 +            modCount++;
  28.539 +            return null;
  28.540 +        }
  28.541 +        int cmp;
  28.542 +        Entry<K,V> parent;
  28.543 +        // split comparator and comparable paths
  28.544 +        Comparator<? super K> cpr = comparator;
  28.545 +        if (cpr != null) {
  28.546 +            do {
  28.547 +                parent = t;
  28.548 +                cmp = cpr.compare(key, t.key);
  28.549 +                if (cmp < 0)
  28.550 +                    t = t.left;
  28.551 +                else if (cmp > 0)
  28.552 +                    t = t.right;
  28.553 +                else
  28.554 +                    return t.setValue(value);
  28.555 +            } while (t != null);
  28.556 +        }
  28.557 +        else {
  28.558 +            if (key == null)
  28.559 +                throw new NullPointerException();
  28.560 +            Comparable<? super K> k = (Comparable<? super K>) key;
  28.561 +            do {
  28.562 +                parent = t;
  28.563 +                cmp = k.compareTo(t.key);
  28.564 +                if (cmp < 0)
  28.565 +                    t = t.left;
  28.566 +                else if (cmp > 0)
  28.567 +                    t = t.right;
  28.568 +                else
  28.569 +                    return t.setValue(value);
  28.570 +            } while (t != null);
  28.571 +        }
  28.572 +        Entry<K,V> e = new Entry<>(key, value, parent);
  28.573 +        if (cmp < 0)
  28.574 +            parent.left = e;
  28.575 +        else
  28.576 +            parent.right = e;
  28.577 +        fixAfterInsertion(e);
  28.578 +        size++;
  28.579 +        modCount++;
  28.580 +        return null;
  28.581 +    }
  28.582 +
  28.583 +    /**
  28.584 +     * Removes the mapping for this key from this TreeMap if present.
  28.585 +     *
  28.586 +     * @param  key key for which mapping should be removed
  28.587 +     * @return the previous value associated with {@code key}, or
  28.588 +     *         {@code null} if there was no mapping for {@code key}.
  28.589 +     *         (A {@code null} return can also indicate that the map
  28.590 +     *         previously associated {@code null} with {@code key}.)
  28.591 +     * @throws ClassCastException if the specified key cannot be compared
  28.592 +     *         with the keys currently in the map
  28.593 +     * @throws NullPointerException if the specified key is null
  28.594 +     *         and this map uses natural ordering, or its comparator
  28.595 +     *         does not permit null keys
  28.596 +     */
  28.597 +    public V remove(Object key) {
  28.598 +        Entry<K,V> p = getEntry(key);
  28.599 +        if (p == null)
  28.600 +            return null;
  28.601 +
  28.602 +        V oldValue = p.value;
  28.603 +        deleteEntry(p);
  28.604 +        return oldValue;
  28.605 +    }
  28.606 +
  28.607 +    /**
  28.608 +     * Removes all of the mappings from this map.
  28.609 +     * The map will be empty after this call returns.
  28.610 +     */
  28.611 +    public void clear() {
  28.612 +        modCount++;
  28.613 +        size = 0;
  28.614 +        root = null;
  28.615 +    }
  28.616 +
  28.617 +    /**
  28.618 +     * Returns a shallow copy of this {@code TreeMap} instance. (The keys and
  28.619 +     * values themselves are not cloned.)
  28.620 +     *
  28.621 +     * @return a shallow copy of this map
  28.622 +     */
  28.623 +    public Object clone() {
  28.624 +        TreeMap<K,V> clone = null;
  28.625 +        try {
  28.626 +            clone = (TreeMap<K,V>) super.clone();
  28.627 +        } catch (CloneNotSupportedException e) {
  28.628 +            throw new InternalError();
  28.629 +        }
  28.630 +
  28.631 +        // Put clone into "virgin" state (except for comparator)
  28.632 +        clone.root = null;
  28.633 +        clone.size = 0;
  28.634 +        clone.modCount = 0;
  28.635 +        clone.entrySet = null;
  28.636 +        clone.navigableKeySet = null;
  28.637 +        clone.descendingMap = null;
  28.638 +
  28.639 +        // Initialize clone with our mappings
  28.640 +        try {
  28.641 +            clone.buildFromSorted(size, entrySet().iterator(), null, null);
  28.642 +        } catch (java.io.IOException cannotHappen) {
  28.643 +        } catch (ClassNotFoundException cannotHappen) {
  28.644 +        }
  28.645 +
  28.646 +        return clone;
  28.647 +    }
  28.648 +
  28.649 +    // NavigableMap API methods
  28.650 +
  28.651 +    /**
  28.652 +     * @since 1.6
  28.653 +     */
  28.654 +    public Map.Entry<K,V> firstEntry() {
  28.655 +        return exportEntry(getFirstEntry());
  28.656 +    }
  28.657 +
  28.658 +    /**
  28.659 +     * @since 1.6
  28.660 +     */
  28.661 +    public Map.Entry<K,V> lastEntry() {
  28.662 +        return exportEntry(getLastEntry());
  28.663 +    }
  28.664 +
  28.665 +    /**
  28.666 +     * @since 1.6
  28.667 +     */
  28.668 +    public Map.Entry<K,V> pollFirstEntry() {
  28.669 +        Entry<K,V> p = getFirstEntry();
  28.670 +        Map.Entry<K,V> result = exportEntry(p);
  28.671 +        if (p != null)
  28.672 +            deleteEntry(p);
  28.673 +        return result;
  28.674 +    }
  28.675 +
  28.676 +    /**
  28.677 +     * @since 1.6
  28.678 +     */
  28.679 +    public Map.Entry<K,V> pollLastEntry() {
  28.680 +        Entry<K,V> p = getLastEntry();
  28.681 +        Map.Entry<K,V> result = exportEntry(p);
  28.682 +        if (p != null)
  28.683 +            deleteEntry(p);
  28.684 +        return result;
  28.685 +    }
  28.686 +
  28.687 +    /**
  28.688 +     * @throws ClassCastException {@inheritDoc}
  28.689 +     * @throws NullPointerException if the specified key is null
  28.690 +     *         and this map uses natural ordering, or its comparator
  28.691 +     *         does not permit null keys
  28.692 +     * @since 1.6
  28.693 +     */
  28.694 +    public Map.Entry<K,V> lowerEntry(K key) {
  28.695 +        return exportEntry(getLowerEntry(key));
  28.696 +    }
  28.697 +
  28.698 +    /**
  28.699 +     * @throws ClassCastException {@inheritDoc}
  28.700 +     * @throws NullPointerException if the specified key is null
  28.701 +     *         and this map uses natural ordering, or its comparator
  28.702 +     *         does not permit null keys
  28.703 +     * @since 1.6
  28.704 +     */
  28.705 +    public K lowerKey(K key) {
  28.706 +        return keyOrNull(getLowerEntry(key));
  28.707 +    }
  28.708 +
  28.709 +    /**
  28.710 +     * @throws ClassCastException {@inheritDoc}
  28.711 +     * @throws NullPointerException if the specified key is null
  28.712 +     *         and this map uses natural ordering, or its comparator
  28.713 +     *         does not permit null keys
  28.714 +     * @since 1.6
  28.715 +     */
  28.716 +    public Map.Entry<K,V> floorEntry(K key) {
  28.717 +        return exportEntry(getFloorEntry(key));
  28.718 +    }
  28.719 +
  28.720 +    /**
  28.721 +     * @throws ClassCastException {@inheritDoc}
  28.722 +     * @throws NullPointerException if the specified key is null
  28.723 +     *         and this map uses natural ordering, or its comparator
  28.724 +     *         does not permit null keys
  28.725 +     * @since 1.6
  28.726 +     */
  28.727 +    public K floorKey(K key) {
  28.728 +        return keyOrNull(getFloorEntry(key));
  28.729 +    }
  28.730 +
  28.731 +    /**
  28.732 +     * @throws ClassCastException {@inheritDoc}
  28.733 +     * @throws NullPointerException if the specified key is null
  28.734 +     *         and this map uses natural ordering, or its comparator
  28.735 +     *         does not permit null keys
  28.736 +     * @since 1.6
  28.737 +     */
  28.738 +    public Map.Entry<K,V> ceilingEntry(K key) {
  28.739 +        return exportEntry(getCeilingEntry(key));
  28.740 +    }
  28.741 +
  28.742 +    /**
  28.743 +     * @throws ClassCastException {@inheritDoc}
  28.744 +     * @throws NullPointerException if the specified key is null
  28.745 +     *         and this map uses natural ordering, or its comparator
  28.746 +     *         does not permit null keys
  28.747 +     * @since 1.6
  28.748 +     */
  28.749 +    public K ceilingKey(K key) {
  28.750 +        return keyOrNull(getCeilingEntry(key));
  28.751 +    }
  28.752 +
  28.753 +    /**
  28.754 +     * @throws ClassCastException {@inheritDoc}
  28.755 +     * @throws NullPointerException if the specified key is null
  28.756 +     *         and this map uses natural ordering, or its comparator
  28.757 +     *         does not permit null keys
  28.758 +     * @since 1.6
  28.759 +     */
  28.760 +    public Map.Entry<K,V> higherEntry(K key) {
  28.761 +        return exportEntry(getHigherEntry(key));
  28.762 +    }
  28.763 +
  28.764 +    /**
  28.765 +     * @throws ClassCastException {@inheritDoc}
  28.766 +     * @throws NullPointerException if the specified key is null
  28.767 +     *         and this map uses natural ordering, or its comparator
  28.768 +     *         does not permit null keys
  28.769 +     * @since 1.6
  28.770 +     */
  28.771 +    public K higherKey(K key) {
  28.772 +        return keyOrNull(getHigherEntry(key));
  28.773 +    }
  28.774 +
  28.775 +    // Views
  28.776 +
  28.777 +    /**
  28.778 +     * Fields initialized to contain an instance of the entry set view
  28.779 +     * the first time this view is requested.  Views are stateless, so
  28.780 +     * there's no reason to create more than one.
  28.781 +     */
  28.782 +    private transient EntrySet entrySet = null;
  28.783 +    private transient KeySet<K> navigableKeySet = null;
  28.784 +    private transient NavigableMap<K,V> descendingMap = null;
  28.785 +
  28.786 +    /**
  28.787 +     * Returns a {@link Set} view of the keys contained in this map.
  28.788 +     * The set's iterator returns the keys in ascending order.
  28.789 +     * The set is backed by the map, so changes to the map are
  28.790 +     * reflected in the set, and vice-versa.  If the map is modified
  28.791 +     * while an iteration over the set is in progress (except through
  28.792 +     * the iterator's own {@code remove} operation), the results of
  28.793 +     * the iteration are undefined.  The set supports element removal,
  28.794 +     * which removes the corresponding mapping from the map, via the
  28.795 +     * {@code Iterator.remove}, {@code Set.remove},
  28.796 +     * {@code removeAll}, {@code retainAll}, and {@code clear}
  28.797 +     * operations.  It does not support the {@code add} or {@code addAll}
  28.798 +     * operations.
  28.799 +     */
  28.800 +    public Set<K> keySet() {
  28.801 +        return navigableKeySet();
  28.802 +    }
  28.803 +
  28.804 +    /**
  28.805 +     * @since 1.6
  28.806 +     */
  28.807 +    public NavigableSet<K> navigableKeySet() {
  28.808 +        KeySet<K> nks = navigableKeySet;
  28.809 +        return (nks != null) ? nks : (navigableKeySet = new KeySet(this));
  28.810 +    }
  28.811 +
  28.812 +    /**
  28.813 +     * @since 1.6
  28.814 +     */
  28.815 +    public NavigableSet<K> descendingKeySet() {
  28.816 +        return descendingMap().navigableKeySet();
  28.817 +    }
  28.818 +
  28.819 +    /**
  28.820 +     * Returns a {@link Collection} view of the values contained in this map.
  28.821 +     * The collection's iterator returns the values in ascending order
  28.822 +     * of the corresponding keys.
  28.823 +     * The collection is backed by the map, so changes to the map are
  28.824 +     * reflected in the collection, and vice-versa.  If the map is
  28.825 +     * modified while an iteration over the collection is in progress
  28.826 +     * (except through the iterator's own {@code remove} operation),
  28.827 +     * the results of the iteration are undefined.  The collection
  28.828 +     * supports element removal, which removes the corresponding
  28.829 +     * mapping from the map, via the {@code Iterator.remove},
  28.830 +     * {@code Collection.remove}, {@code removeAll},
  28.831 +     * {@code retainAll} and {@code clear} operations.  It does not
  28.832 +     * support the {@code add} or {@code addAll} operations.
  28.833 +     */
  28.834 +    public Collection<V> values() {
  28.835 +        Collection<V> vs = values;
  28.836 +        return (vs != null) ? vs : (values = new Values());
  28.837 +    }
  28.838 +
  28.839 +    /**
  28.840 +     * Returns a {@link Set} view of the mappings contained in this map.
  28.841 +     * The set's iterator returns the entries in ascending key order.
  28.842 +     * The set is backed by the map, so changes to the map are
  28.843 +     * reflected in the set, and vice-versa.  If the map is modified
  28.844 +     * while an iteration over the set is in progress (except through
  28.845 +     * the iterator's own {@code remove} operation, or through the
  28.846 +     * {@code setValue} operation on a map entry returned by the
  28.847 +     * iterator) the results of the iteration are undefined.  The set
  28.848 +     * supports element removal, which removes the corresponding
  28.849 +     * mapping from the map, via the {@code Iterator.remove},
  28.850 +     * {@code Set.remove}, {@code removeAll}, {@code retainAll} and
  28.851 +     * {@code clear} operations.  It does not support the
  28.852 +     * {@code add} or {@code addAll} operations.
  28.853 +     */
  28.854 +    public Set<Map.Entry<K,V>> entrySet() {
  28.855 +        EntrySet es = entrySet;
  28.856 +        return (es != null) ? es : (entrySet = new EntrySet());
  28.857 +    }
  28.858 +
  28.859 +    /**
  28.860 +     * @since 1.6
  28.861 +     */
  28.862 +    public NavigableMap<K, V> descendingMap() {
  28.863 +        NavigableMap<K, V> km = descendingMap;
  28.864 +        return (km != null) ? km :
  28.865 +            (descendingMap = new DescendingSubMap(this,
  28.866 +                                                  true, null, true,
  28.867 +                                                  true, null, true));
  28.868 +    }
  28.869 +
  28.870 +    /**
  28.871 +     * @throws ClassCastException       {@inheritDoc}
  28.872 +     * @throws NullPointerException if {@code fromKey} or {@code toKey} is
  28.873 +     *         null and this map uses natural ordering, or its comparator
  28.874 +     *         does not permit null keys
  28.875 +     * @throws IllegalArgumentException {@inheritDoc}
  28.876 +     * @since 1.6
  28.877 +     */
  28.878 +    public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
  28.879 +                                    K toKey,   boolean toInclusive) {
  28.880 +        return new AscendingSubMap(this,
  28.881 +                                   false, fromKey, fromInclusive,
  28.882 +                                   false, toKey,   toInclusive);
  28.883 +    }
  28.884 +
  28.885 +    /**
  28.886 +     * @throws ClassCastException       {@inheritDoc}
  28.887 +     * @throws NullPointerException if {@code toKey} is null
  28.888 +     *         and this map uses natural ordering, or its comparator
  28.889 +     *         does not permit null keys
  28.890 +     * @throws IllegalArgumentException {@inheritDoc}
  28.891 +     * @since 1.6
  28.892 +     */
  28.893 +    public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
  28.894 +        return new AscendingSubMap(this,
  28.895 +                                   true,  null,  true,
  28.896 +                                   false, toKey, inclusive);
  28.897 +    }
  28.898 +
  28.899 +    /**
  28.900 +     * @throws ClassCastException       {@inheritDoc}
  28.901 +     * @throws NullPointerException if {@code fromKey} is null
  28.902 +     *         and this map uses natural ordering, or its comparator
  28.903 +     *         does not permit null keys
  28.904 +     * @throws IllegalArgumentException {@inheritDoc}
  28.905 +     * @since 1.6
  28.906 +     */
  28.907 +    public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
  28.908 +        return new AscendingSubMap(this,
  28.909 +                                   false, fromKey, inclusive,
  28.910 +                                   true,  null,    true);
  28.911 +    }
  28.912 +
  28.913 +    /**
  28.914 +     * @throws ClassCastException       {@inheritDoc}
  28.915 +     * @throws NullPointerException if {@code fromKey} or {@code toKey} is
  28.916 +     *         null and this map uses natural ordering, or its comparator
  28.917 +     *         does not permit null keys
  28.918 +     * @throws IllegalArgumentException {@inheritDoc}
  28.919 +     */
  28.920 +    public SortedMap<K,V> subMap(K fromKey, K toKey) {
  28.921 +        return subMap(fromKey, true, toKey, false);
  28.922 +    }
  28.923 +
  28.924 +    /**
  28.925 +     * @throws ClassCastException       {@inheritDoc}
  28.926 +     * @throws NullPointerException if {@code toKey} is null
  28.927 +     *         and this map uses natural ordering, or its comparator
  28.928 +     *         does not permit null keys
  28.929 +     * @throws IllegalArgumentException {@inheritDoc}
  28.930 +     */
  28.931 +    public SortedMap<K,V> headMap(K toKey) {
  28.932 +        return headMap(toKey, false);
  28.933 +    }
  28.934 +
  28.935 +    /**
  28.936 +     * @throws ClassCastException       {@inheritDoc}
  28.937 +     * @throws NullPointerException if {@code fromKey} is null
  28.938 +     *         and this map uses natural ordering, or its comparator
  28.939 +     *         does not permit null keys
  28.940 +     * @throws IllegalArgumentException {@inheritDoc}
  28.941 +     */
  28.942 +    public SortedMap<K,V> tailMap(K fromKey) {
  28.943 +        return tailMap(fromKey, true);
  28.944 +    }
  28.945 +
  28.946 +    // View class support
  28.947 +
  28.948 +    class Values extends AbstractCollection<V> {
  28.949 +        public Iterator<V> iterator() {
  28.950 +            return new ValueIterator(getFirstEntry());
  28.951 +        }
  28.952 +
  28.953 +        public int size() {
  28.954 +            return TreeMap.this.size();
  28.955 +        }
  28.956 +
  28.957 +        public boolean contains(Object o) {
  28.958 +            return TreeMap.this.containsValue(o);
  28.959 +        }
  28.960 +
  28.961 +        public boolean remove(Object o) {
  28.962 +            for (Entry<K,V> e = getFirstEntry(); e != null; e = successor(e)) {
  28.963 +                if (valEquals(e.getValue(), o)) {
  28.964 +                    deleteEntry(e);
  28.965 +                    return true;
  28.966 +                }
  28.967 +            }
  28.968 +            return false;
  28.969 +        }
  28.970 +
  28.971 +        public void clear() {
  28.972 +            TreeMap.this.clear();
  28.973 +        }
  28.974 +    }
  28.975 +
  28.976 +    class EntrySet extends AbstractSet<Map.Entry<K,V>> {
  28.977 +        public Iterator<Map.Entry<K,V>> iterator() {
  28.978 +            return new EntryIterator(getFirstEntry());
  28.979 +        }
  28.980 +
  28.981 +        public boolean contains(Object o) {
  28.982 +            if (!(o instanceof Map.Entry))
  28.983 +                return false;
  28.984 +            Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
  28.985 +            V value = entry.getValue();
  28.986 +            Entry<K,V> p = getEntry(entry.getKey());
  28.987 +            return p != null && valEquals(p.getValue(), value);
  28.988 +        }
  28.989 +
  28.990 +        public boolean remove(Object o) {
  28.991 +            if (!(o instanceof Map.Entry))
  28.992 +                return false;
  28.993 +            Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
  28.994 +            V value = entry.getValue();
  28.995 +            Entry<K,V> p = getEntry(entry.getKey());
  28.996 +            if (p != null && valEquals(p.getValue(), value)) {
  28.997 +                deleteEntry(p);
  28.998 +                return true;
  28.999 +            }
 28.1000 +            return false;
 28.1001 +        }
 28.1002 +
 28.1003 +        public int size() {
 28.1004 +            return TreeMap.this.size();
 28.1005 +        }
 28.1006 +
 28.1007 +        public void clear() {
 28.1008 +            TreeMap.this.clear();
 28.1009 +        }
 28.1010 +    }
 28.1011 +
 28.1012 +    /*
 28.1013 +     * Unlike Values and EntrySet, the KeySet class is static,
 28.1014 +     * delegating to a NavigableMap to allow use by SubMaps, which
 28.1015 +     * outweighs the ugliness of needing type-tests for the following
 28.1016 +     * Iterator methods that are defined appropriately in main versus
 28.1017 +     * submap classes.
 28.1018 +     */
 28.1019 +
 28.1020 +    Iterator<K> keyIterator() {
 28.1021 +        return new KeyIterator(getFirstEntry());
 28.1022 +    }
 28.1023 +
 28.1024 +    Iterator<K> descendingKeyIterator() {
 28.1025 +        return new DescendingKeyIterator(getLastEntry());
 28.1026 +    }
 28.1027 +
 28.1028 +    static final class KeySet<E> extends AbstractSet<E> implements NavigableSet<E> {
 28.1029 +        private final NavigableMap<E, Object> m;
 28.1030 +        KeySet(NavigableMap<E,Object> map) { m = map; }
 28.1031 +
 28.1032 +        public Iterator<E> iterator() {
 28.1033 +            if (m instanceof TreeMap)
 28.1034 +                return ((TreeMap<E,Object>)m).keyIterator();
 28.1035 +            else
 28.1036 +                return (Iterator<E>)(((TreeMap.NavigableSubMap)m).keyIterator());
 28.1037 +        }
 28.1038 +
 28.1039 +        public Iterator<E> descendingIterator() {
 28.1040 +            if (m instanceof TreeMap)
 28.1041 +                return ((TreeMap<E,Object>)m).descendingKeyIterator();
 28.1042 +            else
 28.1043 +                return (Iterator<E>)(((TreeMap.NavigableSubMap)m).descendingKeyIterator());
 28.1044 +        }
 28.1045 +
 28.1046 +        public int size() { return m.size(); }
 28.1047 +        public boolean isEmpty() { return m.isEmpty(); }
 28.1048 +        public boolean contains(Object o) { return m.containsKey(o); }
 28.1049 +        public void clear() { m.clear(); }
 28.1050 +        public E lower(E e) { return m.lowerKey(e); }
 28.1051 +        public E floor(E e) { return m.floorKey(e); }
 28.1052 +        public E ceiling(E e) { return m.ceilingKey(e); }
 28.1053 +        public E higher(E e) { return m.higherKey(e); }
 28.1054 +        public E first() { return m.firstKey(); }
 28.1055 +        public E last() { return m.lastKey(); }
 28.1056 +        public Comparator<? super E> comparator() { return m.comparator(); }
 28.1057 +        public E pollFirst() {
 28.1058 +            Map.Entry<E,Object> e = m.pollFirstEntry();
 28.1059 +            return (e == null) ? null : e.getKey();
 28.1060 +        }
 28.1061 +        public E pollLast() {
 28.1062 +            Map.Entry<E,Object> e = m.pollLastEntry();
 28.1063 +            return (e == null) ? null : e.getKey();
 28.1064 +        }
 28.1065 +        public boolean remove(Object o) {
 28.1066 +            int oldSize = size();
 28.1067 +            m.remove(o);
 28.1068 +            return size() != oldSize;
 28.1069 +        }
 28.1070 +        public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
 28.1071 +                                      E toElement,   boolean toInclusive) {
 28.1072 +            return new KeySet<>(m.subMap(fromElement, fromInclusive,
 28.1073 +                                          toElement,   toInclusive));
 28.1074 +        }
 28.1075 +        public NavigableSet<E> headSet(E toElement, boolean inclusive) {
 28.1076 +            return new KeySet<>(m.headMap(toElement, inclusive));
 28.1077 +        }
 28.1078 +        public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
 28.1079 +            return new KeySet<>(m.tailMap(fromElement, inclusive));
 28.1080 +        }
 28.1081 +        public SortedSet<E> subSet(E fromElement, E toElement) {
 28.1082 +            return subSet(fromElement, true, toElement, false);
 28.1083 +        }
 28.1084 +        public SortedSet<E> headSet(E toElement) {
 28.1085 +            return headSet(toElement, false);
 28.1086 +        }
 28.1087 +        public SortedSet<E> tailSet(E fromElement) {
 28.1088 +            return tailSet(fromElement, true);
 28.1089 +        }
 28.1090 +        public NavigableSet<E> descendingSet() {
 28.1091 +            return new KeySet(m.descendingMap());
 28.1092 +        }
 28.1093 +    }
 28.1094 +
 28.1095 +    /**
 28.1096 +     * Base class for TreeMap Iterators
 28.1097 +     */
 28.1098 +    abstract class PrivateEntryIterator<T> implements Iterator<T> {
 28.1099 +        Entry<K,V> next;
 28.1100 +        Entry<K,V> lastReturned;
 28.1101 +        int expectedModCount;
 28.1102 +
 28.1103 +        PrivateEntryIterator(Entry<K,V> first) {
 28.1104 +            expectedModCount = modCount;
 28.1105 +            lastReturned = null;
 28.1106 +            next = first;
 28.1107 +        }
 28.1108 +
 28.1109 +        public final boolean hasNext() {
 28.1110 +            return next != null;
 28.1111 +        }
 28.1112 +
 28.1113 +        final Entry<K,V> nextEntry() {
 28.1114 +            Entry<K,V> e = next;
 28.1115 +            if (e == null)
 28.1116 +                throw new NoSuchElementException();
 28.1117 +            if (modCount != expectedModCount)
 28.1118 +                throw new ConcurrentModificationException();
 28.1119 +            next = successor(e);
 28.1120 +            lastReturned = e;
 28.1121 +            return e;
 28.1122 +        }
 28.1123 +
 28.1124 +        final Entry<K,V> prevEntry() {
 28.1125 +            Entry<K,V> e = next;
 28.1126 +            if (e == null)
 28.1127 +                throw new NoSuchElementException();
 28.1128 +            if (modCount != expectedModCount)
 28.1129 +                throw new ConcurrentModificationException();
 28.1130 +            next = predecessor(e);
 28.1131 +            lastReturned = e;
 28.1132 +            return e;
 28.1133 +        }
 28.1134 +
 28.1135 +        public void remove() {
 28.1136 +            if (lastReturned == null)
 28.1137 +                throw new IllegalStateException();
 28.1138 +            if (modCount != expectedModCount)
 28.1139 +                throw new ConcurrentModificationException();
 28.1140 +            // deleted entries are replaced by their successors
 28.1141 +            if (lastReturned.left != null && lastReturned.right != null)
 28.1142 +                next = lastReturned;
 28.1143 +            deleteEntry(lastReturned);
 28.1144 +            expectedModCount = modCount;
 28.1145 +            lastReturned = null;
 28.1146 +        }
 28.1147 +    }
 28.1148 +
 28.1149 +    final class EntryIterator extends PrivateEntryIterator<Map.Entry<K,V>> {
 28.1150 +        EntryIterator(Entry<K,V> first) {
 28.1151 +            super(first);
 28.1152 +        }
 28.1153 +        public Map.Entry<K,V> next() {
 28.1154 +            return nextEntry();
 28.1155 +        }
 28.1156 +    }
 28.1157 +
 28.1158 +    final class ValueIterator extends PrivateEntryIterator<V> {
 28.1159 +        ValueIterator(Entry<K,V> first) {
 28.1160 +            super(first);
 28.1161 +        }
 28.1162 +        public V next() {
 28.1163 +            return nextEntry().value;
 28.1164 +        }
 28.1165 +    }
 28.1166 +
 28.1167 +    final class KeyIterator extends PrivateEntryIterator<K> {
 28.1168 +        KeyIterator(Entry<K,V> first) {
 28.1169 +            super(first);
 28.1170 +        }
 28.1171 +        public K next() {
 28.1172 +            return nextEntry().key;
 28.1173 +        }
 28.1174 +    }
 28.1175 +
 28.1176 +    final class DescendingKeyIterator extends PrivateEntryIterator<K> {
 28.1177 +        DescendingKeyIterator(Entry<K,V> first) {
 28.1178 +            super(first);
 28.1179 +        }
 28.1180 +        public K next() {
 28.1181 +            return prevEntry().key;
 28.1182 +        }
 28.1183 +    }
 28.1184 +
 28.1185 +    // Little utilities
 28.1186 +
 28.1187 +    /**
 28.1188 +     * Compares two keys using the correct comparison method for this TreeMap.
 28.1189 +     */
 28.1190 +    final int compare(Object k1, Object k2) {
 28.1191 +        return comparator==null ? ((Comparable<? super K>)k1).compareTo((K)k2)
 28.1192 +            : comparator.compare((K)k1, (K)k2);
 28.1193 +    }
 28.1194 +
 28.1195 +    /**
 28.1196 +     * Test two values for equality.  Differs from o1.equals(o2) only in
 28.1197 +     * that it copes with {@code null} o1 properly.
 28.1198 +     */
 28.1199 +    static final boolean valEquals(Object o1, Object o2) {
 28.1200 +        return (o1==null ? o2==null : o1.equals(o2));
 28.1201 +    }
 28.1202 +
 28.1203 +    /**
 28.1204 +     * Return SimpleImmutableEntry for entry, or null if null
 28.1205 +     */
 28.1206 +    static <K,V> Map.Entry<K,V> exportEntry(TreeMap.Entry<K,V> e) {
 28.1207 +        return (e == null) ? null :
 28.1208 +            new AbstractMap.SimpleImmutableEntry<>(e);
 28.1209 +    }
 28.1210 +
 28.1211 +    /**
 28.1212 +     * Return key for entry, or null if null
 28.1213 +     */
 28.1214 +    static <K,V> K keyOrNull(TreeMap.Entry<K,V> e) {
 28.1215 +        return (e == null) ? null : e.key;
 28.1216 +    }
 28.1217 +
 28.1218 +    /**
 28.1219 +     * Returns the key corresponding to the specified Entry.
 28.1220 +     * @throws NoSuchElementException if the Entry is null
 28.1221 +     */
 28.1222 +    static <K> K key(Entry<K,?> e) {
 28.1223 +        if (e==null)
 28.1224 +            throw new NoSuchElementException();
 28.1225 +        return e.key;
 28.1226 +    }
 28.1227 +
 28.1228 +
 28.1229 +    // SubMaps
 28.1230 +
 28.1231 +    /**
 28.1232 +     * Dummy value serving as unmatchable fence key for unbounded
 28.1233 +     * SubMapIterators
 28.1234 +     */
 28.1235 +    private static final Object UNBOUNDED = new Object();
 28.1236 +
 28.1237 +    /**
 28.1238 +     * @serial include
 28.1239 +     */
 28.1240 +    abstract static class NavigableSubMap<K,V> extends AbstractMap<K,V>
 28.1241 +        implements NavigableMap<K,V>, java.io.Serializable {
 28.1242 +        /**
 28.1243 +         * The backing map.
 28.1244 +         */
 28.1245 +        final TreeMap<K,V> m;
 28.1246 +
 28.1247 +        /**
 28.1248 +         * Endpoints are represented as triples (fromStart, lo,
 28.1249 +         * loInclusive) and (toEnd, hi, hiInclusive). If fromStart is
 28.1250 +         * true, then the low (absolute) bound is the start of the
 28.1251 +         * backing map, and the other values are ignored. Otherwise,
 28.1252 +         * if loInclusive is true, lo is the inclusive bound, else lo
 28.1253 +         * is the exclusive bound. Similarly for the upper bound.
 28.1254 +         */
 28.1255 +        final K lo, hi;
 28.1256 +        final boolean fromStart, toEnd;
 28.1257 +        final boolean loInclusive, hiInclusive;
 28.1258 +
 28.1259 +        NavigableSubMap(TreeMap<K,V> m,
 28.1260 +                        boolean fromStart, K lo, boolean loInclusive,
 28.1261 +                        boolean toEnd,     K hi, boolean hiInclusive) {
 28.1262 +            if (!fromStart && !toEnd) {
 28.1263 +                if (m.compare(lo, hi) > 0)
 28.1264 +                    throw new IllegalArgumentException("fromKey > toKey");
 28.1265 +            } else {
 28.1266 +                if (!fromStart) // type check
 28.1267 +                    m.compare(lo, lo);
 28.1268 +                if (!toEnd)
 28.1269 +                    m.compare(hi, hi);
 28.1270 +            }
 28.1271 +
 28.1272 +            this.m = m;
 28.1273 +            this.fromStart = fromStart;
 28.1274 +            this.lo = lo;
 28.1275 +            this.loInclusive = loInclusive;
 28.1276 +            this.toEnd = toEnd;
 28.1277 +            this.hi = hi;
 28.1278 +            this.hiInclusive = hiInclusive;
 28.1279 +        }
 28.1280 +
 28.1281 +        // internal utilities
 28.1282 +
 28.1283 +        final boolean tooLow(Object key) {
 28.1284 +            if (!fromStart) {
 28.1285 +                int c = m.compare(key, lo);
 28.1286 +                if (c < 0 || (c == 0 && !loInclusive))
 28.1287 +                    return true;
 28.1288 +            }
 28.1289 +            return false;
 28.1290 +        }
 28.1291 +
 28.1292 +        final boolean tooHigh(Object key) {
 28.1293 +            if (!toEnd) {
 28.1294 +                int c = m.compare(key, hi);
 28.1295 +                if (c > 0 || (c == 0 && !hiInclusive))
 28.1296 +                    return true;
 28.1297 +            }
 28.1298 +            return false;
 28.1299 +        }
 28.1300 +
 28.1301 +        final boolean inRange(Object key) {
 28.1302 +            return !tooLow(key) && !tooHigh(key);
 28.1303 +        }
 28.1304 +
 28.1305 +        final boolean inClosedRange(Object key) {
 28.1306 +            return (fromStart || m.compare(key, lo) >= 0)
 28.1307 +                && (toEnd || m.compare(hi, key) >= 0);
 28.1308 +        }
 28.1309 +
 28.1310 +        final boolean inRange(Object key, boolean inclusive) {
 28.1311 +            return inclusive ? inRange(key) : inClosedRange(key);
 28.1312 +        }
 28.1313 +
 28.1314 +        /*
 28.1315 +         * Absolute versions of relation operations.
 28.1316 +         * Subclasses map to these using like-named "sub"
 28.1317 +         * versions that invert senses for descending maps
 28.1318 +         */
 28.1319 +
 28.1320 +        final TreeMap.Entry<K,V> absLowest() {
 28.1321 +            TreeMap.Entry<K,V> e =
 28.1322 +                (fromStart ?  m.getFirstEntry() :
 28.1323 +                 (loInclusive ? m.getCeilingEntry(lo) :
 28.1324 +                                m.getHigherEntry(lo)));
 28.1325 +            return (e == null || tooHigh(e.key)) ? null : e;
 28.1326 +        }
 28.1327 +
 28.1328 +        final TreeMap.Entry<K,V> absHighest() {
 28.1329 +            TreeMap.Entry<K,V> e =
 28.1330 +                (toEnd ?  m.getLastEntry() :
 28.1331 +                 (hiInclusive ?  m.getFloorEntry(hi) :
 28.1332 +                                 m.getLowerEntry(hi)));
 28.1333 +            return (e == null || tooLow(e.key)) ? null : e;
 28.1334 +        }
 28.1335 +
 28.1336 +        final TreeMap.Entry<K,V> absCeiling(K key) {
 28.1337 +            if (tooLow(key))
 28.1338 +                return absLowest();
 28.1339 +            TreeMap.Entry<K,V> e = m.getCeilingEntry(key);
 28.1340 +            return (e == null || tooHigh(e.key)) ? null : e;
 28.1341 +        }
 28.1342 +
 28.1343 +        final TreeMap.Entry<K,V> absHigher(K key) {
 28.1344 +            if (tooLow(key))
 28.1345 +                return absLowest();
 28.1346 +            TreeMap.Entry<K,V> e = m.getHigherEntry(key);
 28.1347 +            return (e == null || tooHigh(e.key)) ? null : e;
 28.1348 +        }
 28.1349 +
 28.1350 +        final TreeMap.Entry<K,V> absFloor(K key) {
 28.1351 +            if (tooHigh(key))
 28.1352 +                return absHighest();
 28.1353 +            TreeMap.Entry<K,V> e = m.getFloorEntry(key);
 28.1354 +            return (e == null || tooLow(e.key)) ? null : e;
 28.1355 +        }
 28.1356 +
 28.1357 +        final TreeMap.Entry<K,V> absLower(K key) {
 28.1358 +            if (tooHigh(key))
 28.1359 +                return absHighest();
 28.1360 +            TreeMap.Entry<K,V> e = m.getLowerEntry(key);
 28.1361 +            return (e == null || tooLow(e.key)) ? null : e;
 28.1362 +        }
 28.1363 +
 28.1364 +        /** Returns the absolute high fence for ascending traversal */
 28.1365 +        final TreeMap.Entry<K,V> absHighFence() {
 28.1366 +            return (toEnd ? null : (hiInclusive ?
 28.1367 +                                    m.getHigherEntry(hi) :
 28.1368 +                                    m.getCeilingEntry(hi)));
 28.1369 +        }
 28.1370 +
 28.1371 +        /** Return the absolute low fence for descending traversal  */
 28.1372 +        final TreeMap.Entry<K,V> absLowFence() {
 28.1373 +            return (fromStart ? null : (loInclusive ?
 28.1374 +                                        m.getLowerEntry(lo) :
 28.1375 +                                        m.getFloorEntry(lo)));
 28.1376 +        }
 28.1377 +
 28.1378 +        // Abstract methods defined in ascending vs descending classes
 28.1379 +        // These relay to the appropriate absolute versions
 28.1380 +
 28.1381 +        abstract TreeMap.Entry<K,V> subLowest();
 28.1382 +        abstract TreeMap.Entry<K,V> subHighest();
 28.1383 +        abstract TreeMap.Entry<K,V> subCeiling(K key);
 28.1384 +        abstract TreeMap.Entry<K,V> subHigher(K key);
 28.1385 +        abstract TreeMap.Entry<K,V> subFloor(K key);
 28.1386 +        abstract TreeMap.Entry<K,V> subLower(K key);
 28.1387 +
 28.1388 +        /** Returns ascending iterator from the perspective of this submap */
 28.1389 +        abstract Iterator<K> keyIterator();
 28.1390 +
 28.1391 +        /** Returns descending iterator from the perspective of this submap */
 28.1392 +        abstract Iterator<K> descendingKeyIterator();
 28.1393 +
 28.1394 +        // public methods
 28.1395 +
 28.1396 +        public boolean isEmpty() {
 28.1397 +            return (fromStart && toEnd) ? m.isEmpty() : entrySet().isEmpty();
 28.1398 +        }
 28.1399 +
 28.1400 +        public int size() {
 28.1401 +            return (fromStart && toEnd) ? m.size() : entrySet().size();
 28.1402 +        }
 28.1403 +
 28.1404 +        public final boolean containsKey(Object key) {
 28.1405 +            return inRange(key) && m.containsKey(key);
 28.1406 +        }
 28.1407 +
 28.1408 +        public final V put(K key, V value) {
 28.1409 +            if (!inRange(key))
 28.1410 +                throw new IllegalArgumentException("key out of range");
 28.1411 +            return m.put(key, value);
 28.1412 +        }
 28.1413 +
 28.1414 +        public final V get(Object key) {
 28.1415 +            return !inRange(key) ? null :  m.get(key);
 28.1416 +        }
 28.1417 +
 28.1418 +        public final V remove(Object key) {
 28.1419 +            return !inRange(key) ? null : m.remove(key);
 28.1420 +        }
 28.1421 +
 28.1422 +        public final Map.Entry<K,V> ceilingEntry(K key) {
 28.1423 +            return exportEntry(subCeiling(key));
 28.1424 +        }
 28.1425 +
 28.1426 +        public final K ceilingKey(K key) {
 28.1427 +            return keyOrNull(subCeiling(key));
 28.1428 +        }
 28.1429 +
 28.1430 +        public final Map.Entry<K,V> higherEntry(K key) {
 28.1431 +            return exportEntry(subHigher(key));
 28.1432 +        }
 28.1433 +
 28.1434 +        public final K higherKey(K key) {
 28.1435 +            return keyOrNull(subHigher(key));
 28.1436 +        }
 28.1437 +
 28.1438 +        public final Map.Entry<K,V> floorEntry(K key) {
 28.1439 +            return exportEntry(subFloor(key));
 28.1440 +        }
 28.1441 +
 28.1442 +        public final K floorKey(K key) {
 28.1443 +            return keyOrNull(subFloor(key));
 28.1444 +        }
 28.1445 +
 28.1446 +        public final Map.Entry<K,V> lowerEntry(K key) {
 28.1447 +            return exportEntry(subLower(key));
 28.1448 +        }
 28.1449 +
 28.1450 +        public final K lowerKey(K key) {
 28.1451 +            return keyOrNull(subLower(key));
 28.1452 +        }
 28.1453 +
 28.1454 +        public final K firstKey() {
 28.1455 +            return key(subLowest());
 28.1456 +        }
 28.1457 +
 28.1458 +        public final K lastKey() {
 28.1459 +            return key(subHighest());
 28.1460 +        }
 28.1461 +
 28.1462 +        public final Map.Entry<K,V> firstEntry() {
 28.1463 +            return exportEntry(subLowest());
 28.1464 +        }
 28.1465 +
 28.1466 +        public final Map.Entry<K,V> lastEntry() {
 28.1467 +            return exportEntry(subHighest());
 28.1468 +        }
 28.1469 +
 28.1470 +        public final Map.Entry<K,V> pollFirstEntry() {
 28.1471 +            TreeMap.Entry<K,V> e = subLowest();
 28.1472 +            Map.Entry<K,V> result = exportEntry(e);
 28.1473 +            if (e != null)
 28.1474 +                m.deleteEntry(e);
 28.1475 +            return result;
 28.1476 +        }
 28.1477 +
 28.1478 +        public final Map.Entry<K,V> pollLastEntry() {
 28.1479 +            TreeMap.Entry<K,V> e = subHighest();
 28.1480 +            Map.Entry<K,V> result = exportEntry(e);
 28.1481 +            if (e != null)
 28.1482 +                m.deleteEntry(e);
 28.1483 +            return result;
 28.1484 +        }
 28.1485 +
 28.1486 +        // Views
 28.1487 +        transient NavigableMap<K,V> descendingMapView = null;
 28.1488 +        transient EntrySetView entrySetView = null;
 28.1489 +        transient KeySet<K> navigableKeySetView = null;
 28.1490 +
 28.1491 +        public final NavigableSet<K> navigableKeySet() {
 28.1492 +            KeySet<K> nksv = navigableKeySetView;
 28.1493 +            return (nksv != null) ? nksv :
 28.1494 +                (navigableKeySetView = new TreeMap.KeySet(this));
 28.1495 +        }
 28.1496 +
 28.1497 +        public final Set<K> keySet() {
 28.1498 +            return navigableKeySet();
 28.1499 +        }
 28.1500 +
 28.1501 +        public NavigableSet<K> descendingKeySet() {
 28.1502 +            return descendingMap().navigableKeySet();
 28.1503 +        }
 28.1504 +
 28.1505 +        public final SortedMap<K,V> subMap(K fromKey, K toKey) {
 28.1506 +            return subMap(fromKey, true, toKey, false);
 28.1507 +        }
 28.1508 +
 28.1509 +        public final SortedMap<K,V> headMap(K toKey) {
 28.1510 +            return headMap(toKey, false);
 28.1511 +        }
 28.1512 +
 28.1513 +        public final SortedMap<K,V> tailMap(K fromKey) {
 28.1514 +            return tailMap(fromKey, true);
 28.1515 +        }
 28.1516 +
 28.1517 +        // View classes
 28.1518 +
 28.1519 +        abstract class EntrySetView extends AbstractSet<Map.Entry<K,V>> {
 28.1520 +            private transient int size = -1, sizeModCount;
 28.1521 +
 28.1522 +            public int size() {
 28.1523 +                if (fromStart && toEnd)
 28.1524 +                    return m.size();
 28.1525 +                if (size == -1 || sizeModCount != m.modCount) {
 28.1526 +                    sizeModCount = m.modCount;
 28.1527 +                    size = 0;
 28.1528 +                    Iterator i = iterator();
 28.1529 +                    while (i.hasNext()) {
 28.1530 +                        size++;
 28.1531 +                        i.next();
 28.1532 +                    }
 28.1533 +                }
 28.1534 +                return size;
 28.1535 +            }
 28.1536 +
 28.1537 +            public boolean isEmpty() {
 28.1538 +                TreeMap.Entry<K,V> n = absLowest();
 28.1539 +                return n == null || tooHigh(n.key);
 28.1540 +            }
 28.1541 +
 28.1542 +            public boolean contains(Object o) {
 28.1543 +                if (!(o instanceof Map.Entry))
 28.1544 +                    return false;
 28.1545 +                Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
 28.1546 +                K key = entry.getKey();
 28.1547 +                if (!inRange(key))
 28.1548 +                    return false;
 28.1549 +                TreeMap.Entry node = m.getEntry(key);
 28.1550 +                return node != null &&
 28.1551 +                    valEquals(node.getValue(), entry.getValue());
 28.1552 +            }
 28.1553 +
 28.1554 +            public boolean remove(Object o) {
 28.1555 +                if (!(o instanceof Map.Entry))
 28.1556 +                    return false;
 28.1557 +                Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
 28.1558 +                K key = entry.getKey();
 28.1559 +                if (!inRange(key))
 28.1560 +                    return false;
 28.1561 +                TreeMap.Entry<K,V> node = m.getEntry(key);
 28.1562 +                if (node!=null && valEquals(node.getValue(),
 28.1563 +                                            entry.getValue())) {
 28.1564 +                    m.deleteEntry(node);
 28.1565 +                    return true;
 28.1566 +                }
 28.1567 +                return false;
 28.1568 +            }
 28.1569 +        }
 28.1570 +
 28.1571 +        /**
 28.1572 +         * Iterators for SubMaps
 28.1573 +         */
 28.1574 +        abstract class SubMapIterator<T> implements Iterator<T> {
 28.1575 +            TreeMap.Entry<K,V> lastReturned;
 28.1576 +            TreeMap.Entry<K,V> next;
 28.1577 +            final Object fenceKey;
 28.1578 +            int expectedModCount;
 28.1579 +
 28.1580 +            SubMapIterator(TreeMap.Entry<K,V> first,
 28.1581 +                           TreeMap.Entry<K,V> fence) {
 28.1582 +                expectedModCount = m.modCount;
 28.1583 +                lastReturned = null;
 28.1584 +                next = first;
 28.1585 +                fenceKey = fence == null ? UNBOUNDED : fence.key;
 28.1586 +            }
 28.1587 +
 28.1588 +            public final boolean hasNext() {
 28.1589 +                return next != null && next.key != fenceKey;
 28.1590 +            }
 28.1591 +
 28.1592 +            final TreeMap.Entry<K,V> nextEntry() {
 28.1593 +                TreeMap.Entry<K,V> e = next;
 28.1594 +                if (e == null || e.key == fenceKey)
 28.1595 +                    throw new NoSuchElementException();
 28.1596 +                if (m.modCount != expectedModCount)
 28.1597 +                    throw new ConcurrentModificationException();
 28.1598 +                next = successor(e);
 28.1599 +                lastReturned = e;
 28.1600 +                return e;
 28.1601 +            }
 28.1602 +
 28.1603 +            final TreeMap.Entry<K,V> prevEntry() {
 28.1604 +                TreeMap.Entry<K,V> e = next;
 28.1605 +                if (e == null || e.key == fenceKey)
 28.1606 +                    throw new NoSuchElementException();
 28.1607 +                if (m.modCount != expectedModCount)
 28.1608 +                    throw new ConcurrentModificationException();
 28.1609 +                next = predecessor(e);
 28.1610 +                lastReturned = e;
 28.1611 +                return e;
 28.1612 +            }
 28.1613 +
 28.1614 +            final void removeAscending() {
 28.1615 +                if (lastReturned == null)
 28.1616 +                    throw new IllegalStateException();
 28.1617 +                if (m.modCount != expectedModCount)
 28.1618 +                    throw new ConcurrentModificationException();
 28.1619 +                // deleted entries are replaced by their successors
 28.1620 +                if (lastReturned.left != null && lastReturned.right != null)
 28.1621 +                    next = lastReturned;
 28.1622 +                m.deleteEntry(lastReturned);
 28.1623 +                lastReturned = null;
 28.1624 +                expectedModCount = m.modCount;
 28.1625 +            }
 28.1626 +
 28.1627 +            final void removeDescending() {
 28.1628 +                if (lastReturned == null)
 28.1629 +                    throw new IllegalStateException();
 28.1630 +                if (m.modCount != expectedModCount)
 28.1631 +                    throw new ConcurrentModificationException();
 28.1632 +                m.deleteEntry(lastReturned);
 28.1633 +                lastReturned = null;
 28.1634 +                expectedModCount = m.modCount;
 28.1635 +            }
 28.1636 +
 28.1637 +        }
 28.1638 +
 28.1639 +        final class SubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
 28.1640 +            SubMapEntryIterator(TreeMap.Entry<K,V> first,
 28.1641 +                                TreeMap.Entry<K,V> fence) {
 28.1642 +                super(first, fence);
 28.1643 +            }
 28.1644 +            public Map.Entry<K,V> next() {
 28.1645 +                return nextEntry();
 28.1646 +            }
 28.1647 +            public void remove() {
 28.1648 +                removeAscending();
 28.1649 +            }
 28.1650 +        }
 28.1651 +
 28.1652 +        final class SubMapKeyIterator extends SubMapIterator<K> {
 28.1653 +            SubMapKeyIterator(TreeMap.Entry<K,V> first,
 28.1654 +                              TreeMap.Entry<K,V> fence) {
 28.1655 +                super(first, fence);
 28.1656 +            }
 28.1657 +            public K next() {
 28.1658 +                return nextEntry().key;
 28.1659 +            }
 28.1660 +            public void remove() {
 28.1661 +                removeAscending();
 28.1662 +            }
 28.1663 +        }
 28.1664 +
 28.1665 +        final class DescendingSubMapEntryIterator extends SubMapIterator<Map.Entry<K,V>> {
 28.1666 +            DescendingSubMapEntryIterator(TreeMap.Entry<K,V> last,
 28.1667 +                                          TreeMap.Entry<K,V> fence) {
 28.1668 +                super(last, fence);
 28.1669 +            }
 28.1670 +
 28.1671 +            public Map.Entry<K,V> next() {
 28.1672 +                return prevEntry();
 28.1673 +            }
 28.1674 +            public void remove() {
 28.1675 +                removeDescending();
 28.1676 +            }
 28.1677 +        }
 28.1678 +
 28.1679 +        final class DescendingSubMapKeyIterator extends SubMapIterator<K> {
 28.1680 +            DescendingSubMapKeyIterator(TreeMap.Entry<K,V> last,
 28.1681 +                                        TreeMap.Entry<K,V> fence) {
 28.1682 +                super(last, fence);
 28.1683 +            }
 28.1684 +            public K next() {
 28.1685 +                return prevEntry().key;
 28.1686 +            }
 28.1687 +            public void remove() {
 28.1688 +                removeDescending();
 28.1689 +            }
 28.1690 +        }
 28.1691 +    }
 28.1692 +
 28.1693 +    /**
 28.1694 +     * @serial include
 28.1695 +     */
 28.1696 +    static final class AscendingSubMap<K,V> extends NavigableSubMap<K,V> {
 28.1697 +        private static final long serialVersionUID = 912986545866124060L;
 28.1698 +
 28.1699 +        AscendingSubMap(TreeMap<K,V> m,
 28.1700 +                        boolean fromStart, K lo, boolean loInclusive,
 28.1701 +                        boolean toEnd,     K hi, boolean hiInclusive) {
 28.1702 +            super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
 28.1703 +        }
 28.1704 +
 28.1705 +        public Comparator<? super K> comparator() {
 28.1706 +            return m.comparator();
 28.1707 +        }
 28.1708 +
 28.1709 +        public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
 28.1710 +                                        K toKey,   boolean toInclusive) {
 28.1711 +            if (!inRange(fromKey, fromInclusive))
 28.1712 +                throw new IllegalArgumentException("fromKey out of range");
 28.1713 +            if (!inRange(toKey, toInclusive))
 28.1714 +                throw new IllegalArgumentException("toKey out of range");
 28.1715 +            return new AscendingSubMap(m,
 28.1716 +                                       false, fromKey, fromInclusive,
 28.1717 +                                       false, toKey,   toInclusive);
 28.1718 +        }
 28.1719 +
 28.1720 +        public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
 28.1721 +            if (!inRange(toKey, inclusive))
 28.1722 +                throw new IllegalArgumentException("toKey out of range");
 28.1723 +            return new AscendingSubMap(m,
 28.1724 +                                       fromStart, lo,    loInclusive,
 28.1725 +                                       false,     toKey, inclusive);
 28.1726 +        }
 28.1727 +
 28.1728 +        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
 28.1729 +            if (!inRange(fromKey, inclusive))
 28.1730 +                throw new IllegalArgumentException("fromKey out of range");
 28.1731 +            return new AscendingSubMap(m,
 28.1732 +                                       false, fromKey, inclusive,
 28.1733 +                                       toEnd, hi,      hiInclusive);
 28.1734 +        }
 28.1735 +
 28.1736 +        public NavigableMap<K,V> descendingMap() {
 28.1737 +            NavigableMap<K,V> mv = descendingMapView;
 28.1738 +            return (mv != null) ? mv :
 28.1739 +                (descendingMapView =
 28.1740 +                 new DescendingSubMap(m,
 28.1741 +                                      fromStart, lo, loInclusive,
 28.1742 +                                      toEnd,     hi, hiInclusive));
 28.1743 +        }
 28.1744 +
 28.1745 +        Iterator<K> keyIterator() {
 28.1746 +            return new SubMapKeyIterator(absLowest(), absHighFence());
 28.1747 +        }
 28.1748 +
 28.1749 +        Iterator<K> descendingKeyIterator() {
 28.1750 +            return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
 28.1751 +        }
 28.1752 +
 28.1753 +        final class AscendingEntrySetView extends EntrySetView {
 28.1754 +            public Iterator<Map.Entry<K,V>> iterator() {
 28.1755 +                return new SubMapEntryIterator(absLowest(), absHighFence());
 28.1756 +            }
 28.1757 +        }
 28.1758 +
 28.1759 +        public Set<Map.Entry<K,V>> entrySet() {
 28.1760 +            EntrySetView es = entrySetView;
 28.1761 +            return (es != null) ? es : new AscendingEntrySetView();
 28.1762 +        }
 28.1763 +
 28.1764 +        TreeMap.Entry<K,V> subLowest()       { return absLowest(); }
 28.1765 +        TreeMap.Entry<K,V> subHighest()      { return absHighest(); }
 28.1766 +        TreeMap.Entry<K,V> subCeiling(K key) { return absCeiling(key); }
 28.1767 +        TreeMap.Entry<K,V> subHigher(K key)  { return absHigher(key); }
 28.1768 +        TreeMap.Entry<K,V> subFloor(K key)   { return absFloor(key); }
 28.1769 +        TreeMap.Entry<K,V> subLower(K key)   { return absLower(key); }
 28.1770 +    }
 28.1771 +
 28.1772 +    /**
 28.1773 +     * @serial include
 28.1774 +     */
 28.1775 +    static final class DescendingSubMap<K,V>  extends NavigableSubMap<K,V> {
 28.1776 +        private static final long serialVersionUID = 912986545866120460L;
 28.1777 +        DescendingSubMap(TreeMap<K,V> m,
 28.1778 +                        boolean fromStart, K lo, boolean loInclusive,
 28.1779 +                        boolean toEnd,     K hi, boolean hiInclusive) {
 28.1780 +            super(m, fromStart, lo, loInclusive, toEnd, hi, hiInclusive);
 28.1781 +        }
 28.1782 +
 28.1783 +        private final Comparator<? super K> reverseComparator =
 28.1784 +            Collections.reverseOrder(m.comparator);
 28.1785 +
 28.1786 +        public Comparator<? super K> comparator() {
 28.1787 +            return reverseComparator;
 28.1788 +        }
 28.1789 +
 28.1790 +        public NavigableMap<K,V> subMap(K fromKey, boolean fromInclusive,
 28.1791 +                                        K toKey,   boolean toInclusive) {
 28.1792 +            if (!inRange(fromKey, fromInclusive))
 28.1793 +                throw new IllegalArgumentException("fromKey out of range");
 28.1794 +            if (!inRange(toKey, toInclusive))
 28.1795 +                throw new IllegalArgumentException("toKey out of range");
 28.1796 +            return new DescendingSubMap(m,
 28.1797 +                                        false, toKey,   toInclusive,
 28.1798 +                                        false, fromKey, fromInclusive);
 28.1799 +        }
 28.1800 +
 28.1801 +        public NavigableMap<K,V> headMap(K toKey, boolean inclusive) {
 28.1802 +            if (!inRange(toKey, inclusive))
 28.1803 +                throw new IllegalArgumentException("toKey out of range");
 28.1804 +            return new DescendingSubMap(m,
 28.1805 +                                        false, toKey, inclusive,
 28.1806 +                                        toEnd, hi,    hiInclusive);
 28.1807 +        }
 28.1808 +
 28.1809 +        public NavigableMap<K,V> tailMap(K fromKey, boolean inclusive) {
 28.1810 +            if (!inRange(fromKey, inclusive))
 28.1811 +                throw new IllegalArgumentException("fromKey out of range");
 28.1812 +            return new DescendingSubMap(m,
 28.1813 +                                        fromStart, lo, loInclusive,
 28.1814 +                                        false, fromKey, inclusive);
 28.1815 +        }
 28.1816 +
 28.1817 +        public NavigableMap<K,V> descendingMap() {
 28.1818 +            NavigableMap<K,V> mv = descendingMapView;
 28.1819 +            return (mv != null) ? mv :
 28.1820 +                (descendingMapView =
 28.1821 +                 new AscendingSubMap(m,
 28.1822 +                                     fromStart, lo, loInclusive,
 28.1823 +                                     toEnd,     hi, hiInclusive));
 28.1824 +        }
 28.1825 +
 28.1826 +        Iterator<K> keyIterator() {
 28.1827 +            return new DescendingSubMapKeyIterator(absHighest(), absLowFence());
 28.1828 +        }
 28.1829 +
 28.1830 +        Iterator<K> descendingKeyIterator() {
 28.1831 +            return new SubMapKeyIterator(absLowest(), absHighFence());
 28.1832 +        }
 28.1833 +
 28.1834 +        final class DescendingEntrySetView extends EntrySetView {
 28.1835 +            public Iterator<Map.Entry<K,V>> iterator() {
 28.1836 +                return new DescendingSubMapEntryIterator(absHighest(), absLowFence());
 28.1837 +            }
 28.1838 +        }
 28.1839 +
 28.1840 +        public Set<Map.Entry<K,V>> entrySet() {
 28.1841 +            EntrySetView es = entrySetView;
 28.1842 +            return (es != null) ? es : new DescendingEntrySetView();
 28.1843 +        }
 28.1844 +
 28.1845 +        TreeMap.Entry<K,V> subLowest()       { return absHighest(); }
 28.1846 +        TreeMap.Entry<K,V> subHighest()      { return absLowest(); }
 28.1847 +        TreeMap.Entry<K,V> subCeiling(K key) { return absFloor(key); }
 28.1848 +        TreeMap.Entry<K,V> subHigher(K key)  { return absLower(key); }
 28.1849 +        TreeMap.Entry<K,V> subFloor(K key)   { return absCeiling(key); }
 28.1850 +        TreeMap.Entry<K,V> subLower(K key)   { return absHigher(key); }
 28.1851 +    }
 28.1852 +
 28.1853 +    /**
 28.1854 +     * This class exists solely for the sake of serialization
 28.1855 +     * compatibility with previous releases of TreeMap that did not
 28.1856 +     * support NavigableMap.  It translates an old-version SubMap into
 28.1857 +     * a new-version AscendingSubMap. This class is never otherwise
 28.1858 +     * used.
 28.1859 +     *
 28.1860 +     * @serial include
 28.1861 +     */
 28.1862 +    private class SubMap extends AbstractMap<K,V>
 28.1863 +        implements SortedMap<K,V>, java.io.Serializable {
 28.1864 +        private static final long serialVersionUID = -6520786458950516097L;
 28.1865 +        private boolean fromStart = false, toEnd = false;
 28.1866 +        private K fromKey, toKey;
 28.1867 +        private Object readResolve() {
 28.1868 +            return new AscendingSubMap(TreeMap.this,
 28.1869 +                                       fromStart, fromKey, true,
 28.1870 +                                       toEnd, toKey, false);
 28.1871 +        }
 28.1872 +        public Set<Map.Entry<K,V>> entrySet() { throw new InternalError(); }
 28.1873 +        public K lastKey() { throw new InternalError(); }
 28.1874 +        public K firstKey() { throw new InternalError(); }
 28.1875 +        public SortedMap<K,V> subMap(K fromKey, K toKey) { throw new InternalError(); }
 28.1876 +        public SortedMap<K,V> headMap(K toKey) { throw new InternalError(); }
 28.1877 +        public SortedMap<K,V> tailMap(K fromKey) { throw new InternalError(); }
 28.1878 +        public Comparator<? super K> comparator() { throw new InternalError(); }
 28.1879 +    }
 28.1880 +
 28.1881 +
 28.1882 +    // Red-black mechanics
 28.1883 +
 28.1884 +    private static final boolean RED   = false;
 28.1885 +    private static final boolean BLACK = true;
 28.1886 +
 28.1887 +    /**
 28.1888 +     * Node in the Tree.  Doubles as a means to pass key-value pairs back to
 28.1889 +     * user (see Map.Entry).
 28.1890 +     */
 28.1891 +
 28.1892 +    static final class Entry<K,V> implements Map.Entry<K,V> {
 28.1893 +        K key;
 28.1894 +        V value;
 28.1895 +        Entry<K,V> left = null;
 28.1896 +        Entry<K,V> right = null;
 28.1897 +        Entry<K,V> parent;
 28.1898 +        boolean color = BLACK;
 28.1899 +
 28.1900 +        /**
 28.1901 +         * Make a new cell with given key, value, and parent, and with
 28.1902 +         * {@code null} child links, and BLACK color.
 28.1903 +         */
 28.1904 +        Entry(K key, V value, Entry<K,V> parent) {
 28.1905 +            this.key = key;
 28.1906 +            this.value = value;
 28.1907 +            this.parent = parent;
 28.1908 +        }
 28.1909 +
 28.1910 +        /**
 28.1911 +         * Returns the key.
 28.1912 +         *
 28.1913 +         * @return the key
 28.1914 +         */
 28.1915 +        public K getKey() {
 28.1916 +            return key;
 28.1917 +        }
 28.1918 +
 28.1919 +        /**
 28.1920 +         * Returns the value associated with the key.
 28.1921 +         *
 28.1922 +         * @return the value associated with the key
 28.1923 +         */
 28.1924 +        public V getValue() {
 28.1925 +            return value;
 28.1926 +        }
 28.1927 +
 28.1928 +        /**
 28.1929 +         * Replaces the value currently associated with the key with the given
 28.1930 +         * value.
 28.1931 +         *
 28.1932 +         * @return the value associated with the key before this method was
 28.1933 +         *         called
 28.1934 +         */
 28.1935 +        public V setValue(V value) {
 28.1936 +            V oldValue = this.value;
 28.1937 +            this.value = value;
 28.1938 +            return oldValue;
 28.1939 +        }
 28.1940 +
 28.1941 +        public boolean equals(Object o) {
 28.1942 +            if (!(o instanceof Map.Entry))
 28.1943 +                return false;
 28.1944 +            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
 28.1945 +
 28.1946 +            return valEquals(key,e.getKey()) && valEquals(value,e.getValue());
 28.1947 +        }
 28.1948 +
 28.1949 +        public int hashCode() {
 28.1950 +            int keyHash = (key==null ? 0 : key.hashCode());
 28.1951 +            int valueHash = (value==null ? 0 : value.hashCode());
 28.1952 +            return keyHash ^ valueHash;
 28.1953 +        }
 28.1954 +
 28.1955 +        public String toString() {
 28.1956 +            return key + "=" + value;
 28.1957 +        }
 28.1958 +    }
 28.1959 +
 28.1960 +    /**
 28.1961 +     * Returns the first Entry in the TreeMap (according to the TreeMap's
 28.1962 +     * key-sort function).  Returns null if the TreeMap is empty.
 28.1963 +     */
 28.1964 +    final Entry<K,V> getFirstEntry() {
 28.1965 +        Entry<K,V> p = root;
 28.1966 +        if (p != null)
 28.1967 +            while (p.left != null)
 28.1968 +                p = p.left;
 28.1969 +        return p;
 28.1970 +    }
 28.1971 +
 28.1972 +    /**
 28.1973 +     * Returns the last Entry in the TreeMap (according to the TreeMap's
 28.1974 +     * key-sort function).  Returns null if the TreeMap is empty.
 28.1975 +     */
 28.1976 +    final Entry<K,V> getLastEntry() {
 28.1977 +        Entry<K,V> p = root;
 28.1978 +        if (p != null)
 28.1979 +            while (p.right != null)
 28.1980 +                p = p.right;
 28.1981 +        return p;
 28.1982 +    }
 28.1983 +
 28.1984 +    /**
 28.1985 +     * Returns the successor of the specified Entry, or null if no such.
 28.1986 +     */
 28.1987 +    static <K,V> TreeMap.Entry<K,V> successor(Entry<K,V> t) {
 28.1988 +        if (t == null)
 28.1989 +            return null;
 28.1990 +        else if (t.right != null) {
 28.1991 +            Entry<K,V> p = t.right;
 28.1992 +            while (p.left != null)
 28.1993 +                p = p.left;
 28.1994 +            return p;
 28.1995 +        } else {
 28.1996 +            Entry<K,V> p = t.parent;
 28.1997 +            Entry<K,V> ch = t;
 28.1998 +            while (p != null && ch == p.right) {
 28.1999 +                ch = p;
 28.2000 +                p = p.parent;
 28.2001 +            }
 28.2002 +            return p;
 28.2003 +        }
 28.2004 +    }
 28.2005 +
 28.2006 +    /**
 28.2007 +     * Returns the predecessor of the specified Entry, or null if no such.
 28.2008 +     */
 28.2009 +    static <K,V> Entry<K,V> predecessor(Entry<K,V> t) {
 28.2010 +        if (t == null)
 28.2011 +            return null;
 28.2012 +        else if (t.left != null) {
 28.2013 +            Entry<K,V> p = t.left;
 28.2014 +            while (p.right != null)
 28.2015 +                p = p.right;
 28.2016 +            return p;
 28.2017 +        } else {
 28.2018 +            Entry<K,V> p = t.parent;
 28.2019 +            Entry<K,V> ch = t;
 28.2020 +            while (p != null && ch == p.left) {
 28.2021 +                ch = p;
 28.2022 +                p = p.parent;
 28.2023 +            }
 28.2024 +            return p;
 28.2025 +        }
 28.2026 +    }
 28.2027 +
 28.2028 +    /**
 28.2029 +     * Balancing operations.
 28.2030 +     *
 28.2031 +     * Implementations of rebalancings during insertion and deletion are
 28.2032 +     * slightly different than the CLR version.  Rather than using dummy
 28.2033 +     * nilnodes, we use a set of accessors that deal properly with null.  They
 28.2034 +     * are used to avoid messiness surrounding nullness checks in the main
 28.2035 +     * algorithms.
 28.2036 +     */
 28.2037 +
 28.2038 +    private static <K,V> boolean colorOf(Entry<K,V> p) {
 28.2039 +        return (p == null ? BLACK : p.color);
 28.2040 +    }
 28.2041 +
 28.2042 +    private static <K,V> Entry<K,V> parentOf(Entry<K,V> p) {
 28.2043 +        return (p == null ? null: p.parent);
 28.2044 +    }
 28.2045 +
 28.2046 +    private static <K,V> void setColor(Entry<K,V> p, boolean c) {
 28.2047 +        if (p != null)
 28.2048 +            p.color = c;
 28.2049 +    }
 28.2050 +
 28.2051 +    private static <K,V> Entry<K,V> leftOf(Entry<K,V> p) {
 28.2052 +        return (p == null) ? null: p.left;
 28.2053 +    }
 28.2054 +
 28.2055 +    private static <K,V> Entry<K,V> rightOf(Entry<K,V> p) {
 28.2056 +        return (p == null) ? null: p.right;
 28.2057 +    }
 28.2058 +
 28.2059 +    /** From CLR */
 28.2060 +    private void rotateLeft(Entry<K,V> p) {
 28.2061 +        if (p != null) {
 28.2062 +            Entry<K,V> r = p.right;
 28.2063 +            p.right = r.left;
 28.2064 +            if (r.left != null)
 28.2065 +                r.left.parent = p;
 28.2066 +            r.parent = p.parent;
 28.2067 +            if (p.parent == null)
 28.2068 +                root = r;
 28.2069 +            else if (p.parent.left == p)
 28.2070 +                p.parent.left = r;
 28.2071 +            else
 28.2072 +                p.parent.right = r;
 28.2073 +            r.left = p;
 28.2074 +            p.parent = r;
 28.2075 +        }
 28.2076 +    }
 28.2077 +
 28.2078 +    /** From CLR */
 28.2079 +    private void rotateRight(Entry<K,V> p) {
 28.2080 +        if (p != null) {
 28.2081 +            Entry<K,V> l = p.left;
 28.2082 +            p.left = l.right;
 28.2083 +            if (l.right != null) l.right.parent = p;
 28.2084 +            l.parent = p.parent;
 28.2085 +            if (p.parent == null)
 28.2086 +                root = l;
 28.2087 +            else if (p.parent.right == p)
 28.2088 +                p.parent.right = l;
 28.2089 +            else p.parent.left = l;
 28.2090 +            l.right = p;
 28.2091 +            p.parent = l;
 28.2092 +        }
 28.2093 +    }
 28.2094 +
 28.2095 +    /** From CLR */
 28.2096 +    private void fixAfterInsertion(Entry<K,V> x) {
 28.2097 +        x.color = RED;
 28.2098 +
 28.2099 +        while (x != null && x != root && x.parent.color == RED) {
 28.2100 +            if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
 28.2101 +                Entry<K,V> y = rightOf(parentOf(parentOf(x)));
 28.2102 +                if (colorOf(y) == RED) {
 28.2103 +                    setColor(parentOf(x), BLACK);
 28.2104 +                    setColor(y, BLACK);
 28.2105 +                    setColor(parentOf(parentOf(x)), RED);
 28.2106 +                    x = parentOf(parentOf(x));
 28.2107 +                } else {
 28.2108 +                    if (x == rightOf(parentOf(x))) {
 28.2109 +                        x = parentOf(x);
 28.2110 +                        rotateLeft(x);
 28.2111 +                    }
 28.2112 +                    setColor(parentOf(x), BLACK);
 28.2113 +                    setColor(parentOf(parentOf(x)), RED);
 28.2114 +                    rotateRight(parentOf(parentOf(x)));
 28.2115 +                }
 28.2116 +            } else {
 28.2117 +                Entry<K,V> y = leftOf(parentOf(parentOf(x)));
 28.2118 +                if (colorOf(y) == RED) {
 28.2119 +                    setColor(parentOf(x), BLACK);
 28.2120 +                    setColor(y, BLACK);
 28.2121 +                    setColor(parentOf(parentOf(x)), RED);
 28.2122 +                    x = parentOf(parentOf(x));
 28.2123 +                } else {
 28.2124 +                    if (x == leftOf(parentOf(x))) {
 28.2125 +                        x = parentOf(x);
 28.2126 +                        rotateRight(x);
 28.2127 +                    }
 28.2128 +                    setColor(parentOf(x), BLACK);
 28.2129 +                    setColor(parentOf(parentOf(x)), RED);
 28.2130 +                    rotateLeft(parentOf(parentOf(x)));
 28.2131 +                }
 28.2132 +            }
 28.2133 +        }
 28.2134 +        root.color = BLACK;
 28.2135 +    }
 28.2136 +
 28.2137 +    /**
 28.2138 +     * Delete node p, and then rebalance the tree.
 28.2139 +     */
 28.2140 +    private void deleteEntry(Entry<K,V> p) {
 28.2141 +        modCount++;
 28.2142 +        size--;
 28.2143 +
 28.2144 +        // If strictly internal, copy successor's element to p and then make p
 28.2145 +        // point to successor.
 28.2146 +        if (p.left != null && p.right != null) {
 28.2147 +            Entry<K,V> s = successor(p);
 28.2148 +            p.key = s.key;
 28.2149 +            p.value = s.value;
 28.2150 +            p = s;
 28.2151 +        } // p has 2 children
 28.2152 +
 28.2153 +        // Start fixup at replacement node, if it exists.
 28.2154 +        Entry<K,V> replacement = (p.left != null ? p.left : p.right);
 28.2155 +
 28.2156 +        if (replacement != null) {
 28.2157 +            // Link replacement to parent
 28.2158 +            replacement.parent = p.parent;
 28.2159 +            if (p.parent == null)
 28.2160 +                root = replacement;
 28.2161 +            else if (p == p.parent.left)
 28.2162 +                p.parent.left  = replacement;
 28.2163 +            else
 28.2164 +                p.parent.right = replacement;
 28.2165 +
 28.2166 +            // Null out links so they are OK to use by fixAfterDeletion.
 28.2167 +            p.left = p.right = p.parent = null;
 28.2168 +
 28.2169 +            // Fix replacement
 28.2170 +            if (p.color == BLACK)
 28.2171 +                fixAfterDeletion(replacement);
 28.2172 +        } else if (p.parent == null) { // return if we are the only node.
 28.2173 +            root = null;
 28.2174 +        } else { //  No children. Use self as phantom replacement and unlink.
 28.2175 +            if (p.color == BLACK)
 28.2176 +                fixAfterDeletion(p);
 28.2177 +
 28.2178 +            if (p.parent != null) {
 28.2179 +                if (p == p.parent.left)
 28.2180 +                    p.parent.left = null;
 28.2181 +                else if (p == p.parent.right)
 28.2182 +                    p.parent.right = null;
 28.2183 +                p.parent = null;
 28.2184 +            }
 28.2185 +        }
 28.2186 +    }
 28.2187 +
 28.2188 +    /** From CLR */
 28.2189 +    private void fixAfterDeletion(Entry<K,V> x) {
 28.2190 +        while (x != root && colorOf(x) == BLACK) {
 28.2191 +            if (x == leftOf(parentOf(x))) {
 28.2192 +                Entry<K,V> sib = rightOf(parentOf(x));
 28.2193 +
 28.2194 +                if (colorOf(sib) == RED) {
 28.2195 +                    setColor(sib, BLACK);
 28.2196 +                    setColor(parentOf(x), RED);
 28.2197 +                    rotateLeft(parentOf(x));
 28.2198 +                    sib = rightOf(parentOf(x));
 28.2199 +                }
 28.2200 +
 28.2201 +                if (colorOf(leftOf(sib))  == BLACK &&
 28.2202 +                    colorOf(rightOf(sib)) == BLACK) {
 28.2203 +                    setColor(sib, RED);
 28.2204 +                    x = parentOf(x);
 28.2205 +                } else {
 28.2206 +                    if (colorOf(rightOf(sib)) == BLACK) {
 28.2207 +                        setColor(leftOf(sib), BLACK);
 28.2208 +                        setColor(sib, RED);
 28.2209 +                        rotateRight(sib);
 28.2210 +                        sib = rightOf(parentOf(x));
 28.2211 +                    }
 28.2212 +                    setColor(sib, colorOf(parentOf(x)));
 28.2213 +                    setColor(parentOf(x), BLACK);
 28.2214 +                    setColor(rightOf(sib), BLACK);
 28.2215 +                    rotateLeft(parentOf(x));
 28.2216 +                    x = root;
 28.2217 +                }
 28.2218 +            } else { // symmetric
 28.2219 +                Entry<K,V> sib = leftOf(parentOf(x));
 28.2220 +
 28.2221 +                if (colorOf(sib) == RED) {
 28.2222 +                    setColor(sib, BLACK);
 28.2223 +                    setColor(parentOf(x), RED);
 28.2224 +                    rotateRight(parentOf(x));
 28.2225 +                    sib = leftOf(parentOf(x));
 28.2226 +                }
 28.2227 +
 28.2228 +                if (colorOf(rightOf(sib)) == BLACK &&
 28.2229 +                    colorOf(leftOf(sib)) == BLACK) {
 28.2230 +                    setColor(sib, RED);
 28.2231 +                    x = parentOf(x);
 28.2232 +                } else {
 28.2233 +                    if (colorOf(leftOf(sib)) == BLACK) {
 28.2234 +                        setColor(rightOf(sib), BLACK);
 28.2235 +                        setColor(sib, RED);
 28.2236 +                        rotateLeft(sib);
 28.2237 +                        sib = leftOf(parentOf(x));
 28.2238 +                    }
 28.2239 +                    setColor(sib, colorOf(parentOf(x)));
 28.2240 +                    setColor(parentOf(x), BLACK);
 28.2241 +                    setColor(leftOf(sib), BLACK);
 28.2242 +                    rotateRight(parentOf(x));
 28.2243 +                    x = root;
 28.2244 +                }
 28.2245 +            }
 28.2246 +        }
 28.2247 +
 28.2248 +        setColor(x, BLACK);
 28.2249 +    }
 28.2250 +
 28.2251 +    private static final long serialVersionUID = 919286545866124006L;
 28.2252 +
 28.2253 +    /**
 28.2254 +     * Save the state of the {@code TreeMap} instance to a stream (i.e.,
 28.2255 +     * serialize it).
 28.2256 +     *
 28.2257 +     * @serialData The <em>size</em> of the TreeMap (the number of key-value
 28.2258 +     *             mappings) is emitted (int), followed by the key (Object)
 28.2259 +     *             and value (Object) for each key-value mapping represented
 28.2260 +     *             by the TreeMap. The key-value mappings are emitted in
 28.2261 +     *             key-order (as determined by the TreeMap's Comparator,
 28.2262 +     *             or by the keys' natural ordering if the TreeMap has no
 28.2263 +     *             Comparator).
 28.2264 +     */
 28.2265 +    private void writeObject(java.io.ObjectOutputStream s)
 28.2266 +        throws java.io.IOException {
 28.2267 +        // Write out the Comparator and any hidden stuff
 28.2268 +        s.defaultWriteObject();
 28.2269 +
 28.2270 +        // Write out size (number of Mappings)
 28.2271 +        s.writeInt(size);
 28.2272 +
 28.2273 +        // Write out keys and values (alternating)
 28.2274 +        for (Iterator<Map.Entry<K,V>> i = entrySet().iterator(); i.hasNext(); ) {
 28.2275 +            Map.Entry<K,V> e = i.next();
 28.2276 +            s.writeObject(e.getKey());
 28.2277 +            s.writeObject(e.getValue());
 28.2278 +        }
 28.2279 +    }
 28.2280 +
 28.2281 +    /**
 28.2282 +     * Reconstitute the {@code TreeMap} instance from a stream (i.e.,
 28.2283 +     * deserialize it).
 28.2284 +     */
 28.2285 +    private void readObject(final java.io.ObjectInputStream s)
 28.2286 +        throws java.io.IOException, ClassNotFoundException {
 28.2287 +        // Read in the Comparator and any hidden stuff
 28.2288 +        s.defaultReadObject();
 28.2289 +
 28.2290 +        // Read in size
 28.2291 +        int size = s.readInt();
 28.2292 +
 28.2293 +        buildFromSorted(size, null, s, null);
 28.2294 +    }
 28.2295 +
 28.2296 +    /** Intended to be called only from TreeSet.readObject */
 28.2297 +    void readTreeSet(int size, java.io.ObjectInputStream s, V defaultVal)
 28.2298 +        throws java.io.IOException, ClassNotFoundException {
 28.2299 +        buildFromSorted(size, null, s, defaultVal);
 28.2300 +    }
 28.2301 +
 28.2302 +    /** Intended to be called only from TreeSet.addAll */
 28.2303 +    void addAllForTreeSet(SortedSet<? extends K> set, V defaultVal) {
 28.2304 +        try {
 28.2305 +            buildFromSorted(set.size(), set.iterator(), null, defaultVal);
 28.2306 +        } catch (java.io.IOException cannotHappen) {
 28.2307 +        } catch (ClassNotFoundException cannotHappen) {
 28.2308 +        }
 28.2309 +    }
 28.2310 +
 28.2311 +
 28.2312 +    /**
 28.2313 +     * Linear time tree building algorithm from sorted data.  Can accept keys
 28.2314 +     * and/or values from iterator or stream. This leads to too many
 28.2315 +     * parameters, but seems better than alternatives.  The four formats
 28.2316 +     * that this method accepts are:
 28.2317 +     *
 28.2318 +     *    1) An iterator of Map.Entries.  (it != null, defaultVal == null).
 28.2319 +     *    2) An iterator of keys.         (it != null, defaultVal != null).
 28.2320 +     *    3) A stream of alternating serialized keys and values.
 28.2321 +     *                                   (it == null, defaultVal == null).
 28.2322 +     *    4) A stream of serialized keys. (it == null, defaultVal != null).
 28.2323 +     *
 28.2324 +     * It is assumed that the comparator of the TreeMap is already set prior
 28.2325 +     * to calling this method.
 28.2326 +     *
 28.2327 +     * @param size the number of keys (or key-value pairs) to be read from
 28.2328 +     *        the iterator or stream
 28.2329 +     * @param it If non-null, new entries are created from entries
 28.2330 +     *        or keys read from this iterator.
 28.2331 +     * @param str If non-null, new entries are created from keys and
 28.2332 +     *        possibly values read from this stream in serialized form.
 28.2333 +     *        Exactly one of it and str should be non-null.
 28.2334 +     * @param defaultVal if non-null, this default value is used for
 28.2335 +     *        each value in the map.  If null, each value is read from
 28.2336 +     *        iterator or stream, as described above.
 28.2337 +     * @throws IOException propagated from stream reads. This cannot
 28.2338 +     *         occur if str is null.
 28.2339 +     * @throws ClassNotFoundException propagated from readObject.
 28.2340 +     *         This cannot occur if str is null.
 28.2341 +     */
 28.2342 +    private void buildFromSorted(int size, Iterator it,
 28.2343 +                                 java.io.ObjectInputStream str,
 28.2344 +                                 V defaultVal)
 28.2345 +        throws  java.io.IOException, ClassNotFoundException {
 28.2346 +        this.size = size;
 28.2347 +        root = buildFromSorted(0, 0, size-1, computeRedLevel(size),
 28.2348 +                               it, str, defaultVal);
 28.2349 +    }
 28.2350 +
 28.2351 +    /**
 28.2352 +     * Recursive "helper method" that does the real work of the
 28.2353 +     * previous method.  Identically named parameters have
 28.2354 +     * identical definitions.  Additional parameters are documented below.
 28.2355 +     * It is assumed that the comparator and size fields of the TreeMap are
 28.2356 +     * already set prior to calling this method.  (It ignores both fields.)
 28.2357 +     *
 28.2358 +     * @param level the current level of tree. Initial call should be 0.
 28.2359 +     * @param lo the first element index of this subtree. Initial should be 0.
 28.2360 +     * @param hi the last element index of this subtree.  Initial should be
 28.2361 +     *        size-1.
 28.2362 +     * @param redLevel the level at which nodes should be red.
 28.2363 +     *        Must be equal to computeRedLevel for tree of this size.
 28.2364 +     */
 28.2365 +    private final Entry<K,V> buildFromSorted(int level, int lo, int hi,
 28.2366 +                                             int redLevel,
 28.2367 +                                             Iterator it,
 28.2368 +                                             java.io.ObjectInputStream str,
 28.2369 +                                             V defaultVal)
 28.2370 +        throws  java.io.IOException, ClassNotFoundException {
 28.2371 +        /*
 28.2372 +         * Strategy: The root is the middlemost element. To get to it, we
 28.2373 +         * have to first recursively construct the entire left subtree,
 28.2374 +         * so as to grab all of its elements. We can then proceed with right
 28.2375 +         * subtree.
 28.2376 +         *
 28.2377 +         * The lo and hi arguments are the minimum and maximum
 28.2378 +         * indices to pull out of the iterator or stream for current subtree.
 28.2379 +         * They are not actually indexed, we just proceed sequentially,
 28.2380 +         * ensuring that items are extracted in corresponding order.
 28.2381 +         */
 28.2382 +
 28.2383 +        if (hi < lo) return null;
 28.2384 +
 28.2385 +        int mid = (lo + hi) >>> 1;
 28.2386 +
 28.2387 +        Entry<K,V> left  = null;
 28.2388 +        if (lo < mid)
 28.2389 +            left = buildFromSorted(level+1, lo, mid - 1, redLevel,
 28.2390 +                                   it, str, defaultVal);
 28.2391 +
 28.2392 +        // extract key and/or value from iterator or stream
 28.2393 +        K key;
 28.2394 +        V value;
 28.2395 +        if (it != null) {
 28.2396 +            if (defaultVal==null) {
 28.2397 +                Map.Entry<K,V> entry = (Map.Entry<K,V>)it.next();
 28.2398 +                key = entry.getKey();
 28.2399 +                value = entry.getValue();
 28.2400 +            } else {
 28.2401 +                key = (K)it.next();
 28.2402 +                value = defaultVal;
 28.2403 +            }
 28.2404 +        } else { // use stream
 28.2405 +            key = (K) str.readObject();
 28.2406 +            value = (defaultVal != null ? defaultVal : (V) str.readObject());
 28.2407 +        }
 28.2408 +
 28.2409 +        Entry<K,V> middle =  new Entry<>(key, value, null);
 28.2410 +
 28.2411 +        // color nodes in non-full bottommost level red
 28.2412 +        if (level == redLevel)
 28.2413 +            middle.color = RED;
 28.2414 +
 28.2415 +        if (left != null) {
 28.2416 +            middle.left = left;
 28.2417 +            left.parent = middle;
 28.2418 +        }
 28.2419 +
 28.2420 +        if (mid < hi) {
 28.2421 +            Entry<K,V> right = buildFromSorted(level+1, mid+1, hi, redLevel,
 28.2422 +                                               it, str, defaultVal);
 28.2423 +            middle.right = right;
 28.2424 +            right.parent = middle;
 28.2425 +        }
 28.2426 +
 28.2427 +        return middle;
 28.2428 +    }
 28.2429 +
 28.2430 +    /**
 28.2431 +     * Find the level down to which to assign all nodes BLACK.  This is the
 28.2432 +     * last `full' level of the complete binary tree produced by
 28.2433 +     * buildTree. The remaining nodes are colored RED. (This makes a `nice'
 28.2434 +     * set of color assignments wrt future insertions.) This level number is
 28.2435 +     * computed by finding the number of splits needed to reach the zeroeth
 28.2436 +     * node.  (The answer is ~lg(N), but in any case must be computed by same
 28.2437 +     * quick O(lg(N)) loop.)
 28.2438 +     */
 28.2439 +    private static int computeRedLevel(int sz) {
 28.2440 +        int level = 0;
 28.2441 +        for (int m = sz - 1; m >= 0; m = m / 2 - 1)
 28.2442 +            level++;
 28.2443 +        return level;
 28.2444 +    }
 28.2445 +}
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/rt/emul/compact/src/main/java/java/util/TreeSet.java	Sat Sep 07 13:55:09 2013 +0200
    29.3 @@ -0,0 +1,539 @@
    29.4 +/*
    29.5 + * Copyright (c) 1998, 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.util;
   29.30 +
   29.31 +/**
   29.32 + * A {@link NavigableSet} implementation based on a {@link TreeMap}.
   29.33 + * The elements are ordered using their {@linkplain Comparable natural
   29.34 + * ordering}, or by a {@link Comparator} provided at set creation
   29.35 + * time, depending on which constructor is used.
   29.36 + *
   29.37 + * <p>This implementation provides guaranteed log(n) time cost for the basic
   29.38 + * operations ({@code add}, {@code remove} and {@code contains}).
   29.39 + *
   29.40 + * <p>Note that the ordering maintained by a set (whether or not an explicit
   29.41 + * comparator is provided) must be <i>consistent with equals</i> if it is to
   29.42 + * correctly implement the {@code Set} interface.  (See {@code Comparable}
   29.43 + * or {@code Comparator} for a precise definition of <i>consistent with
   29.44 + * equals</i>.)  This is so because the {@code Set} interface is defined in
   29.45 + * terms of the {@code equals} operation, but a {@code TreeSet} instance
   29.46 + * performs all element comparisons using its {@code compareTo} (or
   29.47 + * {@code compare}) method, so two elements that are deemed equal by this method
   29.48 + * are, from the standpoint of the set, equal.  The behavior of a set
   29.49 + * <i>is</i> well-defined even if its ordering is inconsistent with equals; it
   29.50 + * just fails to obey the general contract of the {@code Set} interface.
   29.51 + *
   29.52 + * <p><strong>Note that this implementation is not synchronized.</strong>
   29.53 + * If multiple threads access a tree set concurrently, and at least one
   29.54 + * of the threads modifies the set, it <i>must</i> be synchronized
   29.55 + * externally.  This is typically accomplished by synchronizing on some
   29.56 + * object that naturally encapsulates the set.
   29.57 + * If no such object exists, the set should be "wrapped" using the
   29.58 + * {@link Collections#synchronizedSortedSet Collections.synchronizedSortedSet}
   29.59 + * method.  This is best done at creation time, to prevent accidental
   29.60 + * unsynchronized access to the set: <pre>
   29.61 + *   SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));</pre>
   29.62 + *
   29.63 + * <p>The iterators returned by this class's {@code iterator} method are
   29.64 + * <i>fail-fast</i>: if the set is modified at any time after the iterator is
   29.65 + * created, in any way except through the iterator's own {@code remove}
   29.66 + * method, the iterator will throw a {@link ConcurrentModificationException}.
   29.67 + * Thus, in the face of concurrent modification, the iterator fails quickly
   29.68 + * and cleanly, rather than risking arbitrary, non-deterministic behavior at
   29.69 + * an undetermined time in the future.
   29.70 + *
   29.71 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
   29.72 + * as it is, generally speaking, impossible to make any hard guarantees in the
   29.73 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
   29.74 + * throw {@code ConcurrentModificationException} on a best-effort basis.
   29.75 + * Therefore, it would be wrong to write a program that depended on this
   29.76 + * exception for its correctness:   <i>the fail-fast behavior of iterators
   29.77 + * should be used only to detect bugs.</i>
   29.78 + *
   29.79 + * <p>This class is a member of the
   29.80 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
   29.81 + * Java Collections Framework</a>.
   29.82 + *
   29.83 + * @param <E> the type of elements maintained by this set
   29.84 + *
   29.85 + * @author  Josh Bloch
   29.86 + * @see     Collection
   29.87 + * @see     Set
   29.88 + * @see     HashSet
   29.89 + * @see     Comparable
   29.90 + * @see     Comparator
   29.91 + * @see     TreeMap
   29.92 + * @since   1.2
   29.93 + */
   29.94 +
   29.95 +public class TreeSet<E> extends AbstractSet<E>
   29.96 +    implements NavigableSet<E>, Cloneable, java.io.Serializable
   29.97 +{
   29.98 +    /**
   29.99 +     * The backing map.
  29.100 +     */
  29.101 +    private transient NavigableMap<E,Object> m;
  29.102 +
  29.103 +    // Dummy value to associate with an Object in the backing Map
  29.104 +    private static final Object PRESENT = new Object();
  29.105 +
  29.106 +    /**
  29.107 +     * Constructs a set backed by the specified navigable map.
  29.108 +     */
  29.109 +    TreeSet(NavigableMap<E,Object> m) {
  29.110 +        this.m = m;
  29.111 +    }
  29.112 +
  29.113 +    /**
  29.114 +     * Constructs a new, empty tree set, sorted according to the
  29.115 +     * natural ordering of its elements.  All elements inserted into
  29.116 +     * the set must implement the {@link Comparable} interface.
  29.117 +     * Furthermore, all such elements must be <i>mutually
  29.118 +     * comparable</i>: {@code e1.compareTo(e2)} must not throw a
  29.119 +     * {@code ClassCastException} for any elements {@code e1} and
  29.120 +     * {@code e2} in the set.  If the user attempts to add an element
  29.121 +     * to the set that violates this constraint (for example, the user
  29.122 +     * attempts to add a string element to a set whose elements are
  29.123 +     * integers), the {@code add} call will throw a
  29.124 +     * {@code ClassCastException}.
  29.125 +     */
  29.126 +    public TreeSet() {
  29.127 +        this(new TreeMap<E,Object>());
  29.128 +    }
  29.129 +
  29.130 +    /**
  29.131 +     * Constructs a new, empty tree set, sorted according to the specified
  29.132 +     * comparator.  All elements inserted into the set must be <i>mutually
  29.133 +     * comparable</i> by the specified comparator: {@code comparator.compare(e1,
  29.134 +     * e2)} must not throw a {@code ClassCastException} for any elements
  29.135 +     * {@code e1} and {@code e2} in the set.  If the user attempts to add
  29.136 +     * an element to the set that violates this constraint, the
  29.137 +     * {@code add} call will throw a {@code ClassCastException}.
  29.138 +     *
  29.139 +     * @param comparator the comparator that will be used to order this set.
  29.140 +     *        If {@code null}, the {@linkplain Comparable natural
  29.141 +     *        ordering} of the elements will be used.
  29.142 +     */
  29.143 +    public TreeSet(Comparator<? super E> comparator) {
  29.144 +        this(new TreeMap<>(comparator));
  29.145 +    }
  29.146 +
  29.147 +    /**
  29.148 +     * Constructs a new tree set containing the elements in the specified
  29.149 +     * collection, sorted according to the <i>natural ordering</i> of its
  29.150 +     * elements.  All elements inserted into the set must implement the
  29.151 +     * {@link Comparable} interface.  Furthermore, all such elements must be
  29.152 +     * <i>mutually comparable</i>: {@code e1.compareTo(e2)} must not throw a
  29.153 +     * {@code ClassCastException} for any elements {@code e1} and
  29.154 +     * {@code e2} in the set.
  29.155 +     *
  29.156 +     * @param c collection whose elements will comprise the new set
  29.157 +     * @throws ClassCastException if the elements in {@code c} are
  29.158 +     *         not {@link Comparable}, or are not mutually comparable
  29.159 +     * @throws NullPointerException if the specified collection is null
  29.160 +     */
  29.161 +    public TreeSet(Collection<? extends E> c) {
  29.162 +        this();
  29.163 +        addAll(c);
  29.164 +    }
  29.165 +
  29.166 +    /**
  29.167 +     * Constructs a new tree set containing the same elements and
  29.168 +     * using the same ordering as the specified sorted set.
  29.169 +     *
  29.170 +     * @param s sorted set whose elements will comprise the new set
  29.171 +     * @throws NullPointerException if the specified sorted set is null
  29.172 +     */
  29.173 +    public TreeSet(SortedSet<E> s) {
  29.174 +        this(s.comparator());
  29.175 +        addAll(s);
  29.176 +    }
  29.177 +
  29.178 +    /**
  29.179 +     * Returns an iterator over the elements in this set in ascending order.
  29.180 +     *
  29.181 +     * @return an iterator over the elements in this set in ascending order
  29.182 +     */
  29.183 +    public Iterator<E> iterator() {
  29.184 +        return m.navigableKeySet().iterator();
  29.185 +    }
  29.186 +
  29.187 +    /**
  29.188 +     * Returns an iterator over the elements in this set in descending order.
  29.189 +     *
  29.190 +     * @return an iterator over the elements in this set in descending order
  29.191 +     * @since 1.6
  29.192 +     */
  29.193 +    public Iterator<E> descendingIterator() {
  29.194 +        return m.descendingKeySet().iterator();
  29.195 +    }
  29.196 +
  29.197 +    /**
  29.198 +     * @since 1.6
  29.199 +     */
  29.200 +    public NavigableSet<E> descendingSet() {
  29.201 +        return new TreeSet<>(m.descendingMap());
  29.202 +    }
  29.203 +
  29.204 +    /**
  29.205 +     * Returns the number of elements in this set (its cardinality).
  29.206 +     *
  29.207 +     * @return the number of elements in this set (its cardinality)
  29.208 +     */
  29.209 +    public int size() {
  29.210 +        return m.size();
  29.211 +    }
  29.212 +
  29.213 +    /**
  29.214 +     * Returns {@code true} if this set contains no elements.
  29.215 +     *
  29.216 +     * @return {@code true} if this set contains no elements
  29.217 +     */
  29.218 +    public boolean isEmpty() {
  29.219 +        return m.isEmpty();
  29.220 +    }
  29.221 +
  29.222 +    /**
  29.223 +     * Returns {@code true} if this set contains the specified element.
  29.224 +     * More formally, returns {@code true} if and only if this set
  29.225 +     * contains an element {@code e} such that
  29.226 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
  29.227 +     *
  29.228 +     * @param o object to be checked for containment in this set
  29.229 +     * @return {@code true} if this set contains the specified element
  29.230 +     * @throws ClassCastException if the specified object cannot be compared
  29.231 +     *         with the elements currently in the set
  29.232 +     * @throws NullPointerException if the specified element is null
  29.233 +     *         and this set uses natural ordering, or its comparator
  29.234 +     *         does not permit null elements
  29.235 +     */
  29.236 +    public boolean contains(Object o) {
  29.237 +        return m.containsKey(o);
  29.238 +    }
  29.239 +
  29.240 +    /**
  29.241 +     * Adds the specified element to this set if it is not already present.
  29.242 +     * More formally, adds the specified element {@code e} to this set if
  29.243 +     * the set contains no element {@code e2} such that
  29.244 +     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
  29.245 +     * If this set already contains the element, the call leaves the set
  29.246 +     * unchanged and returns {@code false}.
  29.247 +     *
  29.248 +     * @param e element to be added to this set
  29.249 +     * @return {@code true} if this set did not already contain the specified
  29.250 +     *         element
  29.251 +     * @throws ClassCastException if the specified object cannot be compared
  29.252 +     *         with the elements currently in this set
  29.253 +     * @throws NullPointerException if the specified element is null
  29.254 +     *         and this set uses natural ordering, or its comparator
  29.255 +     *         does not permit null elements
  29.256 +     */
  29.257 +    public boolean add(E e) {
  29.258 +        return m.put(e, PRESENT)==null;
  29.259 +    }
  29.260 +
  29.261 +    /**
  29.262 +     * Removes the specified element from this set if it is present.
  29.263 +     * More formally, removes an element {@code e} such that
  29.264 +     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
  29.265 +     * if this set contains such an element.  Returns {@code true} if
  29.266 +     * this set contained the element (or equivalently, if this set
  29.267 +     * changed as a result of the call).  (This set will not contain the
  29.268 +     * element once the call returns.)
  29.269 +     *
  29.270 +     * @param o object to be removed from this set, if present
  29.271 +     * @return {@code true} if this set contained the specified element
  29.272 +     * @throws ClassCastException if the specified object cannot be compared
  29.273 +     *         with the elements currently in this set
  29.274 +     * @throws NullPointerException if the specified element is null
  29.275 +     *         and this set uses natural ordering, or its comparator
  29.276 +     *         does not permit null elements
  29.277 +     */
  29.278 +    public boolean remove(Object o) {
  29.279 +        return m.remove(o)==PRESENT;
  29.280 +    }
  29.281 +
  29.282 +    /**
  29.283 +     * Removes all of the elements from this set.
  29.284 +     * The set will be empty after this call returns.
  29.285 +     */
  29.286 +    public void clear() {
  29.287 +        m.clear();
  29.288 +    }
  29.289 +
  29.290 +    /**
  29.291 +     * Adds all of the elements in the specified collection to this set.
  29.292 +     *
  29.293 +     * @param c collection containing elements to be added to this set
  29.294 +     * @return {@code true} if this set changed as a result of the call
  29.295 +     * @throws ClassCastException if the elements provided cannot be compared
  29.296 +     *         with the elements currently in the set
  29.297 +     * @throws NullPointerException if the specified collection is null or
  29.298 +     *         if any element is null and this set uses natural ordering, or
  29.299 +     *         its comparator does not permit null elements
  29.300 +     */
  29.301 +    public  boolean addAll(Collection<? extends E> c) {
  29.302 +        // Use linear-time version if applicable
  29.303 +        if (m.size()==0 && c.size() > 0 &&
  29.304 +            c instanceof SortedSet &&
  29.305 +            m instanceof TreeMap) {
  29.306 +            SortedSet<? extends E> set = (SortedSet<? extends E>) c;
  29.307 +            TreeMap<E,Object> map = (TreeMap<E, Object>) m;
  29.308 +            Comparator<? super E> cc = (Comparator<? super E>) set.comparator();
  29.309 +            Comparator<? super E> mc = map.comparator();
  29.310 +            if (cc==mc || (cc != null && cc.equals(mc))) {
  29.311 +                map.addAllForTreeSet(set, PRESENT);
  29.312 +                return true;
  29.313 +            }
  29.314 +        }
  29.315 +        return super.addAll(c);
  29.316 +    }
  29.317 +
  29.318 +    /**
  29.319 +     * @throws ClassCastException {@inheritDoc}
  29.320 +     * @throws NullPointerException if {@code fromElement} or {@code toElement}
  29.321 +     *         is null and this set uses natural ordering, or its comparator
  29.322 +     *         does not permit null elements
  29.323 +     * @throws IllegalArgumentException {@inheritDoc}
  29.324 +     * @since 1.6
  29.325 +     */
  29.326 +    public NavigableSet<E> subSet(E fromElement, boolean fromInclusive,
  29.327 +                                  E toElement,   boolean toInclusive) {
  29.328 +        return new TreeSet<>(m.subMap(fromElement, fromInclusive,
  29.329 +                                       toElement,   toInclusive));
  29.330 +    }
  29.331 +
  29.332 +    /**
  29.333 +     * @throws ClassCastException {@inheritDoc}
  29.334 +     * @throws NullPointerException if {@code toElement} is null and
  29.335 +     *         this set uses natural ordering, or its comparator does
  29.336 +     *         not permit null elements
  29.337 +     * @throws IllegalArgumentException {@inheritDoc}
  29.338 +     * @since 1.6
  29.339 +     */
  29.340 +    public NavigableSet<E> headSet(E toElement, boolean inclusive) {
  29.341 +        return new TreeSet<>(m.headMap(toElement, inclusive));
  29.342 +    }
  29.343 +
  29.344 +    /**
  29.345 +     * @throws ClassCastException {@inheritDoc}
  29.346 +     * @throws NullPointerException if {@code fromElement} is null and
  29.347 +     *         this set uses natural ordering, or its comparator does
  29.348 +     *         not permit null elements
  29.349 +     * @throws IllegalArgumentException {@inheritDoc}
  29.350 +     * @since 1.6
  29.351 +     */
  29.352 +    public NavigableSet<E> tailSet(E fromElement, boolean inclusive) {
  29.353 +        return new TreeSet<>(m.tailMap(fromElement, inclusive));
  29.354 +    }
  29.355 +
  29.356 +    /**
  29.357 +     * @throws ClassCastException {@inheritDoc}
  29.358 +     * @throws NullPointerException if {@code fromElement} or
  29.359 +     *         {@code toElement} is null and this set uses natural ordering,
  29.360 +     *         or its comparator does not permit null elements
  29.361 +     * @throws IllegalArgumentException {@inheritDoc}
  29.362 +     */
  29.363 +    public SortedSet<E> subSet(E fromElement, E toElement) {
  29.364 +        return subSet(fromElement, true, toElement, false);
  29.365 +    }
  29.366 +
  29.367 +    /**
  29.368 +     * @throws ClassCastException {@inheritDoc}
  29.369 +     * @throws NullPointerException if {@code toElement} is null
  29.370 +     *         and this set uses natural ordering, or its comparator does
  29.371 +     *         not permit null elements
  29.372 +     * @throws IllegalArgumentException {@inheritDoc}
  29.373 +     */
  29.374 +    public SortedSet<E> headSet(E toElement) {
  29.375 +        return headSet(toElement, false);
  29.376 +    }
  29.377 +
  29.378 +    /**
  29.379 +     * @throws ClassCastException {@inheritDoc}
  29.380 +     * @throws NullPointerException if {@code fromElement} is null
  29.381 +     *         and this set uses natural ordering, or its comparator does
  29.382 +     *         not permit null elements
  29.383 +     * @throws IllegalArgumentException {@inheritDoc}
  29.384 +     */
  29.385 +    public SortedSet<E> tailSet(E fromElement) {
  29.386 +        return tailSet(fromElement, true);
  29.387 +    }
  29.388 +
  29.389 +    public Comparator<? super E> comparator() {
  29.390 +        return m.comparator();
  29.391 +    }
  29.392 +
  29.393 +    /**
  29.394 +     * @throws NoSuchElementException {@inheritDoc}
  29.395 +     */
  29.396 +    public E first() {
  29.397 +        return m.firstKey();
  29.398 +    }
  29.399 +
  29.400 +    /**
  29.401 +     * @throws NoSuchElementException {@inheritDoc}
  29.402 +     */
  29.403 +    public E last() {
  29.404 +        return m.lastKey();
  29.405 +    }
  29.406 +
  29.407 +    // NavigableSet API methods
  29.408 +
  29.409 +    /**
  29.410 +     * @throws ClassCastException {@inheritDoc}
  29.411 +     * @throws NullPointerException if the specified element is null
  29.412 +     *         and this set uses natural ordering, or its comparator
  29.413 +     *         does not permit null elements
  29.414 +     * @since 1.6
  29.415 +     */
  29.416 +    public E lower(E e) {
  29.417 +        return m.lowerKey(e);
  29.418 +    }
  29.419 +
  29.420 +    /**
  29.421 +     * @throws ClassCastException {@inheritDoc}
  29.422 +     * @throws NullPointerException if the specified element is null
  29.423 +     *         and this set uses natural ordering, or its comparator
  29.424 +     *         does not permit null elements
  29.425 +     * @since 1.6
  29.426 +     */
  29.427 +    public E floor(E e) {
  29.428 +        return m.floorKey(e);
  29.429 +    }
  29.430 +
  29.431 +    /**
  29.432 +     * @throws ClassCastException {@inheritDoc}
  29.433 +     * @throws NullPointerException if the specified element is null
  29.434 +     *         and this set uses natural ordering, or its comparator
  29.435 +     *         does not permit null elements
  29.436 +     * @since 1.6
  29.437 +     */
  29.438 +    public E ceiling(E e) {
  29.439 +        return m.ceilingKey(e);
  29.440 +    }
  29.441 +
  29.442 +    /**
  29.443 +     * @throws ClassCastException {@inheritDoc}
  29.444 +     * @throws NullPointerException if the specified element is null
  29.445 +     *         and this set uses natural ordering, or its comparator
  29.446 +     *         does not permit null elements
  29.447 +     * @since 1.6
  29.448 +     */
  29.449 +    public E higher(E e) {
  29.450 +        return m.higherKey(e);
  29.451 +    }
  29.452 +
  29.453 +    /**
  29.454 +     * @since 1.6
  29.455 +     */
  29.456 +    public E pollFirst() {
  29.457 +        Map.Entry<E,?> e = m.pollFirstEntry();
  29.458 +        return (e == null) ? null : e.getKey();
  29.459 +    }
  29.460 +
  29.461 +    /**
  29.462 +     * @since 1.6
  29.463 +     */
  29.464 +    public E pollLast() {
  29.465 +        Map.Entry<E,?> e = m.pollLastEntry();
  29.466 +        return (e == null) ? null : e.getKey();
  29.467 +    }
  29.468 +
  29.469 +    /**
  29.470 +     * Returns a shallow copy of this {@code TreeSet} instance. (The elements
  29.471 +     * themselves are not cloned.)
  29.472 +     *
  29.473 +     * @return a shallow copy of this set
  29.474 +     */
  29.475 +    public Object clone() {
  29.476 +        TreeSet<E> clone = null;
  29.477 +        try {
  29.478 +            clone = (TreeSet<E>) super.clone();
  29.479 +        } catch (CloneNotSupportedException e) {
  29.480 +            throw new InternalError();
  29.481 +        }
  29.482 +
  29.483 +        clone.m = new TreeMap<>(m);
  29.484 +        return clone;
  29.485 +    }
  29.486 +
  29.487 +    /**
  29.488 +     * Save the state of the {@code TreeSet} instance to a stream (that is,
  29.489 +     * serialize it).
  29.490 +     *
  29.491 +     * @serialData Emits the comparator used to order this set, or
  29.492 +     *             {@code null} if it obeys its elements' natural ordering
  29.493 +     *             (Object), followed by the size of the set (the number of
  29.494 +     *             elements it contains) (int), followed by all of its
  29.495 +     *             elements (each an Object) in order (as determined by the
  29.496 +     *             set's Comparator, or by the elements' natural ordering if
  29.497 +     *             the set has no Comparator).
  29.498 +     */
  29.499 +    private void writeObject(java.io.ObjectOutputStream s)
  29.500 +        throws java.io.IOException {
  29.501 +        // Write out any hidden stuff
  29.502 +        s.defaultWriteObject();
  29.503 +
  29.504 +        // Write out Comparator
  29.505 +        s.writeObject(m.comparator());
  29.506 +
  29.507 +        // Write out size
  29.508 +        s.writeInt(m.size());
  29.509 +
  29.510 +        // Write out all elements in the proper order.
  29.511 +        for (E e : m.keySet())
  29.512 +            s.writeObject(e);
  29.513 +    }
  29.514 +
  29.515 +    /**
  29.516 +     * Reconstitute the {@code TreeSet} instance from a stream (that is,
  29.517 +     * deserialize it).
  29.518 +     */
  29.519 +    private void readObject(java.io.ObjectInputStream s)
  29.520 +        throws java.io.IOException, ClassNotFoundException {
  29.521 +        // Read in any hidden stuff
  29.522 +        s.defaultReadObject();
  29.523 +
  29.524 +        // Read in Comparator
  29.525 +        Comparator<? super E> c = (Comparator<? super E>) s.readObject();
  29.526 +
  29.527 +        // Create backing TreeMap
  29.528 +        TreeMap<E,Object> tm;
  29.529 +        if (c==null)
  29.530 +            tm = new TreeMap<>();
  29.531 +        else
  29.532 +            tm = new TreeMap<>(c);
  29.533 +        m = tm;
  29.534 +
  29.535 +        // Read in size
  29.536 +        int size = s.readInt();
  29.537 +
  29.538 +        tm.readTreeSet(size, s, PRESENT);
  29.539 +    }
  29.540 +
  29.541 +    private static final long serialVersionUID = -2479143000061671589L;
  29.542 +}
    30.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.2 +++ b/rt/emul/compact/src/main/java/java/util/WeakHashMap.java	Sat Sep 07 13:55:09 2013 +0200
    30.3 @@ -0,0 +1,972 @@
    30.4 +/*
    30.5 + * Copyright (c) 1998, 2010, 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.util;
   30.30 +import java.lang.ref.WeakReference;
   30.31 +import java.lang.ref.ReferenceQueue;
   30.32 +
   30.33 +
   30.34 +/**
   30.35 + * Hash table based implementation of the <tt>Map</tt> interface, with
   30.36 + * <em>weak keys</em>.
   30.37 + * An entry in a <tt>WeakHashMap</tt> will automatically be removed when
   30.38 + * its key is no longer in ordinary use.  More precisely, the presence of a
   30.39 + * mapping for a given key will not prevent the key from being discarded by the
   30.40 + * garbage collector, that is, made finalizable, finalized, and then reclaimed.
   30.41 + * When a key has been discarded its entry is effectively removed from the map,
   30.42 + * so this class behaves somewhat differently from other <tt>Map</tt>
   30.43 + * implementations.
   30.44 + *
   30.45 + * <p> Both null values and the null key are supported. This class has
   30.46 + * performance characteristics similar to those of the <tt>HashMap</tt>
   30.47 + * class, and has the same efficiency parameters of <em>initial capacity</em>
   30.48 + * and <em>load factor</em>.
   30.49 + *
   30.50 + * <p> Like most collection classes, this class is not synchronized.
   30.51 + * A synchronized <tt>WeakHashMap</tt> may be constructed using the
   30.52 + * {@link Collections#synchronizedMap Collections.synchronizedMap}
   30.53 + * method.
   30.54 + *
   30.55 + * <p> This class is intended primarily for use with key objects whose
   30.56 + * <tt>equals</tt> methods test for object identity using the
   30.57 + * <tt>==</tt> operator.  Once such a key is discarded it can never be
   30.58 + * recreated, so it is impossible to do a lookup of that key in a
   30.59 + * <tt>WeakHashMap</tt> at some later time and be surprised that its entry
   30.60 + * has been removed.  This class will work perfectly well with key objects
   30.61 + * whose <tt>equals</tt> methods are not based upon object identity, such
   30.62 + * as <tt>String</tt> instances.  With such recreatable key objects,
   30.63 + * however, the automatic removal of <tt>WeakHashMap</tt> entries whose
   30.64 + * keys have been discarded may prove to be confusing.
   30.65 + *
   30.66 + * <p> The behavior of the <tt>WeakHashMap</tt> class depends in part upon
   30.67 + * the actions of the garbage collector, so several familiar (though not
   30.68 + * required) <tt>Map</tt> invariants do not hold for this class.  Because
   30.69 + * the garbage collector may discard keys at any time, a
   30.70 + * <tt>WeakHashMap</tt> may behave as though an unknown thread is silently
   30.71 + * removing entries.  In particular, even if you synchronize on a
   30.72 + * <tt>WeakHashMap</tt> instance and invoke none of its mutator methods, it
   30.73 + * is possible for the <tt>size</tt> method to return smaller values over
   30.74 + * time, for the <tt>isEmpty</tt> method to return <tt>false</tt> and
   30.75 + * then <tt>true</tt>, for the <tt>containsKey</tt> method to return
   30.76 + * <tt>true</tt> and later <tt>false</tt> for a given key, for the
   30.77 + * <tt>get</tt> method to return a value for a given key but later return
   30.78 + * <tt>null</tt>, for the <tt>put</tt> method to return
   30.79 + * <tt>null</tt> and the <tt>remove</tt> method to return
   30.80 + * <tt>false</tt> for a key that previously appeared to be in the map, and
   30.81 + * for successive examinations of the key set, the value collection, and
   30.82 + * the entry set to yield successively smaller numbers of elements.
   30.83 + *
   30.84 + * <p> Each key object in a <tt>WeakHashMap</tt> is stored indirectly as
   30.85 + * the referent of a weak reference.  Therefore a key will automatically be
   30.86 + * removed only after the weak references to it, both inside and outside of the
   30.87 + * map, have been cleared by the garbage collector.
   30.88 + *
   30.89 + * <p> <strong>Implementation note:</strong> The value objects in a
   30.90 + * <tt>WeakHashMap</tt> are held by ordinary strong references.  Thus care
   30.91 + * should be taken to ensure that value objects do not strongly refer to their
   30.92 + * own keys, either directly or indirectly, since that will prevent the keys
   30.93 + * from being discarded.  Note that a value object may refer indirectly to its
   30.94 + * key via the <tt>WeakHashMap</tt> itself; that is, a value object may
   30.95 + * strongly refer to some other key object whose associated value object, in
   30.96 + * turn, strongly refers to the key of the first value object.  One way
   30.97 + * to deal with this is to wrap values themselves within
   30.98 + * <tt>WeakReferences</tt> before
   30.99 + * inserting, as in: <tt>m.put(key, new WeakReference(value))</tt>,
  30.100 + * and then unwrapping upon each <tt>get</tt>.
  30.101 + *
  30.102 + * <p>The iterators returned by the <tt>iterator</tt> method of the collections
  30.103 + * returned by all of this class's "collection view methods" are
  30.104 + * <i>fail-fast</i>: if the map is structurally modified at any time after the
  30.105 + * iterator is created, in any way except through the iterator's own
  30.106 + * <tt>remove</tt> method, the iterator will throw a {@link
  30.107 + * ConcurrentModificationException}.  Thus, in the face of concurrent
  30.108 + * modification, the iterator fails quickly and cleanly, rather than risking
  30.109 + * arbitrary, non-deterministic behavior at an undetermined time in the future.
  30.110 + *
  30.111 + * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  30.112 + * as it is, generally speaking, impossible to make any hard guarantees in the
  30.113 + * presence of unsynchronized concurrent modification.  Fail-fast iterators
  30.114 + * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
  30.115 + * Therefore, it would be wrong to write a program that depended on this
  30.116 + * exception for its correctness:  <i>the fail-fast behavior of iterators
  30.117 + * should be used only to detect bugs.</i>
  30.118 + *
  30.119 + * <p>This class is a member of the
  30.120 + * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  30.121 + * Java Collections Framework</a>.
  30.122 + *
  30.123 + * @param <K> the type of keys maintained by this map
  30.124 + * @param <V> the type of mapped values
  30.125 + *
  30.126 + * @author      Doug Lea
  30.127 + * @author      Josh Bloch
  30.128 + * @author      Mark Reinhold
  30.129 + * @since       1.2
  30.130 + * @see         java.util.HashMap
  30.131 + * @see         java.lang.ref.WeakReference
  30.132 + */
  30.133 +public class WeakHashMap<K,V>
  30.134 +    extends AbstractMap<K,V>
  30.135 +    implements Map<K,V> {
  30.136 +
  30.137 +    /**
  30.138 +     * The default initial capacity -- MUST be a power of two.
  30.139 +     */
  30.140 +    private static final int DEFAULT_INITIAL_CAPACITY = 16;
  30.141 +
  30.142 +    /**
  30.143 +     * The maximum capacity, used if a higher value is implicitly specified
  30.144 +     * by either of the constructors with arguments.
  30.145 +     * MUST be a power of two <= 1<<30.
  30.146 +     */
  30.147 +    private static final int MAXIMUM_CAPACITY = 1 << 30;
  30.148 +
  30.149 +    /**
  30.150 +     * The load factor used when none specified in constructor.
  30.151 +     */
  30.152 +    private static final float DEFAULT_LOAD_FACTOR = 0.75f;
  30.153 +
  30.154 +    /**
  30.155 +     * The table, resized as necessary. Length MUST Always be a power of two.
  30.156 +     */
  30.157 +    Entry<K,V>[] table;
  30.158 +
  30.159 +    /**
  30.160 +     * The number of key-value mappings contained in this weak hash map.
  30.161 +     */
  30.162 +    private int size;
  30.163 +
  30.164 +    /**
  30.165 +     * The next size value at which to resize (capacity * load factor).
  30.166 +     */
  30.167 +    private int threshold;
  30.168 +
  30.169 +    /**
  30.170 +     * The load factor for the hash table.
  30.171 +     */
  30.172 +    private final float loadFactor;
  30.173 +
  30.174 +    /**
  30.175 +     * Reference queue for cleared WeakEntries
  30.176 +     */
  30.177 +    private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
  30.178 +
  30.179 +    /**
  30.180 +     * The number of times this WeakHashMap has been structurally modified.
  30.181 +     * Structural modifications are those that change the number of
  30.182 +     * mappings in the map or otherwise modify its internal structure
  30.183 +     * (e.g., rehash).  This field is used to make iterators on
  30.184 +     * Collection-views of the map fail-fast.
  30.185 +     *
  30.186 +     * @see ConcurrentModificationException
  30.187 +     */
  30.188 +    int modCount;
  30.189 +
  30.190 +    @SuppressWarnings("unchecked")
  30.191 +    private Entry<K,V>[] newTable(int n) {
  30.192 +        return (Entry<K,V>[]) new Entry[n];
  30.193 +    }
  30.194 +
  30.195 +    /**
  30.196 +     * Constructs a new, empty <tt>WeakHashMap</tt> with the given initial
  30.197 +     * capacity and the given load factor.
  30.198 +     *
  30.199 +     * @param  initialCapacity The initial capacity of the <tt>WeakHashMap</tt>
  30.200 +     * @param  loadFactor      The load factor of the <tt>WeakHashMap</tt>
  30.201 +     * @throws IllegalArgumentException if the initial capacity is negative,
  30.202 +     *         or if the load factor is nonpositive.
  30.203 +     */
  30.204 +    public WeakHashMap(int initialCapacity, float loadFactor) {
  30.205 +        if (initialCapacity < 0)
  30.206 +            throw new IllegalArgumentException("Illegal Initial Capacity: "+
  30.207 +                                               initialCapacity);
  30.208 +        if (initialCapacity > MAXIMUM_CAPACITY)
  30.209 +            initialCapacity = MAXIMUM_CAPACITY;
  30.210 +
  30.211 +        if (loadFactor <= 0 || Float.isNaN(loadFactor))
  30.212 +            throw new IllegalArgumentException("Illegal Load factor: "+
  30.213 +                                               loadFactor);
  30.214 +        int capacity = 1;
  30.215 +        while (capacity < initialCapacity)
  30.216 +            capacity <<= 1;
  30.217 +        table = newTable(capacity);
  30.218 +        this.loadFactor = loadFactor;
  30.219 +        threshold = (int)(capacity * loadFactor);
  30.220 +    }
  30.221 +
  30.222 +    /**
  30.223 +     * Constructs a new, empty <tt>WeakHashMap</tt> with the given initial
  30.224 +     * capacity and the default load factor (0.75).
  30.225 +     *
  30.226 +     * @param  initialCapacity The initial capacity of the <tt>WeakHashMap</tt>
  30.227 +     * @throws IllegalArgumentException if the initial capacity is negative
  30.228 +     */
  30.229 +    public WeakHashMap(int initialCapacity) {
  30.230 +        this(initialCapacity, DEFAULT_LOAD_FACTOR);
  30.231 +    }
  30.232 +
  30.233 +    /**
  30.234 +     * Constructs a new, empty <tt>WeakHashMap</tt> with the default initial
  30.235 +     * capacity (16) and load factor (0.75).
  30.236 +     */
  30.237 +    public WeakHashMap() {
  30.238 +        this.loadFactor = DEFAULT_LOAD_FACTOR;
  30.239 +        threshold = DEFAULT_INITIAL_CAPACITY;
  30.240 +        table = newTable(DEFAULT_INITIAL_CAPACITY);
  30.241 +    }
  30.242 +
  30.243 +    /**
  30.244 +     * Constructs a new <tt>WeakHashMap</tt> with the same mappings as the
  30.245 +     * specified map.  The <tt>WeakHashMap</tt> is created with the default
  30.246 +     * load factor (0.75) and an initial capacity sufficient to hold the
  30.247 +     * mappings in the specified map.
  30.248 +     *
  30.249 +     * @param   m the map whose mappings are to be placed in this map
  30.250 +     * @throws  NullPointerException if the specified map is null
  30.251 +     * @since   1.3
  30.252 +     */
  30.253 +    public WeakHashMap(Map<? extends K, ? extends V> m) {
  30.254 +        this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, 16),
  30.255 +             DEFAULT_LOAD_FACTOR);
  30.256 +        putAll(m);
  30.257 +    }
  30.258 +
  30.259 +    // internal utilities
  30.260 +
  30.261 +    /**
  30.262 +     * Value representing null keys inside tables.
  30.263 +     */
  30.264 +    private static final Object NULL_KEY = new Object();
  30.265 +
  30.266 +    /**
  30.267 +     * Use NULL_KEY for key if it is null.
  30.268 +     */
  30.269 +    private static Object maskNull(Object key) {
  30.270 +        return (key == null) ? NULL_KEY : key;
  30.271 +    }
  30.272 +
  30.273 +    /**
  30.274 +     * Returns internal representation of null key back to caller as null.
  30.275 +     */
  30.276 +    static Object unmaskNull(Object key) {
  30.277 +        return (key == NULL_KEY) ? null : key;
  30.278 +    }
  30.279 +
  30.280 +    /**
  30.281 +     * Checks for equality of non-null reference x and possibly-null y.  By
  30.282 +     * default uses Object.equals.
  30.283 +     */
  30.284 +    private static boolean eq(Object x, Object y) {
  30.285 +        return x == y || x.equals(y);
  30.286 +    }
  30.287 +
  30.288 +    /**
  30.289 +     * Returns index for hash code h.
  30.290 +     */
  30.291 +    private static int indexFor(int h, int length) {
  30.292 +        return h & (length-1);
  30.293 +    }
  30.294 +
  30.295 +    /**
  30.296 +     * Expunges stale entries from the table.
  30.297 +     */
  30.298 +    private void expungeStaleEntries() {
  30.299 +        for (Object x; (x = queue.poll()) != null; ) {
  30.300 +            synchronized (queue) {
  30.301 +                @SuppressWarnings("unchecked")
  30.302 +                    Entry<K,V> e = (Entry<K,V>) x;
  30.303 +                int i = indexFor(e.hash, table.length);
  30.304 +
  30.305 +                Entry<K,V> prev = table[i];
  30.306 +                Entry<K,V> p = prev;
  30.307 +                while (p != null) {
  30.308 +                    Entry<K,V> next = p.next;
  30.309 +                    if (p == e) {
  30.310 +                        if (prev == e)
  30.311 +                            table[i] = next;
  30.312 +                        else
  30.313 +                            prev.next = next;
  30.314 +                        // Must not null out e.next;
  30.315 +                        // stale entries may be in use by a HashIterator
  30.316 +                        e.value = null; // Help GC
  30.317 +                        size--;
  30.318 +                        break;
  30.319 +                    }
  30.320 +                    prev = p;
  30.321 +                    p = next;
  30.322 +                }
  30.323 +            }
  30.324 +        }
  30.325 +    }
  30.326 +
  30.327 +    /**
  30.328 +     * Returns the table after first expunging stale entries.
  30.329 +     */
  30.330 +    private Entry<K,V>[] getTable() {
  30.331 +        expungeStaleEntries();
  30.332 +        return table;
  30.333 +    }
  30.334 +
  30.335 +    /**
  30.336 +     * Returns the number of key-value mappings in this map.
  30.337 +     * This result is a snapshot, and may not reflect unprocessed
  30.338 +     * entries that will be removed before next attempted access
  30.339 +     * because they are no longer referenced.
  30.340 +     */
  30.341 +    public int size() {
  30.342 +        if (size == 0)
  30.343 +            return 0;
  30.344 +        expungeStaleEntries();
  30.345 +        return size;
  30.346 +    }
  30.347 +
  30.348 +    /**
  30.349 +     * Returns <tt>true</tt> if this map contains no key-value mappings.
  30.350 +     * This result is a snapshot, and may not reflect unprocessed
  30.351 +     * entries that will be removed before next attempted access
  30.352 +     * because they are no longer referenced.
  30.353 +     */
  30.354 +    public boolean isEmpty() {
  30.355 +        return size() == 0;
  30.356 +    }
  30.357 +
  30.358 +    /**
  30.359 +     * Returns the value to which the specified key is mapped,
  30.360 +     * or {@code null} if this map contains no mapping for the key.
  30.361 +     *
  30.362 +     * <p>More formally, if this map contains a mapping from a key
  30.363 +     * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
  30.364 +     * key.equals(k))}, then this method returns {@code v}; otherwise
  30.365 +     * it returns {@code null}.  (There can be at most one such mapping.)
  30.366 +     *
  30.367 +     * <p>A return value of {@code null} does not <i>necessarily</i>
  30.368 +     * indicate that the map contains no mapping for the key; it's also
  30.369 +     * possible that the map explicitly maps the key to {@code null}.
  30.370 +     * The {@link #containsKey containsKey} operation may be used to
  30.371 +     * distinguish these two cases.
  30.372 +     *
  30.373 +     * @see #put(Object, Object)
  30.374 +     */
  30.375 +    public V get(Object key) {
  30.376 +        Object k = maskNull(key);
  30.377 +        int h = HashMap.hash(k.hashCode());
  30.378 +        Entry<K,V>[] tab = getTable();
  30.379 +        int index = indexFor(h, tab.length);
  30.380 +        Entry<K,V> e = tab[index];
  30.381 +        while (e != null) {
  30.382 +            if (e.hash == h && eq(k, e.get()))
  30.383 +                return e.value;
  30.384 +            e = e.next;
  30.385 +        }
  30.386 +        return null;
  30.387 +    }
  30.388 +
  30.389 +    /**
  30.390 +     * Returns <tt>true</tt> if this map contains a mapping for the
  30.391 +     * specified key.
  30.392 +     *
  30.393 +     * @param  key   The key whose presence in this map is to be tested
  30.394 +     * @return <tt>true</tt> if there is a mapping for <tt>key</tt>;
  30.395 +     *         <tt>false</tt> otherwise
  30.396 +     */
  30.397 +    public boolean containsKey(Object key) {
  30.398 +        return getEntry(key) != null;
  30.399 +    }
  30.400 +
  30.401 +    /**
  30.402 +     * Returns the entry associated with the specified key in this map.
  30.403 +     * Returns null if the map contains no mapping for this key.
  30.404 +     */
  30.405 +    Entry<K,V> getEntry(Object key) {
  30.406 +        Object k = maskNull(key);
  30.407 +        int h = HashMap.hash(k.hashCode());
  30.408 +        Entry<K,V>[] tab = getTable();
  30.409 +        int index = indexFor(h, tab.length);
  30.410 +        Entry<K,V> e = tab[index];
  30.411 +        while (e != null && !(e.hash == h && eq(k, e.get())))
  30.412 +            e = e.next;
  30.413 +        return e;
  30.414 +    }
  30.415 +
  30.416 +    /**
  30.417 +     * Associates the specified value with the specified key in this map.
  30.418 +     * If the map previously contained a mapping for this key, the old
  30.419 +     * value is replaced.
  30.420 +     *
  30.421 +     * @param key key with which the specified value is to be associated.
  30.422 +     * @param value value to be associated with the specified key.
  30.423 +     * @return the previous value associated with <tt>key</tt>, or
  30.424 +     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
  30.425 +     *         (A <tt>null</tt> return can also indicate that the map
  30.426 +     *         previously associated <tt>null</tt> with <tt>key</tt>.)
  30.427 +     */
  30.428 +    public V put(K key, V value) {
  30.429 +        Object k = maskNull(key);
  30.430 +        int h = HashMap.hash(k.hashCode());
  30.431 +        Entry<K,V>[] tab = getTable();
  30.432 +        int i = indexFor(h, tab.length);
  30.433 +
  30.434 +        for (Entry<K,V> e = tab[i]; e != null; e = e.next) {
  30.435 +            if (h == e.hash && eq(k, e.get())) {
  30.436 +                V oldValue = e.value;
  30.437 +                if (value != oldValue)
  30.438 +                    e.value = value;
  30.439 +                return oldValue;
  30.440 +            }
  30.441 +        }
  30.442 +
  30.443 +        modCount++;
  30.444 +        Entry<K,V> e = tab[i];
  30.445 +        tab[i] = new Entry<>(k, value, queue, h, e);
  30.446 +        if (++size >= threshold)
  30.447 +            resize(tab.length * 2);
  30.448 +        return null;
  30.449 +    }
  30.450 +
  30.451 +    /**
  30.452 +     * Rehashes the contents of this map into a new array with a
  30.453 +     * larger capacity.  This method is called automatically when the
  30.454 +     * number of keys in this map reaches its threshold.
  30.455 +     *
  30.456 +     * If current capacity is MAXIMUM_CAPACITY, this method does not
  30.457 +     * resize the map, but sets threshold to Integer.MAX_VALUE.
  30.458 +     * This has the effect of preventing future calls.
  30.459 +     *
  30.460 +     * @param newCapacity the new capacity, MUST be a power of two;
  30.461 +     *        must be greater than current capacity unless current
  30.462 +     *        capacity is MAXIMUM_CAPACITY (in which case value
  30.463 +     *        is irrelevant).
  30.464 +     */
  30.465 +    void resize(int newCapacity) {
  30.466 +        Entry<K,V>[] oldTable = getTable();
  30.467 +        int oldCapacity = oldTable.length;
  30.468 +        if (oldCapacity == MAXIMUM_CAPACITY) {
  30.469 +            threshold = Integer.MAX_VALUE;
  30.470 +            return;
  30.471 +        }
  30.472 +
  30.473 +        Entry<K,V>[] newTable = newTable(newCapacity);
  30.474 +        transfer(oldTable, newTable);
  30.475 +        table = newTable;
  30.476 +
  30.477 +        /*
  30.478 +         * If ignoring null elements and processing ref queue caused massive
  30.479 +         * shrinkage, then restore old table.  This should be rare, but avoids
  30.480 +         * unbounded expansion of garbage-filled tables.
  30.481 +         */
  30.482 +        if (size >= threshold / 2) {
  30.483 +            threshold = (int)(newCapacity * loadFactor);
  30.484 +        } else {
  30.485 +            expungeStaleEntries();
  30.486 +            transfer(newTable, oldTable);
  30.487 +            table = oldTable;
  30.488 +        }
  30.489 +    }
  30.490 +
  30.491 +    /** Transfers all entries from src to dest tables */
  30.492 +    private void transfer(Entry<K,V>[] src, Entry<K,V>[] dest) {
  30.493 +        for (int j = 0; j < src.length; ++j) {
  30.494 +            Entry<K,V> e = src[j];
  30.495 +            src[j] = null;
  30.496 +            while (e != null) {
  30.497 +                Entry<K,V> next = e.next;
  30.498 +                Object key = e.get();
  30.499 +                if (key == null) {
  30.500 +                    e.next = null;  // Help GC
  30.501 +                    e.value = null; //  "   "
  30.502 +                    size--;
  30.503 +                } else {
  30.504 +                    int i = indexFor(e.hash, dest.length);
  30.505 +                    e.next = dest[i];
  30.506 +                    dest[i] = e;
  30.507 +                }
  30.508 +                e = next;
  30.509 +            }
  30.510 +        }
  30.511 +    }
  30.512 +
  30.513 +    /**
  30.514 +     * Copies all of the mappings from the specified map to this map.
  30.515 +     * These mappings will replace any mappings that this map had for any
  30.516 +     * of the keys currently in the specified map.
  30.517 +     *
  30.518 +     * @param m mappings to be stored in this map.
  30.519 +     * @throws  NullPointerException if the specified map is null.
  30.520 +     */
  30.521 +    public void putAll(Map<? extends K, ? extends V> m) {
  30.522 +        int numKeysToBeAdded = m.size();
  30.523 +        if (numKeysToBeAdded == 0)
  30.524 +            return;
  30.525 +
  30.526 +        /*
  30.527 +         * Expand the map if the map if the number of mappings to be added
  30.528 +         * is greater than or equal to threshold.  This is conservative; the
  30.529 +         * obvious condition is (m.size() + size) >= threshold, but this
  30.530 +         * condition could result in a map with twice the appropriate capacity,
  30.531 +         * if the keys to be added overlap with the keys already in this map.
  30.532 +         * By using the conservative calculation, we subject ourself
  30.533 +         * to at most one extra resize.
  30.534 +         */
  30.535 +        if (numKeysToBeAdded > threshold) {
  30.536 +            int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
  30.537 +            if (targetCapacity > MAXIMUM_CAPACITY)
  30.538 +                targetCapacity = MAXIMUM_CAPACITY;
  30.539 +            int newCapacity = table.length;
  30.540 +            while (newCapacity < targetCapacity)
  30.541 +                newCapacity <<= 1;
  30.542 +            if (newCapacity > table.length)
  30.543 +                resize(newCapacity);
  30.544 +        }
  30.545 +
  30.546 +        for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
  30.547 +            put(e.getKey(), e.getValue());
  30.548 +    }
  30.549 +
  30.550 +    /**
  30.551 +     * Removes the mapping for a key from this weak hash map if it is present.
  30.552 +     * More formally, if this map contains a mapping from key <tt>k</tt> to
  30.553 +     * value <tt>v</tt> such that <code>(key==null ?  k==null :
  30.554 +     * key.equals(k))</code>, that mapping is removed.  (The map can contain
  30.555 +     * at most one such mapping.)
  30.556 +     *
  30.557 +     * <p>Returns the value to which this map previously associated the key,
  30.558 +     * or <tt>null</tt> if the map contained no mapping for the key.  A
  30.559 +     * return value of <tt>null</tt> does not <i>necessarily</i> indicate
  30.560 +     * that the map contained no mapping for the key; it's also possible
  30.561 +     * that the map explicitly mapped the key to <tt>null</tt>.
  30.562 +     *
  30.563 +     * <p>The map will not contain a mapping for the specified key once the
  30.564 +     * call returns.
  30.565 +     *
  30.566 +     * @param key key whose mapping is to be removed from the map
  30.567 +     * @return the previous value associated with <tt>key</tt>, or
  30.568 +     *         <tt>null</tt> if there was no mapping for <tt>key</tt>
  30.569 +     */
  30.570 +    public V remove(Object key) {
  30.571 +        Object k = maskNull(key);
  30.572 +        int h = HashMap.hash(k.hashCode());
  30.573 +        Entry<K,V>[] tab = getTable();
  30.574 +        int i = indexFor(h, tab.length);
  30.575 +        Entry<K,V> prev = tab[i];
  30.576 +        Entry<K,V> e = prev;
  30.577 +
  30.578 +        while (e != null) {
  30.579 +            Entry<K,V> next = e.next;
  30.580 +            if (h == e.hash && eq(k, e.get())) {
  30.581 +                modCount++;
  30.582 +                size--;
  30.583 +                if (prev == e)
  30.584 +                    tab[i] = next;
  30.585 +                else
  30.586 +                    prev.next = next;
  30.587 +                return e.value;
  30.588 +            }
  30.589 +            prev = e;
  30.590 +            e = next;
  30.591 +        }
  30.592 +
  30.593 +        return null;
  30.594 +    }
  30.595 +
  30.596 +    /** Special version of remove needed by Entry set */
  30.597 +    boolean removeMapping(Object o) {
  30.598 +        if (!(o instanceof Map.Entry))
  30.599 +            return false;
  30.600 +        Entry<K,V>[] tab = getTable();
  30.601 +        Map.Entry<?,?> entry = (Map.Entry<?,?>)o;
  30.602 +        Object k = maskNull(entry.getKey());
  30.603 +        int h = HashMap.hash(k.hashCode());
  30.604 +        int i = indexFor(h, tab.length);
  30.605 +        Entry<K,V> prev = tab[i];
  30.606 +        Entry<K,V> e = prev;
  30.607 +
  30.608 +        while (e != null) {
  30.609 +            Entry<K,V> next = e.next;
  30.610 +            if (h == e.hash && e.equals(entry)) {
  30.611 +                modCount++;
  30.612 +                size--;
  30.613 +                if (prev == e)
  30.614 +                    tab[i] = next;
  30.615 +                else
  30.616 +                    prev.next = next;
  30.617 +                return true;
  30.618 +            }
  30.619 +            prev = e;
  30.620 +            e = next;
  30.621 +        }
  30.622 +
  30.623 +        return false;
  30.624 +    }
  30.625 +
  30.626 +    /**
  30.627 +     * Removes all of the mappings from this map.
  30.628 +     * The map will be empty after this call returns.
  30.629 +     */
  30.630 +    public void clear() {
  30.631 +        // clear out ref queue. We don't need to expunge entries
  30.632 +        // since table is getting cleared.
  30.633 +        while (queue.poll() != null)
  30.634 +            ;
  30.635 +
  30.636 +        modCount++;
  30.637 +        Arrays.fill(table, null);
  30.638 +        size = 0;
  30.639 +
  30.640 +        // Allocation of array may have caused GC, which may have caused
  30.641 +        // additional entries to go stale.  Removing these entries from the
  30.642 +        // reference queue will make them eligible for reclamation.
  30.643 +        while (queue.poll() != null)
  30.644 +            ;
  30.645 +    }
  30.646 +
  30.647 +    /**
  30.648 +     * Returns <tt>true</tt> if this map maps one or more keys to the
  30.649 +     * specified value.
  30.650 +     *
  30.651 +     * @param value value whose presence in this map is to be tested
  30.652 +     * @return <tt>true</tt> if this map maps one or more keys to the
  30.653 +     *         specified value
  30.654 +     */
  30.655 +    public boolean containsValue(Object value) {
  30.656 +        if (value==null)
  30.657 +            return containsNullValue();
  30.658 +
  30.659 +        Entry<K,V>[] tab = getTable();
  30.660 +        for (int i = tab.length; i-- > 0;)
  30.661 +            for (Entry<K,V> e = tab[i]; e != null; e = e.next)
  30.662 +                if (value.equals(e.value))
  30.663 +                    return true;
  30.664 +        return false;
  30.665 +    }
  30.666 +
  30.667 +    /**
  30.668 +     * Special-case code for containsValue with null argument
  30.669 +     */
  30.670 +    private boolean containsNullValue() {
  30.671 +        Entry<K,V>[] tab = getTable();
  30.672 +        for (int i = tab.length; i-- > 0;)
  30.673 +            for (Entry<K,V> e = tab[i]; e != null; e = e.next)
  30.674 +                if (e.value==null)
  30.675 +                    return true;
  30.676 +        return false;
  30.677 +    }
  30.678 +
  30.679 +    /**
  30.680 +     * The entries in this hash table extend WeakReference, using its main ref
  30.681 +     * field as the key.
  30.682 +     */
  30.683 +    private static class Entry<K,V> extends WeakReference<Object> implements Map.Entry<K,V> {
  30.684 +        V value;
  30.685 +        final int hash;
  30.686 +        Entry<K,V> next;
  30.687 +
  30.688 +        /**
  30.689 +         * Creates new entry.
  30.690 +         */
  30.691 +        Entry(Object key, V value,
  30.692 +              ReferenceQueue<Object> queue,
  30.693 +              int hash, Entry<K,V> next) {
  30.694 +            super(key, queue);
  30.695 +            this.value = value;
  30.696 +            this.hash  = hash;
  30.697 +            this.next  = next;
  30.698 +        }
  30.699 +
  30.700 +        @SuppressWarnings("unchecked")
  30.701 +        public K getKey() {
  30.702 +            return (K) WeakHashMap.unmaskNull(get());
  30.703 +        }
  30.704 +
  30.705 +        public V getValue() {
  30.706 +            return value;
  30.707 +        }
  30.708 +
  30.709 +        public V setValue(V newValue) {
  30.710 +            V oldValue = value;
  30.711 +            value = newValue;
  30.712 +            return oldValue;
  30.713 +        }
  30.714 +
  30.715 +        public boolean equals(Object o) {
  30.716 +            if (!(o instanceof Map.Entry))
  30.717 +                return false;
  30.718 +            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
  30.719 +            K k1 = getKey();
  30.720 +            Object k2 = e.getKey();
  30.721 +            if (k1 == k2 || (k1 != null && k1.equals(k2))) {
  30.722 +                V v1 = getValue();
  30.723 +                Object v2 = e.getValue();
  30.724 +                if (v1 == v2 || (v1 != null && v1.equals(v2)))
  30.725 +                    return true;
  30.726 +            }
  30.727 +            return false;
  30.728 +        }
  30.729 +
  30.730 +        public int hashCode() {
  30.731 +            K k = getKey();
  30.732 +            V v = getValue();
  30.733 +            return ((k==null ? 0 : k.hashCode()) ^
  30.734 +                    (v==null ? 0 : v.hashCode()));
  30.735 +        }
  30.736 +
  30.737 +        public String toString() {
  30.738 +            return getKey() + "=" + getValue();
  30.739 +        }
  30.740 +    }
  30.741 +
  30.742 +    private abstract class HashIterator<T> implements Iterator<T> {
  30.743 +        private int index;
  30.744 +        private Entry<K,V> entry = null;
  30.745 +        private Entry<K,V> lastReturned = null;
  30.746 +        private int expectedModCount = modCount;
  30.747 +
  30.748 +        /**
  30.749 +         * Strong reference needed to avoid disappearance of key
  30.750 +         * between hasNext and next
  30.751 +         */
  30.752 +        private Object nextKey = null;
  30.753 +
  30.754 +        /**
  30.755 +         * Strong reference needed to avoid disappearance of key
  30.756 +         * between nextEntry() and any use of the entry
  30.757 +         */
  30.758 +        private Object currentKey = null;
  30.759 +
  30.760 +        HashIterator() {
  30.761 +            index = isEmpty() ? 0 : table.length;
  30.762 +        }
  30.763 +
  30.764 +        public boolean hasNext() {
  30.765 +            Entry<K,V>[] t = table;
  30.766 +
  30.767 +            while (nextKey == null) {
  30.768 +                Entry<K,V> e = entry;
  30.769 +                int i = index;
  30.770 +                while (e == null && i > 0)
  30.771 +                    e = t[--i];
  30.772 +                entry = e;
  30.773 +                index = i;
  30.774 +                if (e == null) {
  30.775 +                    currentKey = null;
  30.776 +                    return false;
  30.777 +                }
  30.778 +                nextKey = e.get(); // hold on to key in strong ref
  30.779 +                if (nextKey == null)
  30.780 +                    entry = entry.next;
  30.781 +            }
  30.782 +            return true;
  30.783 +        }
  30.784 +
  30.785 +        /** The common parts of next() across different types of iterators */
  30.786 +        protected Entry<K,V> nextEntry() {
  30.787 +            if (modCount != expectedModCount)
  30.788 +                throw new ConcurrentModificationException();
  30.789 +            if (nextKey == null && !hasNext())
  30.790 +                throw new NoSuchElementException();
  30.791 +
  30.792 +            lastReturned = entry;
  30.793 +            entry = entry.next;
  30.794 +            currentKey = nextKey;
  30.795 +            nextKey = null;
  30.796 +            return lastReturned;
  30.797 +        }
  30.798 +
  30.799 +        public void remove() {
  30.800 +            if (lastReturned == null)
  30.801 +                throw new IllegalStateException();
  30.802 +            if (modCount != expectedModCount)
  30.803 +                throw new ConcurrentModificationException();
  30.804 +
  30.805 +            WeakHashMap.this.remove(currentKey);
  30.806 +            expectedModCount = modCount;
  30.807 +            lastReturned = null;
  30.808 +            currentKey = null;
  30.809 +        }
  30.810 +
  30.811 +    }
  30.812 +
  30.813 +    private class ValueIterator extends HashIterator<V> {
  30.814 +        public V next() {
  30.815 +            return nextEntry().value;
  30.816 +        }
  30.817 +    }
  30.818 +
  30.819 +    private class KeyIterator extends HashIterator<K> {
  30.820 +        public K next() {
  30.821 +            return nextEntry().getKey();
  30.822 +        }
  30.823 +    }
  30.824 +
  30.825 +    private class EntryIterator extends HashIterator<Map.Entry<K,V>> {
  30.826 +        public Map.Entry<K,V> next() {
  30.827 +            return nextEntry();
  30.828 +        }
  30.829 +    }
  30.830 +
  30.831 +    // Views
  30.832 +
  30.833 +    private transient Set<Map.Entry<K,V>> entrySet = null;
  30.834 +
  30.835 +    /**
  30.836 +     * Returns a {@link Set} view of the keys contained in this map.
  30.837 +     * The set is backed by the map, so changes to the map are
  30.838 +     * reflected in the set, and vice-versa.  If the map is modified
  30.839 +     * while an iteration over the set is in progress (except through
  30.840 +     * the iterator's own <tt>remove</tt> operation), the results of
  30.841 +     * the iteration are undefined.  The set supports element removal,
  30.842 +     * which removes the corresponding mapping from the map, via the
  30.843 +     * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
  30.844 +     * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
  30.845 +     * operations.  It does not support the <tt>add</tt> or <tt>addAll</tt>
  30.846 +     * operations.
  30.847 +     */
  30.848 +    public Set<K> keySet() {
  30.849 +        Set<K> ks = keySet;
  30.850 +        return (ks != null ? ks : (keySet = new KeySet()));
  30.851 +    }
  30.852 +
  30.853 +    private class KeySet extends AbstractSet<K> {
  30.854 +        public Iterator<K> iterator() {
  30.855 +            return new KeyIterator();
  30.856 +        }
  30.857 +
  30.858 +        public int size() {
  30.859 +            return WeakHashMap.this.size();
  30.860 +        }
  30.861 +
  30.862 +        public boolean contains(Object o) {
  30.863 +            return containsKey(o);
  30.864 +        }
  30.865 +
  30.866 +        public boolean remove(Object o) {
  30.867 +            if (containsKey(o)) {
  30.868 +                WeakHashMap.this.remove(o);
  30.869 +                return true;
  30.870 +            }
  30.871 +            else
  30.872 +                return false;
  30.873 +        }
  30.874 +
  30.875 +        public void clear() {
  30.876 +            WeakHashMap.this.clear();
  30.877 +        }
  30.878 +    }
  30.879 +
  30.880 +    /**
  30.881 +     * Returns a {@link Collection} view of the values contained in this map.
  30.882 +     * The collection is backed by the map, so changes to the map are
  30.883 +     * reflected in the collection, and vice-versa.  If the map is
  30.884 +     * modified while an iteration over the collection is in progress
  30.885 +     * (except through the iterator's own <tt>remove</tt> operation),
  30.886 +     * the results of the iteration are undefined.  The collection
  30.887 +     * supports element removal, which removes the corresponding
  30.888 +     * mapping from the map, via the <tt>Iterator.remove</tt>,
  30.889 +     * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
  30.890 +     * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
  30.891 +     * support the <tt>add</tt> or <tt>addAll</tt> operations.
  30.892 +     */
  30.893 +    public Collection<V> values() {
  30.894 +        Collection<V> vs = values;
  30.895 +        return (vs != null) ? vs : (values = new Values());
  30.896 +    }
  30.897 +
  30.898 +    private class Values extends AbstractCollection<V> {
  30.899 +        public Iterator<V> iterator() {
  30.900 +            return new ValueIterator();
  30.901 +        }
  30.902 +
  30.903 +        public int size() {
  30.904 +            return WeakHashMap.this.size();
  30.905 +        }
  30.906 +
  30.907 +        public boolean contains(Object o) {
  30.908 +            return containsValue(o);
  30.909 +        }
  30.910 +
  30.911 +        public void clear() {
  30.912 +            WeakHashMap.this.clear();
  30.913 +        }
  30.914 +    }
  30.915 +
  30.916 +    /**
  30.917 +     * Returns a {@link Set} view of the mappings contained in this map.
  30.918 +     * The set is backed by the map, so changes to the map are
  30.919 +     * reflected in the set, and vice-versa.  If the map is modified
  30.920 +     * while an iteration over the set is in progress (except through
  30.921 +     * the iterator's own <tt>remove</tt> operation, or through the
  30.922 +     * <tt>setValue</tt> operation on a map entry returned by the
  30.923 +     * iterator) the results of the iteration are undefined.  The set
  30.924 +     * supports element removal, which removes the corresponding
  30.925 +     * mapping from the map, via the <tt>Iterator.remove</tt>,
  30.926 +     * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
  30.927 +     * <tt>clear</tt> operations.  It does not support the
  30.928 +     * <tt>add</tt> or <tt>addAll</tt> operations.
  30.929 +     */
  30.930 +    public Set<Map.Entry<K,V>> entrySet() {
  30.931 +        Set<Map.Entry<K,V>> es = entrySet;
  30.932 +        return es != null ? es : (entrySet = new EntrySet());
  30.933 +    }
  30.934 +
  30.935 +    private class EntrySet extends AbstractSet<Map.Entry<K,V>> {
  30.936 +        public Iterator<Map.Entry<K,V>> iterator() {
  30.937 +            return new EntryIterator();
  30.938 +        }
  30.939 +
  30.940 +        public boolean contains(Object o) {
  30.941 +            if (!(o instanceof Map.Entry))
  30.942 +                return false;
  30.943 +            Map.Entry<?,?> e = (Map.Entry<?,?>)o;
  30.944 +            Entry<K,V> candidate = getEntry(e.getKey());
  30.945 +            return candidate != null && candidate.equals(e);
  30.946 +        }
  30.947 +
  30.948 +        public boolean remove(Object o) {
  30.949 +            return removeMapping(o);
  30.950 +        }
  30.951 +
  30.952 +        public int size() {
  30.953 +            return WeakHashMap.this.size();
  30.954 +        }
  30.955 +
  30.956 +        public void clear() {
  30.957 +            WeakHashMap.this.clear();
  30.958 +        }
  30.959 +
  30.960 +        private List<Map.Entry<K,V>> deepCopy() {
  30.961 +            List<Map.Entry<K,V>> list = new ArrayList<>(size());
  30.962 +            for (Map.Entry<K,V> e : this)
  30.963 +                list.add(new AbstractMap.SimpleEntry<>(e));
  30.964 +            return list;
  30.965 +        }
  30.966 +
  30.967 +        public Object[] toArray() {
  30.968 +            return deepCopy().toArray();
  30.969 +        }
  30.970 +
  30.971 +        public <T> T[] toArray(T[] a) {
  30.972 +            return deepCopy().toArray(a);
  30.973 +        }
  30.974 +    }
  30.975 +}
    31.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.2 +++ b/rt/emul/compact/src/main/java/java/util/concurrent/Executor.java	Sat Sep 07 13:55:09 2013 +0200
    31.3 @@ -0,0 +1,141 @@
    31.4 +/*
    31.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    31.6 + *
    31.7 + * This code is free software; you can redistribute it and/or modify it
    31.8 + * under the terms of the GNU General Public License version 2 only, as
    31.9 + * published by the Free Software Foundation.  Oracle designates this
   31.10 + * particular file as subject to the "Classpath" exception as provided
   31.11 + * by Oracle in the LICENSE file that accompanied this code.
   31.12 + *
   31.13 + * This code is distributed in the hope that it will be useful, but WITHOUT
   31.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   31.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   31.16 + * version 2 for more details (a copy is included in the LICENSE file that
   31.17 + * accompanied this code).
   31.18 + *
   31.19 + * You should have received a copy of the GNU General Public License version
   31.20 + * 2 along with this work; if not, write to the Free Software Foundation,
   31.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   31.22 + *
   31.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   31.24 + * or visit www.oracle.com if you need additional information or have any
   31.25 + * questions.
   31.26 + */
   31.27 +
   31.28 +/*
   31.29 + * This file is available under and governed by the GNU General Public
   31.30 + * License version 2 only, as published by the Free Software Foundation.
   31.31 + * However, the following notice accompanied the original version of this
   31.32 + * file:
   31.33 + *
   31.34 + * Written by Doug Lea with assistance from members of JCP JSR-166
   31.35 + * Expert Group and released to the public domain, as explained at
   31.36 + * http://creativecommons.org/publicdomain/zero/1.0/
   31.37 + */
   31.38 +
   31.39 +package java.util.concurrent;
   31.40 +
   31.41 +/**
   31.42 + * An object that executes submitted {@link Runnable} tasks. This
   31.43 + * interface provides a way of decoupling task submission from the
   31.44 + * mechanics of how each task will be run, including details of thread
   31.45 + * use, scheduling, etc.  An <tt>Executor</tt> is normally used
   31.46 + * instead of explicitly creating threads. For example, rather than
   31.47 + * invoking <tt>new Thread(new(RunnableTask())).start()</tt> for each
   31.48 + * of a set of tasks, you might use:
   31.49 + *
   31.50 + * <pre>
   31.51 + * Executor executor = <em>anExecutor</em>;
   31.52 + * executor.execute(new RunnableTask1());
   31.53 + * executor.execute(new RunnableTask2());
   31.54 + * ...
   31.55 + * </pre>
   31.56 + *
   31.57 + * However, the <tt>Executor</tt> interface does not strictly
   31.58 + * require that execution be asynchronous. In the simplest case, an
   31.59 + * executor can run the submitted task immediately in the caller's
   31.60 + * thread:
   31.61 + *
   31.62 + * <pre>
   31.63 + * class DirectExecutor implements Executor {
   31.64 + *     public void execute(Runnable r) {
   31.65 + *         r.run();
   31.66 + *     }
   31.67 + * }</pre>
   31.68 + *
   31.69 + * More typically, tasks are executed in some thread other
   31.70 + * than the caller's thread.  The executor below spawns a new thread
   31.71 + * for each task.
   31.72 + *
   31.73 + * <pre>
   31.74 + * class ThreadPerTaskExecutor implements Executor {
   31.75 + *     public void execute(Runnable r) {
   31.76 + *         new Thread(r).start();
   31.77 + *     }
   31.78 + * }</pre>
   31.79 + *
   31.80 + * Many <tt>Executor</tt> implementations impose some sort of
   31.81 + * limitation on how and when tasks are scheduled.  The executor below
   31.82 + * serializes the submission of tasks to a second executor,
   31.83 + * illustrating a composite executor.
   31.84 + *
   31.85 + *  <pre> {@code
   31.86 + * class SerialExecutor implements Executor {
   31.87 + *   final Queue<Runnable> tasks = new ArrayDeque<Runnable>();
   31.88 + *   final Executor executor;
   31.89 + *   Runnable active;
   31.90 + *
   31.91 + *   SerialExecutor(Executor executor) {
   31.92 + *     this.executor = executor;
   31.93 + *   }
   31.94 + *
   31.95 + *   public synchronized void execute(final Runnable r) {
   31.96 + *     tasks.offer(new Runnable() {
   31.97 + *       public void run() {
   31.98 + *         try {
   31.99 + *           r.run();
  31.100 + *         } finally {
  31.101 + *           scheduleNext();
  31.102 + *         }
  31.103 + *       }
  31.104 + *     });
  31.105 + *     if (active == null) {
  31.106 + *       scheduleNext();
  31.107 + *     }
  31.108 + *   }
  31.109 + *
  31.110 + *   protected synchronized void scheduleNext() {
  31.111 + *     if ((active = tasks.poll()) != null) {
  31.112 + *       executor.execute(active);
  31.113 + *     }
  31.114 + *   }
  31.115 + * }}</pre>
  31.116 + *
  31.117 + * The <tt>Executor</tt> implementations provided in this package
  31.118 + * implement {@link ExecutorService}, which is a more extensive
  31.119 + * interface.  The {@link ThreadPoolExecutor} class provides an
  31.120 + * extensible thread pool implementation. The {@link Executors} class
  31.121 + * provides convenient factory methods for these Executors.
  31.122 + *
  31.123 + * <p>Memory consistency effects: Actions in a thread prior to
  31.124 + * submitting a {@code Runnable} object to an {@code Executor}
  31.125 + * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
  31.126 + * its execution begins, perhaps in another thread.
  31.127 + *
  31.128 + * @since 1.5
  31.129 + * @author Doug Lea
  31.130 + */
  31.131 +public interface Executor {
  31.132 +
  31.133 +    /**
  31.134 +     * Executes the given command at some time in the future.  The command
  31.135 +     * may execute in a new thread, in a pooled thread, or in the calling
  31.136 +     * thread, at the discretion of the <tt>Executor</tt> implementation.
  31.137 +     *
  31.138 +     * @param command the runnable task
  31.139 +     * @throws RejectedExecutionException if this task cannot be
  31.140 +     * accepted for execution.
  31.141 +     * @throws NullPointerException if command is null
  31.142 +     */
  31.143 +    void execute(Runnable command);
  31.144 +}
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/rt/emul/compact/src/main/java/java/util/logging/Level.java	Sat Sep 07 13:55:09 2013 +0200
    32.3 @@ -0,0 +1,378 @@
    32.4 +/*
    32.5 + * Copyright (c) 2000, 2010, 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.util.logging;
   32.30 +import java.util.ResourceBundle;
   32.31 +
   32.32 +/**
   32.33 + * The Level class defines a set of standard logging levels that
   32.34 + * can be used to control logging output.  The logging Level objects
   32.35 + * are ordered and are specified by ordered integers.  Enabling logging
   32.36 + * at a given level also enables logging at all higher levels.
   32.37 + * <p>
   32.38 + * Clients should normally use the predefined Level constants such
   32.39 + * as Level.SEVERE.
   32.40 + * <p>
   32.41 + * The levels in descending order are:
   32.42 + * <ul>
   32.43 + * <li>SEVERE (highest value)
   32.44 + * <li>WARNING
   32.45 + * <li>INFO
   32.46 + * <li>CONFIG
   32.47 + * <li>FINE
   32.48 + * <li>FINER
   32.49 + * <li>FINEST  (lowest value)
   32.50 + * </ul>
   32.51 + * In addition there is a level OFF that can be used to turn
   32.52 + * off logging, and a level ALL that can be used to enable
   32.53 + * logging of all messages.
   32.54 + * <p>
   32.55 + * It is possible for third parties to define additional logging
   32.56 + * levels by subclassing Level.  In such cases subclasses should
   32.57 + * take care to chose unique integer level values and to ensure that
   32.58 + * they maintain the Object uniqueness property across serialization
   32.59 + * by defining a suitable readResolve method.
   32.60 + *
   32.61 + * @since 1.4
   32.62 + */
   32.63 +
   32.64 +public class Level implements java.io.Serializable {
   32.65 +    private static java.util.ArrayList<Level> known = new java.util.ArrayList<>();
   32.66 +    private static String defaultBundle = "sun.util.logging.resources.logging";
   32.67 +
   32.68 +    /**
   32.69 +     * @serial  The non-localized name of the level.
   32.70 +     */
   32.71 +    private final String name;
   32.72 +
   32.73 +    /**
   32.74 +     * @serial  The integer value of the level.
   32.75 +     */
   32.76 +    private final int value;
   32.77 +
   32.78 +    /**
   32.79 +     * @serial The resource bundle name to be used in localizing the level name.
   32.80 +     */
   32.81 +    private final String resourceBundleName;
   32.82 +
   32.83 +    /**
   32.84 +     * OFF is a special level that can be used to turn off logging.
   32.85 +     * This level is initialized to <CODE>Integer.MAX_VALUE</CODE>.
   32.86 +     */
   32.87 +    public static final Level OFF = new Level("OFF",Integer.MAX_VALUE, defaultBundle);
   32.88 +
   32.89 +    /**
   32.90 +     * SEVERE is a message level indicating a serious failure.
   32.91 +     * <p>
   32.92 +     * In general SEVERE messages should describe events that are
   32.93 +     * of considerable importance and which will prevent normal
   32.94 +     * program execution.   They should be reasonably intelligible
   32.95 +     * to end users and to system administrators.
   32.96 +     * This level is initialized to <CODE>1000</CODE>.
   32.97 +     */
   32.98 +    public static final Level SEVERE = new Level("SEVERE",1000, defaultBundle);
   32.99 +
  32.100 +    /**
  32.101 +     * WARNING is a message level indicating a potential problem.
  32.102 +     * <p>
  32.103 +     * In general WARNING messages should describe events that will
  32.104 +     * be of interest to end users or system managers, or which
  32.105 +     * indicate potential problems.
  32.106 +     * This level is initialized to <CODE>900</CODE>.
  32.107 +     */
  32.108 +    public static final Level WARNING = new Level("WARNING", 900, defaultBundle);
  32.109 +
  32.110 +    /**
  32.111 +     * INFO is a message level for informational messages.
  32.112 +     * <p>
  32.113 +     * Typically INFO messages will be written to the console
  32.114 +     * or its equivalent.  So the INFO level should only be
  32.115 +     * used for reasonably significant messages that will
  32.116 +     * make sense to end users and system administrators.
  32.117 +     * This level is initialized to <CODE>800</CODE>.
  32.118 +     */
  32.119 +    public static final Level INFO = new Level("INFO", 800, defaultBundle);
  32.120 +
  32.121 +    /**
  32.122 +     * CONFIG is a message level for static configuration messages.
  32.123 +     * <p>
  32.124 +     * CONFIG messages are intended to provide a variety of static
  32.125 +     * configuration information, to assist in debugging problems
  32.126 +     * that may be associated with particular configurations.
  32.127 +     * For example, CONFIG message might include the CPU type,
  32.128 +     * the graphics depth, the GUI look-and-feel, etc.
  32.129 +     * This level is initialized to <CODE>700</CODE>.
  32.130 +     */
  32.131 +    public static final Level CONFIG = new Level("CONFIG", 700, defaultBundle);
  32.132 +
  32.133 +    /**
  32.134 +     * FINE is a message level providing tracing information.
  32.135 +     * <p>
  32.136 +     * All of FINE, FINER, and FINEST are intended for relatively
  32.137 +     * detailed tracing.  The exact meaning of the three levels will
  32.138 +     * vary between subsystems, but in general, FINEST should be used
  32.139 +     * for the most voluminous detailed output, FINER for somewhat
  32.140 +     * less detailed output, and FINE for the  lowest volume (and
  32.141 +     * most important) messages.
  32.142 +     * <p>
  32.143 +     * In general the FINE level should be used for information
  32.144 +     * that will be broadly interesting to developers who do not have
  32.145 +     * a specialized interest in the specific subsystem.
  32.146 +     * <p>
  32.147 +     * FINE messages might include things like minor (recoverable)
  32.148 +     * failures.  Issues indicating potential performance problems
  32.149 +     * are also worth logging as FINE.
  32.150 +     * This level is initialized to <CODE>500</CODE>.
  32.151 +     */
  32.152 +    public static final Level FINE = new Level("FINE", 500, defaultBundle);
  32.153 +
  32.154 +    /**
  32.155 +     * FINER indicates a fairly detailed tracing message.
  32.156 +     * By default logging calls for entering, returning, or throwing
  32.157 +     * an exception are traced at this level.
  32.158 +     * This level is initialized to <CODE>400</CODE>.
  32.159 +     */
  32.160 +    public static final Level FINER = new Level("FINER", 400, defaultBundle);
  32.161 +
  32.162 +    /**
  32.163 +     * FINEST indicates a highly detailed tracing message.
  32.164 +     * This level is initialized to <CODE>300</CODE>.
  32.165 +     */
  32.166 +    public static final Level FINEST = new Level("FINEST", 300, defaultBundle);
  32.167 +
  32.168 +    /**
  32.169 +     * ALL indicates that all messages should be logged.
  32.170 +     * This level is initialized to <CODE>Integer.MIN_VALUE</CODE>.
  32.171 +     */
  32.172 +    public static final Level ALL = new Level("ALL", Integer.MIN_VALUE, defaultBundle);
  32.173 +
  32.174 +    /**
  32.175 +     * Create a named Level with a given integer value.
  32.176 +     * <p>
  32.177 +     * Note that this constructor is "protected" to allow subclassing.
  32.178 +     * In general clients of logging should use one of the constant Level
  32.179 +     * objects such as SEVERE or FINEST.  However, if clients need to
  32.180 +     * add new logging levels, they may subclass Level and define new
  32.181 +     * constants.
  32.182 +     * @param name  the name of the Level, for example "SEVERE".
  32.183 +     * @param value an integer value for the level.
  32.184 +     * @throws NullPointerException if the name is null
  32.185 +     */
  32.186 +    protected Level(String name, int value) {
  32.187 +        this(name, value, null);
  32.188 +    }
  32.189 +
  32.190 +    /**
  32.191 +     * Create a named Level with a given integer value and a
  32.192 +     * given localization resource name.
  32.193 +     * <p>
  32.194 +     * @param name  the name of the Level, for example "SEVERE".
  32.195 +     * @param value an integer value for the level.
  32.196 +     * @param resourceBundleName name of a resource bundle to use in
  32.197 +     *    localizing the given name. If the resourceBundleName is null
  32.198 +     *    or an empty string, it is ignored.
  32.199 +     * @throws NullPointerException if the name is null
  32.200 +     */
  32.201 +    protected Level(String name, int value, String resourceBundleName) {
  32.202 +        if (name == null) {
  32.203 +            throw new NullPointerException();
  32.204 +        }
  32.205 +        this.name = name;
  32.206 +        this.value = value;
  32.207 +        this.resourceBundleName = resourceBundleName;
  32.208 +        synchronized (Level.class) {
  32.209 +            known.add(this);
  32.210 +        }
  32.211 +    }
  32.212 +
  32.213 +    /**
  32.214 +     * Return the level's localization resource bundle name, or
  32.215 +     * null if no localization bundle is defined.
  32.216 +     *
  32.217 +     * @return localization resource bundle name
  32.218 +     */
  32.219 +    public String getResourceBundleName() {
  32.220 +        return resourceBundleName;
  32.221 +    }
  32.222 +
  32.223 +    /**
  32.224 +     * Return the non-localized string name of the Level.
  32.225 +     *
  32.226 +     * @return non-localized name
  32.227 +     */
  32.228 +    public String getName() {
  32.229 +        return name;
  32.230 +    }
  32.231 +
  32.232 +    /**
  32.233 +     * Return the localized string name of the Level, for
  32.234 +     * the current default locale.
  32.235 +     * <p>
  32.236 +     * If no localization information is available, the
  32.237 +     * non-localized name is returned.
  32.238 +     *
  32.239 +     * @return localized name
  32.240 +     */
  32.241 +    public String getLocalizedName() {
  32.242 +        try {
  32.243 +            ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName);
  32.244 +            return rb.getString(name);
  32.245 +        } catch (Exception ex) {
  32.246 +            return name;
  32.247 +        }
  32.248 +    }
  32.249 +
  32.250 +    /**
  32.251 +     * Returns a string representation of this Level.
  32.252 +     *
  32.253 +     * @return the non-localized name of the Level, for example "INFO".
  32.254 +     */
  32.255 +    public final String toString() {
  32.256 +        return name;
  32.257 +    }
  32.258 +
  32.259 +    /**
  32.260 +     * Get the integer value for this level.  This integer value
  32.261 +     * can be used for efficient ordering comparisons between
  32.262 +     * Level objects.
  32.263 +     * @return the integer value for this level.
  32.264 +     */
  32.265 +    public final int intValue() {
  32.266 +        return value;
  32.267 +    }
  32.268 +
  32.269 +    private static final long serialVersionUID = -8176160795706313070L;
  32.270 +
  32.271 +    // Serialization magic to prevent "doppelgangers".
  32.272 +    // This is a performance optimization.
  32.273 +    private Object readResolve() {
  32.274 +        synchronized (Level.class) {
  32.275 +            for (int i = 0; i < known.size(); i++) {
  32.276 +                Level other = known.get(i);
  32.277 +                if (this.name.equals(other.name) && this.value == other.value
  32.278 +                        && (this.resourceBundleName == other.resourceBundleName ||
  32.279 +                            (this.resourceBundleName != null &&
  32.280 +                            this.resourceBundleName.equals(other.resourceBundleName)))) {
  32.281 +                    return other;
  32.282 +                }
  32.283 +            }
  32.284 +            // Woops.  Whoever sent us this object knows
  32.285 +            // about a new log level.  Add it to our list.
  32.286 +            known.add(this);
  32.287 +            return this;
  32.288 +        }
  32.289 +    }
  32.290 +
  32.291 +    /**
  32.292 +     * Parse a level name string into a Level.
  32.293 +     * <p>
  32.294 +     * The argument string may consist of either a level name
  32.295 +     * or an integer value.
  32.296 +     * <p>
  32.297 +     * For example:
  32.298 +     * <ul>
  32.299 +     * <li>     "SEVERE"
  32.300 +     * <li>     "1000"
  32.301 +     * </ul>
  32.302 +     * @param  name   string to be parsed
  32.303 +     * @throws NullPointerException if the name is null
  32.304 +     * @throws IllegalArgumentException if the value is not valid.
  32.305 +     * Valid values are integers between <CODE>Integer.MIN_VALUE</CODE>
  32.306 +     * and <CODE>Integer.MAX_VALUE</CODE>, and all known level names.
  32.307 +     * Known names are the levels defined by this class (e.g., <CODE>FINE</CODE>,
  32.308 +     * <CODE>FINER</CODE>, <CODE>FINEST</CODE>), or created by this class with
  32.309 +     * appropriate package access, or new levels defined or created
  32.310 +     * by subclasses.
  32.311 +     *
  32.312 +     * @return The parsed value. Passing an integer that corresponds to a known name
  32.313 +     * (e.g., 700) will return the associated name (e.g., <CODE>CONFIG</CODE>).
  32.314 +     * Passing an integer that does not (e.g., 1) will return a new level name
  32.315 +     * initialized to that value.
  32.316 +     */
  32.317 +    public static synchronized Level parse(String name) throws IllegalArgumentException {
  32.318 +        // Check that name is not null.
  32.319 +        name.length();
  32.320 +
  32.321 +        // Look for a known Level with the given non-localized name.
  32.322 +        for (int i = 0; i < known.size(); i++) {
  32.323 +            Level l = known.get(i);
  32.324 +            if (name.equals(l.name)) {
  32.325 +                return l;
  32.326 +            }
  32.327 +        }
  32.328 +
  32.329 +        // Now, check if the given name is an integer.  If so,
  32.330 +        // first look for a Level with the given value and then
  32.331 +        // if necessary create one.
  32.332 +        try {
  32.333 +            int x = Integer.parseInt(name);
  32.334 +            for (int i = 0; i < known.size(); i++) {
  32.335 +                Level l = known.get(i);
  32.336 +                if (l.value == x) {
  32.337 +                    return l;
  32.338 +                }
  32.339 +            }
  32.340 +            // Create a new Level.
  32.341 +            return new Level(name, x);
  32.342 +        } catch (NumberFormatException ex) {
  32.343 +            // Not an integer.
  32.344 +            // Drop through.
  32.345 +        }
  32.346 +
  32.347 +        // Finally, look for a known level with the given localized name,
  32.348 +        // in the current default locale.
  32.349 +        // This is relatively expensive, but not excessively so.
  32.350 +        for (int i = 0; i < known.size(); i++) {
  32.351 +            Level l =  known.get(i);
  32.352 +            if (name.equals(l.getLocalizedName())) {
  32.353 +                return l;
  32.354 +            }
  32.355 +        }
  32.356 +
  32.357 +        // OK, we've tried everything and failed
  32.358 +        throw new IllegalArgumentException("Bad level \"" + name + "\"");
  32.359 +    }
  32.360 +
  32.361 +    /**
  32.362 +     * Compare two objects for value equality.
  32.363 +     * @return true if and only if the two objects have the same level value.
  32.364 +     */
  32.365 +    public boolean equals(Object ox) {
  32.366 +        try {
  32.367 +            Level lx = (Level)ox;
  32.368 +            return (lx.value == this.value);
  32.369 +        } catch (Exception ex) {
  32.370 +            return false;
  32.371 +        }
  32.372 +    }
  32.373 +
  32.374 +    /**
  32.375 +     * Generate a hashcode.
  32.376 +     * @return a hashcode based on the level value
  32.377 +     */
  32.378 +    public int hashCode() {
  32.379 +        return this.value;
  32.380 +    }
  32.381 +}
    33.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.2 +++ b/rt/emul/compact/src/main/java/java/util/logging/LogRecord.java	Sat Sep 07 13:55:09 2013 +0200
    33.3 @@ -0,0 +1,566 @@
    33.4 +/*
    33.5 + * Copyright (c) 2000, 2010, 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.util.logging;
   33.30 +import java.util.*;
   33.31 +import java.util.concurrent.atomic.AtomicInteger;
   33.32 +import java.util.concurrent.atomic.AtomicLong;
   33.33 +import java.io.*;
   33.34 +
   33.35 +import sun.misc.JavaLangAccess;
   33.36 +import sun.misc.SharedSecrets;
   33.37 +
   33.38 +/**
   33.39 + * LogRecord objects are used to pass logging requests between
   33.40 + * the logging framework and individual log Handlers.
   33.41 + * <p>
   33.42 + * When a LogRecord is passed into the logging framework it
   33.43 + * logically belongs to the framework and should no longer be
   33.44 + * used or updated by the client application.
   33.45 + * <p>
   33.46 + * Note that if the client application has not specified an
   33.47 + * explicit source method name and source class name, then the
   33.48 + * LogRecord class will infer them automatically when they are
   33.49 + * first accessed (due to a call on getSourceMethodName or
   33.50 + * getSourceClassName) by analyzing the call stack.  Therefore,
   33.51 + * if a logging Handler wants to pass off a LogRecord to another
   33.52 + * thread, or to transmit it over RMI, and if it wishes to subsequently
   33.53 + * obtain method name or class name information it should call
   33.54 + * one of getSourceClassName or getSourceMethodName to force
   33.55 + * the values to be filled in.
   33.56 + * <p>
   33.57 + * <b> Serialization notes:</b>
   33.58 + * <ul>
   33.59 + * <li>The LogRecord class is serializable.
   33.60 + *
   33.61 + * <li> Because objects in the parameters array may not be serializable,
   33.62 + * during serialization all objects in the parameters array are
   33.63 + * written as the corresponding Strings (using Object.toString).
   33.64 + *
   33.65 + * <li> The ResourceBundle is not transmitted as part of the serialized
   33.66 + * form, but the resource bundle name is, and the recipient object's
   33.67 + * readObject method will attempt to locate a suitable resource bundle.
   33.68 + *
   33.69 + * </ul>
   33.70 + *
   33.71 + * @since 1.4
   33.72 + */
   33.73 +
   33.74 +public class LogRecord implements java.io.Serializable {
   33.75 +    private static final AtomicLong globalSequenceNumber
   33.76 +        = new AtomicLong(0);
   33.77 +
   33.78 +    /**
   33.79 +     * The default value of threadID will be the current thread's
   33.80 +     * thread id, for ease of correlation, unless it is greater than
   33.81 +     * MIN_SEQUENTIAL_THREAD_ID, in which case we try harder to keep
   33.82 +     * our promise to keep threadIDs unique by avoiding collisions due
   33.83 +     * to 32-bit wraparound.  Unfortunately, LogRecord.getThreadID()
   33.84 +     * returns int, while Thread.getId() returns long.
   33.85 +     */
   33.86 +    private static final int MIN_SEQUENTIAL_THREAD_ID = Integer.MAX_VALUE / 2;
   33.87 +
   33.88 +    private static final AtomicInteger nextThreadId
   33.89 +        = new AtomicInteger(MIN_SEQUENTIAL_THREAD_ID);
   33.90 +
   33.91 +    private static final ThreadLocal<Integer> threadIds = new ThreadLocal<>();
   33.92 +
   33.93 +    /**
   33.94 +     * @serial Logging message level
   33.95 +     */
   33.96 +    private Level level;
   33.97 +
   33.98 +    /**
   33.99 +     * @serial Sequence number
  33.100 +     */
  33.101 +    private long sequenceNumber;
  33.102 +
  33.103 +    /**
  33.104 +     * @serial Class that issued logging call
  33.105 +     */
  33.106 +    private String sourceClassName;
  33.107 +
  33.108 +    /**
  33.109 +     * @serial Method that issued logging call
  33.110 +     */
  33.111 +    private String sourceMethodName;
  33.112 +
  33.113 +    /**
  33.114 +     * @serial Non-localized raw message text
  33.115 +     */
  33.116 +    private String message;
  33.117 +
  33.118 +    /**
  33.119 +     * @serial Thread ID for thread that issued logging call.
  33.120 +     */
  33.121 +    private int threadID;
  33.122 +
  33.123 +    /**
  33.124 +     * @serial Event time in milliseconds since 1970
  33.125 +     */
  33.126 +    private long millis;
  33.127 +
  33.128 +    /**
  33.129 +     * @serial The Throwable (if any) associated with log message
  33.130 +     */
  33.131 +    private Throwable thrown;
  33.132 +
  33.133 +    /**
  33.134 +     * @serial Name of the source Logger.
  33.135 +     */
  33.136 +    private String loggerName;
  33.137 +
  33.138 +    /**
  33.139 +     * @serial Resource bundle name to localized log message.
  33.140 +     */
  33.141 +    private String resourceBundleName;
  33.142 +
  33.143 +    private transient boolean needToInferCaller;
  33.144 +    private transient Object parameters[];
  33.145 +    private transient ResourceBundle resourceBundle;
  33.146 +
  33.147 +    /**
  33.148 +     * Returns the default value for a new LogRecord's threadID.
  33.149 +     */
  33.150 +    private int defaultThreadID() {
  33.151 +        long tid = Thread.currentThread().getId();
  33.152 +        if (tid < MIN_SEQUENTIAL_THREAD_ID) {
  33.153 +            return (int) tid;
  33.154 +        } else {
  33.155 +            Integer id = threadIds.get();
  33.156 +            if (id == null) {
  33.157 +                id = nextThreadId.getAndIncrement();
  33.158 +                threadIds.set(id);
  33.159 +            }
  33.160 +            return id;
  33.161 +        }
  33.162 +    }
  33.163 +
  33.164 +    /**
  33.165 +     * Construct a LogRecord with the given level and message values.
  33.166 +     * <p>
  33.167 +     * The sequence property will be initialized with a new unique value.
  33.168 +     * These sequence values are allocated in increasing order within a VM.
  33.169 +     * <p>
  33.170 +     * The millis property will be initialized to the current time.
  33.171 +     * <p>
  33.172 +     * The thread ID property will be initialized with a unique ID for
  33.173 +     * the current thread.
  33.174 +     * <p>
  33.175 +     * All other properties will be initialized to "null".
  33.176 +     *
  33.177 +     * @param level  a logging level value
  33.178 +     * @param msg  the raw non-localized logging message (may be null)
  33.179 +     */
  33.180 +    public LogRecord(Level level, String msg) {
  33.181 +        // Make sure level isn't null, by calling random method.
  33.182 +        level.getClass();
  33.183 +        this.level = level;
  33.184 +        message = msg;
  33.185 +        // Assign a thread ID and a unique sequence number.
  33.186 +        sequenceNumber = globalSequenceNumber.getAndIncrement();
  33.187 +        threadID = defaultThreadID();
  33.188 +        millis = System.currentTimeMillis();
  33.189 +        needToInferCaller = true;
  33.190 +   }
  33.191 +
  33.192 +    /**
  33.193 +     * Get the source Logger's name.
  33.194 +     *
  33.195 +     * @return source logger name (may be null)
  33.196 +     */
  33.197 +    public String getLoggerName() {
  33.198 +        return loggerName;
  33.199 +    }
  33.200 +
  33.201 +    /**
  33.202 +     * Set the source Logger's name.
  33.203 +     *
  33.204 +     * @param name   the source logger name (may be null)
  33.205 +     */
  33.206 +    public void setLoggerName(String name) {
  33.207 +        loggerName = name;
  33.208 +    }
  33.209 +
  33.210 +    /**
  33.211 +     * Get the localization resource bundle
  33.212 +     * <p>
  33.213 +     * This is the ResourceBundle that should be used to localize
  33.214 +     * the message string before formatting it.  The result may
  33.215 +     * be null if the message is not localizable, or if no suitable
  33.216 +     * ResourceBundle is available.
  33.217 +     */
  33.218 +    public ResourceBundle getResourceBundle() {
  33.219 +        return resourceBundle;
  33.220 +    }
  33.221 +
  33.222 +    /**
  33.223 +     * Set the localization resource bundle.
  33.224 +     *
  33.225 +     * @param bundle  localization bundle (may be null)
  33.226 +     */
  33.227 +    public void setResourceBundle(ResourceBundle bundle) {
  33.228 +        resourceBundle = bundle;
  33.229 +    }
  33.230 +
  33.231 +    /**
  33.232 +     * Get the localization resource bundle name
  33.233 +     * <p>
  33.234 +     * This is the name for the ResourceBundle that should be
  33.235 +     * used to localize the message string before formatting it.
  33.236 +     * The result may be null if the message is not localizable.
  33.237 +     */
  33.238 +    public String getResourceBundleName() {
  33.239 +        return resourceBundleName;
  33.240 +    }
  33.241 +
  33.242 +    /**
  33.243 +     * Set the localization resource bundle name.
  33.244 +     *
  33.245 +     * @param name  localization bundle name (may be null)
  33.246 +     */
  33.247 +    public void setResourceBundleName(String name) {
  33.248 +        resourceBundleName = name;
  33.249 +    }
  33.250 +
  33.251 +    /**
  33.252 +     * Get the logging message level, for example Level.SEVERE.
  33.253 +     * @return the logging message level
  33.254 +     */
  33.255 +    public Level getLevel() {
  33.256 +        return level;
  33.257 +    }
  33.258 +
  33.259 +    /**
  33.260 +     * Set the logging message level, for example Level.SEVERE.
  33.261 +     * @param level the logging message level
  33.262 +     */
  33.263 +    public void setLevel(Level level) {
  33.264 +        if (level == null) {
  33.265 +            throw new NullPointerException();
  33.266 +        }
  33.267 +        this.level = level;
  33.268 +    }
  33.269 +
  33.270 +    /**
  33.271 +     * Get the sequence number.
  33.272 +     * <p>
  33.273 +     * Sequence numbers are normally assigned in the LogRecord
  33.274 +     * constructor, which assigns unique sequence numbers to
  33.275 +     * each new LogRecord in increasing order.
  33.276 +     * @return the sequence number
  33.277 +     */
  33.278 +    public long getSequenceNumber() {
  33.279 +        return sequenceNumber;
  33.280 +    }
  33.281 +
  33.282 +    /**
  33.283 +     * Set the sequence number.
  33.284 +     * <p>
  33.285 +     * Sequence numbers are normally assigned in the LogRecord constructor,
  33.286 +     * so it should not normally be necessary to use this method.
  33.287 +     */
  33.288 +    public void setSequenceNumber(long seq) {
  33.289 +        sequenceNumber = seq;
  33.290 +    }
  33.291 +
  33.292 +    /**
  33.293 +     * Get the  name of the class that (allegedly) issued the logging request.
  33.294 +     * <p>
  33.295 +     * Note that this sourceClassName is not verified and may be spoofed.
  33.296 +     * This information may either have been provided as part of the
  33.297 +     * logging call, or it may have been inferred automatically by the
  33.298 +     * logging framework.  In the latter case, the information may only
  33.299 +     * be approximate and may in fact describe an earlier call on the
  33.300 +     * stack frame.
  33.301 +     * <p>
  33.302 +     * May be null if no information could be obtained.
  33.303 +     *
  33.304 +     * @return the source class name
  33.305 +     */
  33.306 +    public String getSourceClassName() {
  33.307 +        if (needToInferCaller) {
  33.308 +            inferCaller();
  33.309 +        }
  33.310 +        return sourceClassName;
  33.311 +    }
  33.312 +
  33.313 +    /**
  33.314 +     * Set the name of the class that (allegedly) issued the logging request.
  33.315 +     *
  33.316 +     * @param sourceClassName the source class name (may be null)
  33.317 +     */
  33.318 +    public void setSourceClassName(String sourceClassName) {
  33.319 +        this.sourceClassName = sourceClassName;
  33.320 +        needToInferCaller = false;
  33.321 +    }
  33.322 +
  33.323 +    /**
  33.324 +     * Get the  name of the method that (allegedly) issued the logging request.
  33.325 +     * <p>
  33.326 +     * Note that this sourceMethodName is not verified and may be spoofed.
  33.327 +     * This information may either have been provided as part of the
  33.328 +     * logging call, or it may have been inferred automatically by the
  33.329 +     * logging framework.  In the latter case, the information may only
  33.330 +     * be approximate and may in fact describe an earlier call on the
  33.331 +     * stack frame.
  33.332 +     * <p>
  33.333 +     * May be null if no information could be obtained.
  33.334 +     *
  33.335 +     * @return the source method name
  33.336 +     */
  33.337 +    public String getSourceMethodName() {
  33.338 +        if (needToInferCaller) {
  33.339 +            inferCaller();
  33.340 +        }
  33.341 +        return sourceMethodName;
  33.342 +    }
  33.343 +
  33.344 +    /**
  33.345 +     * Set the name of the method that (allegedly) issued the logging request.
  33.346 +     *
  33.347 +     * @param sourceMethodName the source method name (may be null)
  33.348 +     */
  33.349 +    public void setSourceMethodName(String sourceMethodName) {
  33.350 +        this.sourceMethodName = sourceMethodName;
  33.351 +        needToInferCaller = false;
  33.352 +    }
  33.353 +
  33.354 +    /**
  33.355 +     * Get the "raw" log message, before localization or formatting.
  33.356 +     * <p>
  33.357 +     * May be null, which is equivalent to the empty string "".
  33.358 +     * <p>
  33.359 +     * This message may be either the final text or a localization key.
  33.360 +     * <p>
  33.361 +     * During formatting, if the source logger has a localization
  33.362 +     * ResourceBundle and if that ResourceBundle has an entry for
  33.363 +     * this message string, then the message string is replaced
  33.364 +     * with the localized value.
  33.365 +     *
  33.366 +     * @return the raw message string
  33.367 +     */
  33.368 +    public String getMessage() {
  33.369 +        return message;
  33.370 +    }
  33.371 +
  33.372 +    /**
  33.373 +     * Set the "raw" log message, before localization or formatting.
  33.374 +     *
  33.375 +     * @param message the raw message string (may be null)
  33.376 +     */
  33.377 +    public void setMessage(String message) {
  33.378 +        this.message = message;
  33.379 +    }
  33.380 +
  33.381 +    /**
  33.382 +     * Get the parameters to the log message.
  33.383 +     *
  33.384 +     * @return the log message parameters.  May be null if
  33.385 +     *                  there are no parameters.
  33.386 +     */
  33.387 +    public Object[] getParameters() {
  33.388 +        return parameters;
  33.389 +    }
  33.390 +
  33.391 +    /**
  33.392 +     * Set the parameters to the log message.
  33.393 +     *
  33.394 +     * @param parameters the log message parameters. (may be null)
  33.395 +     */
  33.396 +    public void setParameters(Object parameters[]) {
  33.397 +        this.parameters = parameters;
  33.398 +    }
  33.399 +
  33.400 +    /**
  33.401 +     * Get an identifier for the thread where the message originated.
  33.402 +     * <p>
  33.403 +     * This is a thread identifier within the Java VM and may or
  33.404 +     * may not map to any operating system ID.
  33.405 +     *
  33.406 +     * @return thread ID
  33.407 +     */
  33.408 +    public int getThreadID() {
  33.409 +        return threadID;
  33.410 +    }
  33.411 +
  33.412 +    /**
  33.413 +     * Set an identifier for the thread where the message originated.
  33.414 +     * @param threadID  the thread ID
  33.415 +     */
  33.416 +    public void setThreadID(int threadID) {
  33.417 +        this.threadID = threadID;
  33.418 +    }
  33.419 +
  33.420 +    /**
  33.421 +     * Get event time in milliseconds since 1970.
  33.422 +     *
  33.423 +     * @return event time in millis since 1970
  33.424 +     */
  33.425 +    public long getMillis() {
  33.426 +        return millis;
  33.427 +    }
  33.428 +
  33.429 +    /**
  33.430 +     * Set event time.
  33.431 +     *
  33.432 +     * @param millis event time in millis since 1970
  33.433 +     */
  33.434 +    public void setMillis(long millis) {
  33.435 +        this.millis = millis;
  33.436 +    }
  33.437 +
  33.438 +    /**
  33.439 +     * Get any throwable associated with the log record.
  33.440 +     * <p>
  33.441 +     * If the event involved an exception, this will be the
  33.442 +     * exception object. Otherwise null.
  33.443 +     *
  33.444 +     * @return a throwable
  33.445 +     */
  33.446 +    public Throwable getThrown() {
  33.447 +        return thrown;
  33.448 +    }
  33.449 +
  33.450 +    /**
  33.451 +     * Set a throwable associated with the log event.
  33.452 +     *
  33.453 +     * @param thrown  a throwable (may be null)
  33.454 +     */
  33.455 +    public void setThrown(Throwable thrown) {
  33.456 +        this.thrown = thrown;
  33.457 +    }
  33.458 +
  33.459 +    private static final long serialVersionUID = 5372048053134512534L;
  33.460 +
  33.461 +    /**
  33.462 +     * @serialData Default fields, followed by a two byte version number
  33.463 +     * (major byte, followed by minor byte), followed by information on
  33.464 +     * the log record parameter array.  If there is no parameter array,
  33.465 +     * then -1 is written.  If there is a parameter array (possible of zero
  33.466 +     * length) then the array length is written as an integer, followed
  33.467 +     * by String values for each parameter.  If a parameter is null, then
  33.468 +     * a null String is written.  Otherwise the output of Object.toString()
  33.469 +     * is written.
  33.470 +     */
  33.471 +    private void writeObject(ObjectOutputStream out) throws IOException {
  33.472 +        // We have to call defaultWriteObject first.
  33.473 +        out.defaultWriteObject();
  33.474 +
  33.475 +        // Write our version number.
  33.476 +        out.writeByte(1);
  33.477 +        out.writeByte(0);
  33.478 +        if (parameters == null) {
  33.479 +            out.writeInt(-1);
  33.480 +            return;
  33.481 +        }
  33.482 +        out.writeInt(parameters.length);
  33.483 +        // Write string values for the parameters.
  33.484 +        for (int i = 0; i < parameters.length; i++) {
  33.485 +            if (parameters[i] == null) {
  33.486 +                out.writeObject(null);
  33.487 +            } else {
  33.488 +                out.writeObject(parameters[i].toString());
  33.489 +            }
  33.490 +        }
  33.491 +    }
  33.492 +
  33.493 +    private void readObject(ObjectInputStream in)
  33.494 +                        throws IOException, ClassNotFoundException {
  33.495 +        // We have to call defaultReadObject first.
  33.496 +        in.defaultReadObject();
  33.497 +
  33.498 +        // Read version number.
  33.499 +        byte major = in.readByte();
  33.500 +        byte minor = in.readByte();
  33.501 +        if (major != 1) {
  33.502 +            throw new IOException("LogRecord: bad version: " + major + "." + minor);
  33.503 +        }
  33.504 +        int len = in.readInt();
  33.505 +        if (len == -1) {
  33.506 +            parameters = null;
  33.507 +        } else {
  33.508 +            parameters = new Object[len];
  33.509 +            for (int i = 0; i < parameters.length; i++) {
  33.510 +                parameters[i] = in.readObject();
  33.511 +            }
  33.512 +        }
  33.513 +        // If necessary, try to regenerate the resource bundle.
  33.514 +        if (resourceBundleName != null) {
  33.515 +            try {
  33.516 +                resourceBundle = ResourceBundle.getBundle(resourceBundleName);
  33.517 +            } catch (MissingResourceException ex) {
  33.518 +                // This is not a good place to throw an exception,
  33.519 +                // so we simply leave the resourceBundle null.
  33.520 +                resourceBundle = null;
  33.521 +            }
  33.522 +        }
  33.523 +
  33.524 +        needToInferCaller = false;
  33.525 +    }
  33.526 +
  33.527 +    // Private method to infer the caller's class and method names
  33.528 +    private void inferCaller() {
  33.529 +        needToInferCaller = false;
  33.530 +        JavaLangAccess access = SharedSecrets.getJavaLangAccess();
  33.531 +        Throwable throwable = new Throwable();
  33.532 +        int depth = access.getStackTraceDepth(throwable);
  33.533 +
  33.534 +        boolean lookingForLogger = true;
  33.535 +        for (int ix = 0; ix < depth; ix++) {
  33.536 +            // Calling getStackTraceElement directly prevents the VM
  33.537 +            // from paying the cost of building the entire stack frame.
  33.538 +            StackTraceElement frame =
  33.539 +                access.getStackTraceElement(throwable, ix);
  33.540 +            String cname = frame.getClassName();
  33.541 +            boolean isLoggerImpl = isLoggerImplFrame(cname);
  33.542 +            if (lookingForLogger) {
  33.543 +                // Skip all frames until we have found the first logger frame.
  33.544 +                if (isLoggerImpl) {
  33.545 +                    lookingForLogger = false;
  33.546 +                }
  33.547 +            } else {
  33.548 +                if (!isLoggerImpl) {
  33.549 +                    // skip reflection call
  33.550 +                    if (!cname.startsWith("java.lang.reflect.") && !cname.startsWith("sun.reflect.")) {
  33.551 +                       // We've found the relevant frame.
  33.552 +                       setSourceClassName(cname);
  33.553 +                       setSourceMethodName(frame.getMethodName());
  33.554 +                       return;
  33.555 +                    }
  33.556 +                }
  33.557 +            }
  33.558 +        }
  33.559 +        // We haven't found a suitable frame, so just punt.  This is
  33.560 +        // OK as we are only committed to making a "best effort" here.
  33.561 +    }
  33.562 +
  33.563 +    private boolean isLoggerImplFrame(String cname) {
  33.564 +        // the log record could be created for a platform logger
  33.565 +        return (cname.equals("java.util.logging.Logger") ||
  33.566 +                cname.startsWith("java.util.logging.LoggingProxyImpl") ||
  33.567 +                cname.startsWith("sun.util.logging."));
  33.568 +    }
  33.569 +}
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/rt/emul/compact/src/main/java/java/util/logging/Logger.java	Sat Sep 07 13:55:09 2013 +0200
    34.3 @@ -0,0 +1,1530 @@
    34.4 +/*
    34.5 + * Copyright (c) 2000, 2011, 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 +
   34.29 +
   34.30 +package java.util.logging;
   34.31 +
   34.32 +import java.util.*;
   34.33 +import java.util.concurrent.CopyOnWriteArrayList;
   34.34 +import java.security.*;
   34.35 +import java.lang.ref.WeakReference;
   34.36 +
   34.37 +/**
   34.38 + * A Logger object is used to log messages for a specific
   34.39 + * system or application component.  Loggers are normally named,
   34.40 + * using a hierarchical dot-separated namespace.  Logger names
   34.41 + * can be arbitrary strings, but they should normally be based on
   34.42 + * the package name or class name of the logged component, such
   34.43 + * as java.net or javax.swing.  In addition it is possible to create
   34.44 + * "anonymous" Loggers that are not stored in the Logger namespace.
   34.45 + * <p>
   34.46 + * Logger objects may be obtained by calls on one of the getLogger
   34.47 + * factory methods.  These will either create a new Logger or
   34.48 + * return a suitable existing Logger. It is important to note that
   34.49 + * the Logger returned by one of the {@code getLogger} factory methods
   34.50 + * may be garbage collected at any time if a strong reference to the
   34.51 + * Logger is not kept.
   34.52 + * <p>
   34.53 + * Logging messages will be forwarded to registered Handler
   34.54 + * objects, which can forward the messages to a variety of
   34.55 + * destinations, including consoles, files, OS logs, etc.
   34.56 + * <p>
   34.57 + * Each Logger keeps track of a "parent" Logger, which is its
   34.58 + * nearest existing ancestor in the Logger namespace.
   34.59 + * <p>
   34.60 + * Each Logger has a "Level" associated with it.  This reflects
   34.61 + * a minimum Level that this logger cares about.  If a Logger's
   34.62 + * level is set to <tt>null</tt>, then its effective level is inherited
   34.63 + * from its parent, which may in turn obtain it recursively from its
   34.64 + * parent, and so on up the tree.
   34.65 + * <p>
   34.66 + * The log level can be configured based on the properties from the
   34.67 + * logging configuration file, as described in the description
   34.68 + * of the LogManager class.  However it may also be dynamically changed
   34.69 + * by calls on the Logger.setLevel method.  If a logger's level is
   34.70 + * changed the change may also affect child loggers, since any child
   34.71 + * logger that has <tt>null</tt> as its level will inherit its
   34.72 + * effective level from its parent.
   34.73 + * <p>
   34.74 + * On each logging call the Logger initially performs a cheap
   34.75 + * check of the request level (e.g., SEVERE or FINE) against the
   34.76 + * effective log level of the logger.  If the request level is
   34.77 + * lower than the log level, the logging call returns immediately.
   34.78 + * <p>
   34.79 + * After passing this initial (cheap) test, the Logger will allocate
   34.80 + * a LogRecord to describe the logging message.  It will then call a
   34.81 + * Filter (if present) to do a more detailed check on whether the
   34.82 + * record should be published.  If that passes it will then publish
   34.83 + * the LogRecord to its output Handlers.  By default, loggers also
   34.84 + * publish to their parent's Handlers, recursively up the tree.
   34.85 + * <p>
   34.86 + * Each Logger may have a ResourceBundle name associated with it.
   34.87 + * The named bundle will be used for localizing logging messages.
   34.88 + * If a Logger does not have its own ResourceBundle name, then
   34.89 + * it will inherit the ResourceBundle name from its parent,
   34.90 + * recursively up the tree.
   34.91 + * <p>
   34.92 + * Most of the logger output methods take a "msg" argument.  This
   34.93 + * msg argument may be either a raw value or a localization key.
   34.94 + * During formatting, if the logger has (or inherits) a localization
   34.95 + * ResourceBundle and if the ResourceBundle has a mapping for the msg
   34.96 + * string, then the msg string is replaced by the localized value.
   34.97 + * Otherwise the original msg string is used.  Typically, formatters use
   34.98 + * java.text.MessageFormat style formatting to format parameters, so
   34.99 + * for example a format string "{0} {1}" would format two parameters
  34.100 + * as strings.
  34.101 + * <p>
  34.102 + * When mapping ResourceBundle names to ResourceBundles, the Logger
  34.103 + * will first try to use the Thread's ContextClassLoader.  If that
  34.104 + * is null it will try the SystemClassLoader instead.  As a temporary
  34.105 + * transition feature in the initial implementation, if the Logger is
  34.106 + * unable to locate a ResourceBundle from the ContextClassLoader or
  34.107 + * SystemClassLoader the Logger will also search up the class stack
  34.108 + * and use successive calling ClassLoaders to try to locate a ResourceBundle.
  34.109 + * (This call stack search is to allow containers to transition to
  34.110 + * using ContextClassLoaders and is likely to be removed in future
  34.111 + * versions.)
  34.112 + * <p>
  34.113 + * Formatting (including localization) is the responsibility of
  34.114 + * the output Handler, which will typically call a Formatter.
  34.115 + * <p>
  34.116 + * Note that formatting need not occur synchronously.  It may be delayed
  34.117 + * until a LogRecord is actually written to an external sink.
  34.118 + * <p>
  34.119 + * The logging methods are grouped in five main categories:
  34.120 + * <ul>
  34.121 + * <li><p>
  34.122 + *     There are a set of "log" methods that take a log level, a message
  34.123 + *     string, and optionally some parameters to the message string.
  34.124 + * <li><p>
  34.125 + *     There are a set of "logp" methods (for "log precise") that are
  34.126 + *     like the "log" methods, but also take an explicit source class name
  34.127 + *     and method name.
  34.128 + * <li><p>
  34.129 + *     There are a set of "logrb" method (for "log with resource bundle")
  34.130 + *     that are like the "logp" method, but also take an explicit resource
  34.131 + *     bundle name for use in localizing the log message.
  34.132 + * <li><p>
  34.133 + *     There are convenience methods for tracing method entries (the
  34.134 + *     "entering" methods), method returns (the "exiting" methods) and
  34.135 + *     throwing exceptions (the "throwing" methods).
  34.136 + * <li><p>
  34.137 + *     Finally, there are a set of convenience methods for use in the
  34.138 + *     very simplest cases, when a developer simply wants to log a
  34.139 + *     simple string at a given log level.  These methods are named
  34.140 + *     after the standard Level names ("severe", "warning", "info", etc.)
  34.141 + *     and take a single argument, a message string.
  34.142 + * </ul>
  34.143 + * <p>
  34.144 + * For the methods that do not take an explicit source name and
  34.145 + * method name, the Logging framework will make a "best effort"
  34.146 + * to determine which class and method called into the logging method.
  34.147 + * However, it is important to realize that this automatically inferred
  34.148 + * information may only be approximate (or may even be quite wrong!).
  34.149 + * Virtual machines are allowed to do extensive optimizations when
  34.150 + * JITing and may entirely remove stack frames, making it impossible
  34.151 + * to reliably locate the calling class and method.
  34.152 + * <P>
  34.153 + * All methods on Logger are multi-thread safe.
  34.154 + * <p>
  34.155 + * <b>Subclassing Information:</b> Note that a LogManager class may
  34.156 + * provide its own implementation of named Loggers for any point in
  34.157 + * the namespace.  Therefore, any subclasses of Logger (unless they
  34.158 + * are implemented in conjunction with a new LogManager class) should
  34.159 + * take care to obtain a Logger instance from the LogManager class and
  34.160 + * should delegate operations such as "isLoggable" and "log(LogRecord)"
  34.161 + * to that instance.  Note that in order to intercept all logging
  34.162 + * output, subclasses need only override the log(LogRecord) method.
  34.163 + * All the other logging methods are implemented as calls on this
  34.164 + * log(LogRecord) method.
  34.165 + *
  34.166 + * @since 1.4
  34.167 + */
  34.168 +
  34.169 +
  34.170 +public class Logger {
  34.171 +    private static final Handler emptyHandlers[] = new Handler[0];
  34.172 +    private static final int offValue = Level.OFF.intValue();
  34.173 +    private LogManager manager;
  34.174 +    private String name;
  34.175 +    private final CopyOnWriteArrayList<Handler> handlers =
  34.176 +        new CopyOnWriteArrayList<>();
  34.177 +    private String resourceBundleName;
  34.178 +    private volatile boolean useParentHandlers = true;
  34.179 +    private volatile Filter filter;
  34.180 +    private boolean anonymous;
  34.181 +
  34.182 +    private ResourceBundle catalog;     // Cached resource bundle
  34.183 +    private String catalogName;         // name associated with catalog
  34.184 +    private Locale catalogLocale;       // locale associated with catalog
  34.185 +
  34.186 +    // The fields relating to parent-child relationships and levels
  34.187 +    // are managed under a separate lock, the treeLock.
  34.188 +    private static Object treeLock = new Object();
  34.189 +    // We keep weak references from parents to children, but strong
  34.190 +    // references from children to parents.
  34.191 +    private volatile Logger parent;    // our nearest parent.
  34.192 +    private ArrayList<LogManager.LoggerWeakRef> kids;   // WeakReferences to loggers that have us as parent
  34.193 +    private volatile Level levelObject;
  34.194 +    private volatile int levelValue;  // current effective level value
  34.195 +
  34.196 +    /**
  34.197 +     * GLOBAL_LOGGER_NAME is a name for the global logger.
  34.198 +     *
  34.199 +     * @since 1.6
  34.200 +     */
  34.201 +    public static final String GLOBAL_LOGGER_NAME = "global";
  34.202 +
  34.203 +    /**
  34.204 +     * Return global logger object with the name Logger.GLOBAL_LOGGER_NAME.
  34.205 +     *
  34.206 +     * @return global logger object
  34.207 +     * @since 1.7
  34.208 +     */
  34.209 +    public static final Logger getGlobal() {
  34.210 +        return global;
  34.211 +    }
  34.212 +
  34.213 +    /**
  34.214 +     * The "global" Logger object is provided as a convenience to developers
  34.215 +     * who are making casual use of the Logging package.  Developers
  34.216 +     * who are making serious use of the logging package (for example
  34.217 +     * in products) should create and use their own Logger objects,
  34.218 +     * with appropriate names, so that logging can be controlled on a
  34.219 +     * suitable per-Logger granularity. Developers also need to keep a
  34.220 +     * strong reference to their Logger objects to prevent them from
  34.221 +     * being garbage collected.
  34.222 +     * <p>
  34.223 +     * @deprecated Initialization of this field is prone to deadlocks.
  34.224 +     * The field must be initialized by the Logger class initialization
  34.225 +     * which may cause deadlocks with the LogManager class initialization.
  34.226 +     * In such cases two class initialization wait for each other to complete.
  34.227 +     * The preferred way to get the global logger object is via the call
  34.228 +     * <code>Logger.getGlobal()</code>.
  34.229 +     * For compatibility with old JDK versions where the
  34.230 +     * <code>Logger.getGlobal()</code> is not available use the call
  34.231 +     * <code>Logger.getLogger(Logger.GLOBAL_LOGGER_NAME)</code>
  34.232 +     * or <code>Logger.getLogger("global")</code>.
  34.233 +     */
  34.234 +    @Deprecated
  34.235 +    public static final Logger global = new Logger(GLOBAL_LOGGER_NAME);
  34.236 +
  34.237 +    /**
  34.238 +     * Protected method to construct a logger for a named subsystem.
  34.239 +     * <p>
  34.240 +     * The logger will be initially configured with a null Level
  34.241 +     * and with useParentHandlers set to true.
  34.242 +     *
  34.243 +     * @param   name    A name for the logger.  This should
  34.244 +     *                          be a dot-separated name and should normally
  34.245 +     *                          be based on the package name or class name
  34.246 +     *                          of the subsystem, such as java.net
  34.247 +     *                          or javax.swing.  It may be null for anonymous Loggers.
  34.248 +     * @param   resourceBundleName  name of ResourceBundle to be used for localizing
  34.249 +     *                          messages for this logger.  May be null if none
  34.250 +     *                          of the messages require localization.
  34.251 +     * @throws MissingResourceException if the resourceBundleName is non-null and
  34.252 +     *             no corresponding resource can be found.
  34.253 +     */
  34.254 +    protected Logger(String name, String resourceBundleName) {
  34.255 +        this.manager = LogManager.getLogManager();
  34.256 +        if (resourceBundleName != null) {
  34.257 +            // Note: we may get a MissingResourceException here.
  34.258 +            setupResourceInfo(resourceBundleName);
  34.259 +        }
  34.260 +        this.name = name;
  34.261 +        levelValue = Level.INFO.intValue();
  34.262 +    }
  34.263 +
  34.264 +    // This constructor is used only to create the global Logger.
  34.265 +    // It is needed to break a cyclic dependence between the LogManager
  34.266 +    // and Logger static initializers causing deadlocks.
  34.267 +    private Logger(String name) {
  34.268 +        // The manager field is not initialized here.
  34.269 +        this.name = name;
  34.270 +        levelValue = Level.INFO.intValue();
  34.271 +    }
  34.272 +
  34.273 +    // It is called from the LogManager.<clinit> to complete
  34.274 +    // initialization of the global Logger.
  34.275 +    void setLogManager(LogManager manager) {
  34.276 +        this.manager = manager;
  34.277 +    }
  34.278 +
  34.279 +    private void checkAccess() throws SecurityException {
  34.280 +        if (!anonymous) {
  34.281 +            if (manager == null) {
  34.282 +                // Complete initialization of the global Logger.
  34.283 +                manager = LogManager.getLogManager();
  34.284 +            }
  34.285 +            manager.checkAccess();
  34.286 +        }
  34.287 +    }
  34.288 +
  34.289 +    /**
  34.290 +     * Find or create a logger for a named subsystem.  If a logger has
  34.291 +     * already been created with the given name it is returned.  Otherwise
  34.292 +     * a new logger is created.
  34.293 +     * <p>
  34.294 +     * If a new logger is created its log level will be configured
  34.295 +     * based on the LogManager configuration and it will configured
  34.296 +     * to also send logging output to its parent's Handlers.  It will
  34.297 +     * be registered in the LogManager global namespace.
  34.298 +     * <p>
  34.299 +     * Note: The LogManager may only retain a weak reference to the newly
  34.300 +     * created Logger. It is important to understand that a previously
  34.301 +     * created Logger with the given name may be garbage collected at any
  34.302 +     * time if there is no strong reference to the Logger. In particular,
  34.303 +     * this means that two back-to-back calls like
  34.304 +     * {@code getLogger("MyLogger").log(...)} may use different Logger
  34.305 +     * objects named "MyLogger" if there is no strong reference to the
  34.306 +     * Logger named "MyLogger" elsewhere in the program.
  34.307 +     *
  34.308 +     * @param   name            A name for the logger.  This should
  34.309 +     *                          be a dot-separated name and should normally
  34.310 +     *                          be based on the package name or class name
  34.311 +     *                          of the subsystem, such as java.net
  34.312 +     *                          or javax.swing
  34.313 +     * @return a suitable Logger
  34.314 +     * @throws NullPointerException if the name is null.
  34.315 +     */
  34.316 +
  34.317 +    // Synchronization is not required here. All synchronization for
  34.318 +    // adding a new Logger object is handled by LogManager.addLogger().
  34.319 +    public static Logger getLogger(String name) {
  34.320 +        // This method is intentionally not a wrapper around a call
  34.321 +        // to getLogger(name, resourceBundleName). If it were then
  34.322 +        // this sequence:
  34.323 +        //
  34.324 +        //     getLogger("Foo", "resourceBundleForFoo");
  34.325 +        //     getLogger("Foo");
  34.326 +        //
  34.327 +        // would throw an IllegalArgumentException in the second call
  34.328 +        // because the wrapper would result in an attempt to replace
  34.329 +        // the existing "resourceBundleForFoo" with null.
  34.330 +        LogManager manager = LogManager.getLogManager();
  34.331 +        return manager.demandLogger(name);
  34.332 +    }
  34.333 +
  34.334 +    /**
  34.335 +     * Find or create a logger for a named subsystem.  If a logger has
  34.336 +     * already been created with the given name it is returned.  Otherwise
  34.337 +     * a new logger is created.
  34.338 +     * <p>
  34.339 +     * If a new logger is created its log level will be configured
  34.340 +     * based on the LogManager and it will configured to also send logging
  34.341 +     * output to its parent's Handlers.  It will be registered in
  34.342 +     * the LogManager global namespace.
  34.343 +     * <p>
  34.344 +     * Note: The LogManager may only retain a weak reference to the newly
  34.345 +     * created Logger. It is important to understand that a previously
  34.346 +     * created Logger with the given name may be garbage collected at any
  34.347 +     * time if there is no strong reference to the Logger. In particular,
  34.348 +     * this means that two back-to-back calls like
  34.349 +     * {@code getLogger("MyLogger", ...).log(...)} may use different Logger
  34.350 +     * objects named "MyLogger" if there is no strong reference to the
  34.351 +     * Logger named "MyLogger" elsewhere in the program.
  34.352 +     * <p>
  34.353 +     * If the named Logger already exists and does not yet have a
  34.354 +     * localization resource bundle then the given resource bundle
  34.355 +     * name is used.  If the named Logger already exists and has
  34.356 +     * a different resource bundle name then an IllegalArgumentException
  34.357 +     * is thrown.
  34.358 +     * <p>
  34.359 +     * @param   name    A name for the logger.  This should
  34.360 +     *                          be a dot-separated name and should normally
  34.361 +     *                          be based on the package name or class name
  34.362 +     *                          of the subsystem, such as java.net
  34.363 +     *                          or javax.swing
  34.364 +     * @param   resourceBundleName  name of ResourceBundle to be used for localizing
  34.365 +     *                          messages for this logger. May be <CODE>null</CODE> if none of
  34.366 +     *                          the messages require localization.
  34.367 +     * @return a suitable Logger
  34.368 +     * @throws MissingResourceException if the resourceBundleName is non-null and
  34.369 +     *             no corresponding resource can be found.
  34.370 +     * @throws IllegalArgumentException if the Logger already exists and uses
  34.371 +     *             a different resource bundle name.
  34.372 +     * @throws NullPointerException if the name is null.
  34.373 +     */
  34.374 +
  34.375 +    // Synchronization is not required here. All synchronization for
  34.376 +    // adding a new Logger object is handled by LogManager.addLogger().
  34.377 +    public static Logger getLogger(String name, String resourceBundleName) {
  34.378 +        LogManager manager = LogManager.getLogManager();
  34.379 +        Logger result = manager.demandLogger(name);
  34.380 +        if (result.resourceBundleName == null) {
  34.381 +            // Note: we may get a MissingResourceException here.
  34.382 +            result.setupResourceInfo(resourceBundleName);
  34.383 +        } else if (!result.resourceBundleName.equals(resourceBundleName)) {
  34.384 +            throw new IllegalArgumentException(result.resourceBundleName +
  34.385 +                                " != " + resourceBundleName);
  34.386 +        }
  34.387 +        return result;
  34.388 +    }
  34.389 +
  34.390 +
  34.391 +    /**
  34.392 +     * Create an anonymous Logger.  The newly created Logger is not
  34.393 +     * registered in the LogManager namespace.  There will be no
  34.394 +     * access checks on updates to the logger.
  34.395 +     * <p>
  34.396 +     * This factory method is primarily intended for use from applets.
  34.397 +     * Because the resulting Logger is anonymous it can be kept private
  34.398 +     * by the creating class.  This removes the need for normal security
  34.399 +     * checks, which in turn allows untrusted applet code to update
  34.400 +     * the control state of the Logger.  For example an applet can do
  34.401 +     * a setLevel or an addHandler on an anonymous Logger.
  34.402 +     * <p>
  34.403 +     * Even although the new logger is anonymous, it is configured
  34.404 +     * to have the root logger ("") as its parent.  This means that
  34.405 +     * by default it inherits its effective level and handlers
  34.406 +     * from the root logger.
  34.407 +     * <p>
  34.408 +     *
  34.409 +     * @return a newly created private Logger
  34.410 +     */
  34.411 +    public static Logger getAnonymousLogger() {
  34.412 +        return getAnonymousLogger(null);
  34.413 +    }
  34.414 +
  34.415 +    /**
  34.416 +     * Create an anonymous Logger.  The newly created Logger is not
  34.417 +     * registered in the LogManager namespace.  There will be no
  34.418 +     * access checks on updates to the logger.
  34.419 +     * <p>
  34.420 +     * This factory method is primarily intended for use from applets.
  34.421 +     * Because the resulting Logger is anonymous it can be kept private
  34.422 +     * by the creating class.  This removes the need for normal security
  34.423 +     * checks, which in turn allows untrusted applet code to update
  34.424 +     * the control state of the Logger.  For example an applet can do
  34.425 +     * a setLevel or an addHandler on an anonymous Logger.
  34.426 +     * <p>
  34.427 +     * Even although the new logger is anonymous, it is configured
  34.428 +     * to have the root logger ("") as its parent.  This means that
  34.429 +     * by default it inherits its effective level and handlers
  34.430 +     * from the root logger.
  34.431 +     * <p>
  34.432 +     * @param   resourceBundleName  name of ResourceBundle to be used for localizing
  34.433 +     *                          messages for this logger.
  34.434 +     *          May be null if none of the messages require localization.
  34.435 +     * @return a newly created private Logger
  34.436 +     * @throws MissingResourceException if the resourceBundleName is non-null and
  34.437 +     *             no corresponding resource can be found.
  34.438 +     */
  34.439 +
  34.440 +    // Synchronization is not required here. All synchronization for
  34.441 +    // adding a new anonymous Logger object is handled by doSetParent().
  34.442 +    public static Logger getAnonymousLogger(String resourceBundleName) {
  34.443 +        LogManager manager = LogManager.getLogManager();
  34.444 +        // cleanup some Loggers that have been GC'ed
  34.445 +        manager.drainLoggerRefQueueBounded();
  34.446 +        Logger result = new Logger(null, resourceBundleName);
  34.447 +        result.anonymous = true;
  34.448 +        Logger root = manager.getLogger("");
  34.449 +        result.doSetParent(root);
  34.450 +        return result;
  34.451 +    }
  34.452 +
  34.453 +    /**
  34.454 +     * Retrieve the localization resource bundle for this
  34.455 +     * logger for the current default locale.  Note that if
  34.456 +     * the result is null, then the Logger will use a resource
  34.457 +     * bundle inherited from its parent.
  34.458 +     *
  34.459 +     * @return localization bundle (may be null)
  34.460 +     */
  34.461 +    public ResourceBundle getResourceBundle() {
  34.462 +        return findResourceBundle(getResourceBundleName());
  34.463 +    }
  34.464 +
  34.465 +    /**
  34.466 +     * Retrieve the localization resource bundle name for this
  34.467 +     * logger.  Note that if the result is null, then the Logger
  34.468 +     * will use a resource bundle name inherited from its parent.
  34.469 +     *
  34.470 +     * @return localization bundle name (may be null)
  34.471 +     */
  34.472 +    public String getResourceBundleName() {
  34.473 +        return resourceBundleName;
  34.474 +    }
  34.475 +
  34.476 +    /**
  34.477 +     * Set a filter to control output on this Logger.
  34.478 +     * <P>
  34.479 +     * After passing the initial "level" check, the Logger will
  34.480 +     * call this Filter to check if a log record should really
  34.481 +     * be published.
  34.482 +     *
  34.483 +     * @param   newFilter  a filter object (may be null)
  34.484 +     * @exception  SecurityException  if a security manager exists and if
  34.485 +     *             the caller does not have LoggingPermission("control").
  34.486 +     */
  34.487 +    public void setFilter(Filter newFilter) throws SecurityException {
  34.488 +        checkAccess();
  34.489 +        filter = newFilter;
  34.490 +    }
  34.491 +
  34.492 +    /**
  34.493 +     * Get the current filter for this Logger.
  34.494 +     *
  34.495 +     * @return  a filter object (may be null)
  34.496 +     */
  34.497 +    public Filter getFilter() {
  34.498 +        return filter;
  34.499 +    }
  34.500 +
  34.501 +    /**
  34.502 +     * Log a LogRecord.
  34.503 +     * <p>
  34.504 +     * All the other logging methods in this class call through
  34.505 +     * this method to actually perform any logging.  Subclasses can
  34.506 +     * override this single method to capture all log activity.
  34.507 +     *
  34.508 +     * @param record the LogRecord to be published
  34.509 +     */
  34.510 +    public void log(LogRecord record) {
  34.511 +        if (record.getLevel().intValue() < levelValue || levelValue == offValue) {
  34.512 +            return;
  34.513 +        }
  34.514 +        Filter theFilter = filter;
  34.515 +        if (theFilter != null && !theFilter.isLoggable(record)) {
  34.516 +            return;
  34.517 +        }
  34.518 +
  34.519 +        // Post the LogRecord to all our Handlers, and then to
  34.520 +        // our parents' handlers, all the way up the tree.
  34.521 +
  34.522 +        Logger logger = this;
  34.523 +        while (logger != null) {
  34.524 +            for (Handler handler : logger.getHandlers()) {
  34.525 +                handler.publish(record);
  34.526 +            }
  34.527 +
  34.528 +            if (!logger.getUseParentHandlers()) {
  34.529 +                break;
  34.530 +            }
  34.531 +
  34.532 +            logger = logger.getParent();
  34.533 +        }
  34.534 +    }
  34.535 +
  34.536 +    // private support method for logging.
  34.537 +    // We fill in the logger name, resource bundle name, and
  34.538 +    // resource bundle and then call "void log(LogRecord)".
  34.539 +    private void doLog(LogRecord lr) {
  34.540 +        lr.setLoggerName(name);
  34.541 +        String ebname = getEffectiveResourceBundleName();
  34.542 +        if (ebname != null) {
  34.543 +            lr.setResourceBundleName(ebname);
  34.544 +            lr.setResourceBundle(findResourceBundle(ebname));
  34.545 +        }
  34.546 +        log(lr);
  34.547 +    }
  34.548 +
  34.549 +
  34.550 +    //================================================================
  34.551 +    // Start of convenience methods WITHOUT className and methodName
  34.552 +    //================================================================
  34.553 +
  34.554 +    /**
  34.555 +     * Log a message, with no arguments.
  34.556 +     * <p>
  34.557 +     * If the logger is currently enabled for the given message
  34.558 +     * level then the given message is forwarded to all the
  34.559 +     * registered output Handler objects.
  34.560 +     * <p>
  34.561 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.562 +     * @param   msg     The string message (or a key in the message catalog)
  34.563 +     */
  34.564 +    public void log(Level level, String msg) {
  34.565 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.566 +            return;
  34.567 +        }
  34.568 +        LogRecord lr = new LogRecord(level, msg);
  34.569 +        doLog(lr);
  34.570 +    }
  34.571 +
  34.572 +    /**
  34.573 +     * Log a message, with one object parameter.
  34.574 +     * <p>
  34.575 +     * If the logger is currently enabled for the given message
  34.576 +     * level then a corresponding LogRecord is created and forwarded
  34.577 +     * to all the registered output Handler objects.
  34.578 +     * <p>
  34.579 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.580 +     * @param   msg     The string message (or a key in the message catalog)
  34.581 +     * @param   param1  parameter to the message
  34.582 +     */
  34.583 +    public void log(Level level, String msg, Object param1) {
  34.584 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.585 +            return;
  34.586 +        }
  34.587 +        LogRecord lr = new LogRecord(level, msg);
  34.588 +        Object params[] = { param1 };
  34.589 +        lr.setParameters(params);
  34.590 +        doLog(lr);
  34.591 +    }
  34.592 +
  34.593 +    /**
  34.594 +     * Log a message, with an array of object arguments.
  34.595 +     * <p>
  34.596 +     * If the logger is currently enabled for the given message
  34.597 +     * level then a corresponding LogRecord is created and forwarded
  34.598 +     * to all the registered output Handler objects.
  34.599 +     * <p>
  34.600 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.601 +     * @param   msg     The string message (or a key in the message catalog)
  34.602 +     * @param   params  array of parameters to the message
  34.603 +     */
  34.604 +    public void log(Level level, String msg, Object params[]) {
  34.605 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.606 +            return;
  34.607 +        }
  34.608 +        LogRecord lr = new LogRecord(level, msg);
  34.609 +        lr.setParameters(params);
  34.610 +        doLog(lr);
  34.611 +    }
  34.612 +
  34.613 +    /**
  34.614 +     * Log a message, with associated Throwable information.
  34.615 +     * <p>
  34.616 +     * If the logger is currently enabled for the given message
  34.617 +     * level then the given arguments are stored in a LogRecord
  34.618 +     * which is forwarded to all registered output handlers.
  34.619 +     * <p>
  34.620 +     * Note that the thrown argument is stored in the LogRecord thrown
  34.621 +     * property, rather than the LogRecord parameters property.  Thus is it
  34.622 +     * processed specially by output Formatters and is not treated
  34.623 +     * as a formatting parameter to the LogRecord message property.
  34.624 +     * <p>
  34.625 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.626 +     * @param   msg     The string message (or a key in the message catalog)
  34.627 +     * @param   thrown  Throwable associated with log message.
  34.628 +     */
  34.629 +    public void log(Level level, String msg, Throwable thrown) {
  34.630 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.631 +            return;
  34.632 +        }
  34.633 +        LogRecord lr = new LogRecord(level, msg);
  34.634 +        lr.setThrown(thrown);
  34.635 +        doLog(lr);
  34.636 +    }
  34.637 +
  34.638 +    //================================================================
  34.639 +    // Start of convenience methods WITH className and methodName
  34.640 +    //================================================================
  34.641 +
  34.642 +    /**
  34.643 +     * Log a message, specifying source class and method,
  34.644 +     * with no arguments.
  34.645 +     * <p>
  34.646 +     * If the logger is currently enabled for the given message
  34.647 +     * level then the given message is forwarded to all the
  34.648 +     * registered output Handler objects.
  34.649 +     * <p>
  34.650 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.651 +     * @param   sourceClass    name of class that issued the logging request
  34.652 +     * @param   sourceMethod   name of method that issued the logging request
  34.653 +     * @param   msg     The string message (or a key in the message catalog)
  34.654 +     */
  34.655 +    public void logp(Level level, String sourceClass, String sourceMethod, String msg) {
  34.656 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.657 +            return;
  34.658 +        }
  34.659 +        LogRecord lr = new LogRecord(level, msg);
  34.660 +        lr.setSourceClassName(sourceClass);
  34.661 +        lr.setSourceMethodName(sourceMethod);
  34.662 +        doLog(lr);
  34.663 +    }
  34.664 +
  34.665 +    /**
  34.666 +     * Log a message, specifying source class and method,
  34.667 +     * with a single object parameter to the log message.
  34.668 +     * <p>
  34.669 +     * If the logger is currently enabled for the given message
  34.670 +     * level then a corresponding LogRecord is created and forwarded
  34.671 +     * to all the registered output Handler objects.
  34.672 +     * <p>
  34.673 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.674 +     * @param   sourceClass    name of class that issued the logging request
  34.675 +     * @param   sourceMethod   name of method that issued the logging request
  34.676 +     * @param   msg      The string message (or a key in the message catalog)
  34.677 +     * @param   param1    Parameter to the log message.
  34.678 +     */
  34.679 +    public void logp(Level level, String sourceClass, String sourceMethod,
  34.680 +                                                String msg, Object param1) {
  34.681 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.682 +            return;
  34.683 +        }
  34.684 +        LogRecord lr = new LogRecord(level, msg);
  34.685 +        lr.setSourceClassName(sourceClass);
  34.686 +        lr.setSourceMethodName(sourceMethod);
  34.687 +        Object params[] = { param1 };
  34.688 +        lr.setParameters(params);
  34.689 +        doLog(lr);
  34.690 +    }
  34.691 +
  34.692 +    /**
  34.693 +     * Log a message, specifying source class and method,
  34.694 +     * with an array of object arguments.
  34.695 +     * <p>
  34.696 +     * If the logger is currently enabled for the given message
  34.697 +     * level then a corresponding LogRecord is created and forwarded
  34.698 +     * to all the registered output Handler objects.
  34.699 +     * <p>
  34.700 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.701 +     * @param   sourceClass    name of class that issued the logging request
  34.702 +     * @param   sourceMethod   name of method that issued the logging request
  34.703 +     * @param   msg     The string message (or a key in the message catalog)
  34.704 +     * @param   params  Array of parameters to the message
  34.705 +     */
  34.706 +    public void logp(Level level, String sourceClass, String sourceMethod,
  34.707 +                                                String msg, Object params[]) {
  34.708 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.709 +            return;
  34.710 +        }
  34.711 +        LogRecord lr = new LogRecord(level, msg);
  34.712 +        lr.setSourceClassName(sourceClass);
  34.713 +        lr.setSourceMethodName(sourceMethod);
  34.714 +        lr.setParameters(params);
  34.715 +        doLog(lr);
  34.716 +    }
  34.717 +
  34.718 +    /**
  34.719 +     * Log a message, specifying source class and method,
  34.720 +     * with associated Throwable information.
  34.721 +     * <p>
  34.722 +     * If the logger is currently enabled for the given message
  34.723 +     * level then the given arguments are stored in a LogRecord
  34.724 +     * which is forwarded to all registered output handlers.
  34.725 +     * <p>
  34.726 +     * Note that the thrown argument is stored in the LogRecord thrown
  34.727 +     * property, rather than the LogRecord parameters property.  Thus is it
  34.728 +     * processed specially by output Formatters and is not treated
  34.729 +     * as a formatting parameter to the LogRecord message property.
  34.730 +     * <p>
  34.731 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.732 +     * @param   sourceClass    name of class that issued the logging request
  34.733 +     * @param   sourceMethod   name of method that issued the logging request
  34.734 +     * @param   msg     The string message (or a key in the message catalog)
  34.735 +     * @param   thrown  Throwable associated with log message.
  34.736 +     */
  34.737 +    public void logp(Level level, String sourceClass, String sourceMethod,
  34.738 +                                                        String msg, Throwable thrown) {
  34.739 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.740 +            return;
  34.741 +        }
  34.742 +        LogRecord lr = new LogRecord(level, msg);
  34.743 +        lr.setSourceClassName(sourceClass);
  34.744 +        lr.setSourceMethodName(sourceMethod);
  34.745 +        lr.setThrown(thrown);
  34.746 +        doLog(lr);
  34.747 +    }
  34.748 +
  34.749 +
  34.750 +    //=========================================================================
  34.751 +    // Start of convenience methods WITH className, methodName and bundle name.
  34.752 +    //=========================================================================
  34.753 +
  34.754 +    // Private support method for logging for "logrb" methods.
  34.755 +    // We fill in the logger name, resource bundle name, and
  34.756 +    // resource bundle and then call "void log(LogRecord)".
  34.757 +    private void doLog(LogRecord lr, String rbname) {
  34.758 +        lr.setLoggerName(name);
  34.759 +        if (rbname != null) {
  34.760 +            lr.setResourceBundleName(rbname);
  34.761 +            lr.setResourceBundle(findResourceBundle(rbname));
  34.762 +        }
  34.763 +        log(lr);
  34.764 +    }
  34.765 +
  34.766 +    /**
  34.767 +     * Log a message, specifying source class, method, and resource bundle name
  34.768 +     * with no arguments.
  34.769 +     * <p>
  34.770 +     * If the logger is currently enabled for the given message
  34.771 +     * level then the given message is forwarded to all the
  34.772 +     * registered output Handler objects.
  34.773 +     * <p>
  34.774 +     * The msg string is localized using the named resource bundle.  If the
  34.775 +     * resource bundle name is null, or an empty String or invalid
  34.776 +     * then the msg string is not localized.
  34.777 +     * <p>
  34.778 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.779 +     * @param   sourceClass    name of class that issued the logging request
  34.780 +     * @param   sourceMethod   name of method that issued the logging request
  34.781 +     * @param   bundleName     name of resource bundle to localize msg,
  34.782 +     *                         can be null
  34.783 +     * @param   msg     The string message (or a key in the message catalog)
  34.784 +     */
  34.785 +
  34.786 +    public void logrb(Level level, String sourceClass, String sourceMethod,
  34.787 +                                String bundleName, String msg) {
  34.788 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.789 +            return;
  34.790 +        }
  34.791 +        LogRecord lr = new LogRecord(level, msg);
  34.792 +        lr.setSourceClassName(sourceClass);
  34.793 +        lr.setSourceMethodName(sourceMethod);
  34.794 +        doLog(lr, bundleName);
  34.795 +    }
  34.796 +
  34.797 +    /**
  34.798 +     * Log a message, specifying source class, method, and resource bundle name,
  34.799 +     * with a single object parameter to the log message.
  34.800 +     * <p>
  34.801 +     * If the logger is currently enabled for the given message
  34.802 +     * level then a corresponding LogRecord is created and forwarded
  34.803 +     * to all the registered output Handler objects.
  34.804 +     * <p>
  34.805 +     * The msg string is localized using the named resource bundle.  If the
  34.806 +     * resource bundle name is null, or an empty String or invalid
  34.807 +     * then the msg string is not localized.
  34.808 +     * <p>
  34.809 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.810 +     * @param   sourceClass    name of class that issued the logging request
  34.811 +     * @param   sourceMethod   name of method that issued the logging request
  34.812 +     * @param   bundleName     name of resource bundle to localize msg,
  34.813 +     *                         can be null
  34.814 +     * @param   msg      The string message (or a key in the message catalog)
  34.815 +     * @param   param1    Parameter to the log message.
  34.816 +     */
  34.817 +    public void logrb(Level level, String sourceClass, String sourceMethod,
  34.818 +                                String bundleName, String msg, Object param1) {
  34.819 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.820 +            return;
  34.821 +        }
  34.822 +        LogRecord lr = new LogRecord(level, msg);
  34.823 +        lr.setSourceClassName(sourceClass);
  34.824 +        lr.setSourceMethodName(sourceMethod);
  34.825 +        Object params[] = { param1 };
  34.826 +        lr.setParameters(params);
  34.827 +        doLog(lr, bundleName);
  34.828 +    }
  34.829 +
  34.830 +    /**
  34.831 +     * Log a message, specifying source class, method, and resource bundle name,
  34.832 +     * with an array of object arguments.
  34.833 +     * <p>
  34.834 +     * If the logger is currently enabled for the given message
  34.835 +     * level then a corresponding LogRecord is created and forwarded
  34.836 +     * to all the registered output Handler objects.
  34.837 +     * <p>
  34.838 +     * The msg string is localized using the named resource bundle.  If the
  34.839 +     * resource bundle name is null, or an empty String or invalid
  34.840 +     * then the msg string is not localized.
  34.841 +     * <p>
  34.842 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.843 +     * @param   sourceClass    name of class that issued the logging request
  34.844 +     * @param   sourceMethod   name of method that issued the logging request
  34.845 +     * @param   bundleName     name of resource bundle to localize msg,
  34.846 +     *                         can be null.
  34.847 +     * @param   msg     The string message (or a key in the message catalog)
  34.848 +     * @param   params  Array of parameters to the message
  34.849 +     */
  34.850 +    public void logrb(Level level, String sourceClass, String sourceMethod,
  34.851 +                                String bundleName, String msg, Object params[]) {
  34.852 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.853 +            return;
  34.854 +        }
  34.855 +        LogRecord lr = new LogRecord(level, msg);
  34.856 +        lr.setSourceClassName(sourceClass);
  34.857 +        lr.setSourceMethodName(sourceMethod);
  34.858 +        lr.setParameters(params);
  34.859 +        doLog(lr, bundleName);
  34.860 +    }
  34.861 +
  34.862 +    /**
  34.863 +     * Log a message, specifying source class, method, and resource bundle name,
  34.864 +     * with associated Throwable information.
  34.865 +     * <p>
  34.866 +     * If the logger is currently enabled for the given message
  34.867 +     * level then the given arguments are stored in a LogRecord
  34.868 +     * which is forwarded to all registered output handlers.
  34.869 +     * <p>
  34.870 +     * The msg string is localized using the named resource bundle.  If the
  34.871 +     * resource bundle name is null, or an empty String or invalid
  34.872 +     * then the msg string is not localized.
  34.873 +     * <p>
  34.874 +     * Note that the thrown argument is stored in the LogRecord thrown
  34.875 +     * property, rather than the LogRecord parameters property.  Thus is it
  34.876 +     * processed specially by output Formatters and is not treated
  34.877 +     * as a formatting parameter to the LogRecord message property.
  34.878 +     * <p>
  34.879 +     * @param   level   One of the message level identifiers, e.g., SEVERE
  34.880 +     * @param   sourceClass    name of class that issued the logging request
  34.881 +     * @param   sourceMethod   name of method that issued the logging request
  34.882 +     * @param   bundleName     name of resource bundle to localize msg,
  34.883 +     *                         can be null
  34.884 +     * @param   msg     The string message (or a key in the message catalog)
  34.885 +     * @param   thrown  Throwable associated with log message.
  34.886 +     */
  34.887 +    public void logrb(Level level, String sourceClass, String sourceMethod,
  34.888 +                                        String bundleName, String msg, Throwable thrown) {
  34.889 +        if (level.intValue() < levelValue || levelValue == offValue) {
  34.890 +            return;
  34.891 +        }
  34.892 +        LogRecord lr = new LogRecord(level, msg);
  34.893 +        lr.setSourceClassName(sourceClass);
  34.894 +        lr.setSourceMethodName(sourceMethod);
  34.895 +        lr.setThrown(thrown);
  34.896 +        doLog(lr, bundleName);
  34.897 +    }
  34.898 +
  34.899 +
  34.900 +    //======================================================================
  34.901 +    // Start of convenience methods for logging method entries and returns.
  34.902 +    //======================================================================
  34.903 +
  34.904 +    /**
  34.905 +     * Log a method entry.
  34.906 +     * <p>
  34.907 +     * This is a convenience method that can be used to log entry
  34.908 +     * to a method.  A LogRecord with message "ENTRY", log level
  34.909 +     * FINER, and the given sourceMethod and sourceClass is logged.
  34.910 +     * <p>
  34.911 +     * @param   sourceClass    name of class that issued the logging request
  34.912 +     * @param   sourceMethod   name of method that is being entered
  34.913 +     */
  34.914 +    public void entering(String sourceClass, String sourceMethod) {
  34.915 +        if (Level.FINER.intValue() < levelValue) {
  34.916 +            return;
  34.917 +        }
  34.918 +        logp(Level.FINER, sourceClass, sourceMethod, "ENTRY");
  34.919 +    }
  34.920 +
  34.921 +    /**
  34.922 +     * Log a method entry, with one parameter.
  34.923 +     * <p>
  34.924 +     * This is a convenience method that can be used to log entry
  34.925 +     * to a method.  A LogRecord with message "ENTRY {0}", log level
  34.926 +     * FINER, and the given sourceMethod, sourceClass, and parameter
  34.927 +     * is logged.
  34.928 +     * <p>
  34.929 +     * @param   sourceClass    name of class that issued the logging request
  34.930 +     * @param   sourceMethod   name of method that is being entered
  34.931 +     * @param   param1         parameter to the method being entered
  34.932 +     */
  34.933 +    public void entering(String sourceClass, String sourceMethod, Object param1) {
  34.934 +        if (Level.FINER.intValue() < levelValue) {
  34.935 +            return;
  34.936 +        }
  34.937 +        Object params[] = { param1 };
  34.938 +        logp(Level.FINER, sourceClass, sourceMethod, "ENTRY {0}", params);
  34.939 +    }
  34.940 +
  34.941 +    /**
  34.942 +     * Log a method entry, with an array of parameters.
  34.943 +     * <p>
  34.944 +     * This is a convenience method that can be used to log entry
  34.945 +     * to a method.  A LogRecord with message "ENTRY" (followed by a
  34.946 +     * format {N} indicator for each entry in the parameter array),
  34.947 +     * log level FINER, and the given sourceMethod, sourceClass, and
  34.948 +     * parameters is logged.
  34.949 +     * <p>
  34.950 +     * @param   sourceClass    name of class that issued the logging request
  34.951 +     * @param   sourceMethod   name of method that is being entered
  34.952 +     * @param   params         array of parameters to the method being entered
  34.953 +     */
  34.954 +    public void entering(String sourceClass, String sourceMethod, Object params[]) {
  34.955 +        if (Level.FINER.intValue() < levelValue) {
  34.956 +            return;
  34.957 +        }
  34.958 +        String msg = "ENTRY";
  34.959 +        if (params == null ) {
  34.960 +           logp(Level.FINER, sourceClass, sourceMethod, msg);
  34.961 +           return;
  34.962 +        }
  34.963 +        for (int i = 0; i < params.length; i++) {
  34.964 +            msg = msg + " {" + i + "}";
  34.965 +        }
  34.966 +        logp(Level.FINER, sourceClass, sourceMethod, msg, params);
  34.967 +    }
  34.968 +
  34.969 +    /**
  34.970 +     * Log a method return.
  34.971 +     * <p>
  34.972 +     * This is a convenience method that can be used to log returning
  34.973 +     * from a method.  A LogRecord with message "RETURN", log level
  34.974 +     * FINER, and the given sourceMethod and sourceClass is logged.
  34.975 +     * <p>
  34.976 +     * @param   sourceClass    name of class that issued the logging request
  34.977 +     * @param   sourceMethod   name of the method
  34.978 +     */
  34.979 +    public void exiting(String sourceClass, String sourceMethod) {
  34.980 +        if (Level.FINER.intValue() < levelValue) {
  34.981 +            return;
  34.982 +        }
  34.983 +        logp(Level.FINER, sourceClass, sourceMethod, "RETURN");
  34.984 +    }
  34.985 +
  34.986 +
  34.987 +    /**
  34.988 +     * Log a method return, with result object.
  34.989 +     * <p>
  34.990 +     * This is a convenience method that can be used to log returning
  34.991 +     * from a method.  A LogRecord with message "RETURN {0}", log level
  34.992 +     * FINER, and the gives sourceMethod, sourceClass, and result
  34.993 +     * object is logged.
  34.994 +     * <p>
  34.995 +     * @param   sourceClass    name of class that issued the logging request
  34.996 +     * @param   sourceMethod   name of the method
  34.997 +     * @param   result  Object that is being returned
  34.998 +     */
  34.999 +    public void exiting(String sourceClass, String sourceMethod, Object result) {
 34.1000 +        if (Level.FINER.intValue() < levelValue) {
 34.1001 +            return;
 34.1002 +        }
 34.1003 +        Object params[] = { result };
 34.1004 +        logp(Level.FINER, sourceClass, sourceMethod, "RETURN {0}", result);
 34.1005 +    }
 34.1006 +
 34.1007 +    /**
 34.1008 +     * Log throwing an exception.
 34.1009 +     * <p>
 34.1010 +     * This is a convenience method to log that a method is
 34.1011 +     * terminating by throwing an exception.  The logging is done
 34.1012 +     * using the FINER level.
 34.1013 +     * <p>
 34.1014 +     * If the logger is currently enabled for the given message
 34.1015 +     * level then the given arguments are stored in a LogRecord
 34.1016 +     * which is forwarded to all registered output handlers.  The
 34.1017 +     * LogRecord's message is set to "THROW".
 34.1018 +     * <p>
 34.1019 +     * Note that the thrown argument is stored in the LogRecord thrown
 34.1020 +     * property, rather than the LogRecord parameters property.  Thus is it
 34.1021 +     * processed specially by output Formatters and is not treated
 34.1022 +     * as a formatting parameter to the LogRecord message property.
 34.1023 +     * <p>
 34.1024 +     * @param   sourceClass    name of class that issued the logging request
 34.1025 +     * @param   sourceMethod  name of the method.
 34.1026 +     * @param   thrown  The Throwable that is being thrown.
 34.1027 +     */
 34.1028 +    public void throwing(String sourceClass, String sourceMethod, Throwable thrown) {
 34.1029 +        if (Level.FINER.intValue() < levelValue || levelValue == offValue ) {
 34.1030 +            return;
 34.1031 +        }
 34.1032 +        LogRecord lr = new LogRecord(Level.FINER, "THROW");
 34.1033 +        lr.setSourceClassName(sourceClass);
 34.1034 +        lr.setSourceMethodName(sourceMethod);
 34.1035 +        lr.setThrown(thrown);
 34.1036 +        doLog(lr);
 34.1037 +    }
 34.1038 +
 34.1039 +    //=======================================================================
 34.1040 +    // Start of simple convenience methods using level names as method names
 34.1041 +    //=======================================================================
 34.1042 +
 34.1043 +    /**
 34.1044 +     * Log a SEVERE message.
 34.1045 +     * <p>
 34.1046 +     * If the logger is currently enabled for the SEVERE message
 34.1047 +     * level then the given message is forwarded to all the
 34.1048 +     * registered output Handler objects.
 34.1049 +     * <p>
 34.1050 +     * @param   msg     The string message (or a key in the message catalog)
 34.1051 +     */
 34.1052 +    public void severe(String msg) {
 34.1053 +        if (Level.SEVERE.intValue() < levelValue) {
 34.1054 +            return;
 34.1055 +        }
 34.1056 +        log(Level.SEVERE, msg);
 34.1057 +    }
 34.1058 +
 34.1059 +    /**
 34.1060 +     * Log a WARNING message.
 34.1061 +     * <p>
 34.1062 +     * If the logger is currently enabled for the WARNING message
 34.1063 +     * level then the given message is forwarded to all the
 34.1064 +     * registered output Handler objects.
 34.1065 +     * <p>
 34.1066 +     * @param   msg     The string message (or a key in the message catalog)
 34.1067 +     */
 34.1068 +    public void warning(String msg) {
 34.1069 +        if (Level.WARNING.intValue() < levelValue) {
 34.1070 +            return;
 34.1071 +        }
 34.1072 +        log(Level.WARNING, msg);
 34.1073 +    }
 34.1074 +
 34.1075 +    /**
 34.1076 +     * Log an INFO message.
 34.1077 +     * <p>
 34.1078 +     * If the logger is currently enabled for the INFO message
 34.1079 +     * level then the given message is forwarded to all the
 34.1080 +     * registered output Handler objects.
 34.1081 +     * <p>
 34.1082 +     * @param   msg     The string message (or a key in the message catalog)
 34.1083 +     */
 34.1084 +    public void info(String msg) {
 34.1085 +        if (Level.INFO.intValue() < levelValue) {
 34.1086 +            return;
 34.1087 +        }
 34.1088 +        log(Level.INFO, msg);
 34.1089 +    }
 34.1090 +
 34.1091 +    /**
 34.1092 +     * Log a CONFIG message.
 34.1093 +     * <p>
 34.1094 +     * If the logger is currently enabled for the CONFIG message
 34.1095 +     * level then the given message is forwarded to all the
 34.1096 +     * registered output Handler objects.
 34.1097 +     * <p>
 34.1098 +     * @param   msg     The string message (or a key in the message catalog)
 34.1099 +     */
 34.1100 +    public void config(String msg) {
 34.1101 +        if (Level.CONFIG.intValue() < levelValue) {
 34.1102 +            return;
 34.1103 +        }
 34.1104 +        log(Level.CONFIG, msg);
 34.1105 +    }
 34.1106 +
 34.1107 +    /**
 34.1108 +     * Log a FINE message.
 34.1109 +     * <p>
 34.1110 +     * If the logger is currently enabled for the FINE message
 34.1111 +     * level then the given message is forwarded to all the
 34.1112 +     * registered output Handler objects.
 34.1113 +     * <p>
 34.1114 +     * @param   msg     The string message (or a key in the message catalog)
 34.1115 +     */
 34.1116 +    public void fine(String msg) {
 34.1117 +        if (Level.FINE.intValue() < levelValue) {
 34.1118 +            return;
 34.1119 +        }
 34.1120 +        log(Level.FINE, msg);
 34.1121 +    }
 34.1122 +
 34.1123 +    /**
 34.1124 +     * Log a FINER message.
 34.1125 +     * <p>
 34.1126 +     * If the logger is currently enabled for the FINER message
 34.1127 +     * level then the given message is forwarded to all the
 34.1128 +     * registered output Handler objects.
 34.1129 +     * <p>
 34.1130 +     * @param   msg     The string message (or a key in the message catalog)
 34.1131 +     */
 34.1132 +    public void finer(String msg) {
 34.1133 +        if (Level.FINER.intValue() < levelValue) {
 34.1134 +            return;
 34.1135 +        }
 34.1136 +        log(Level.FINER, msg);
 34.1137 +    }
 34.1138 +
 34.1139 +    /**
 34.1140 +     * Log a FINEST message.
 34.1141 +     * <p>
 34.1142 +     * If the logger is currently enabled for the FINEST message
 34.1143 +     * level then the given message is forwarded to all the
 34.1144 +     * registered output Handler objects.
 34.1145 +     * <p>
 34.1146 +     * @param   msg     The string message (or a key in the message catalog)
 34.1147 +     */
 34.1148 +    public void finest(String msg) {
 34.1149 +        if (Level.FINEST.intValue() < levelValue) {
 34.1150 +            return;
 34.1151 +        }
 34.1152 +        log(Level.FINEST, msg);
 34.1153 +    }
 34.1154 +
 34.1155 +    //================================================================
 34.1156 +    // End of convenience methods
 34.1157 +    //================================================================
 34.1158 +
 34.1159 +    /**
 34.1160 +     * Set the log level specifying which message levels will be
 34.1161 +     * logged by this logger.  Message levels lower than this
 34.1162 +     * value will be discarded.  The level value Level.OFF
 34.1163 +     * can be used to turn off logging.
 34.1164 +     * <p>
 34.1165 +     * If the new level is null, it means that this node should
 34.1166 +     * inherit its level from its nearest ancestor with a specific
 34.1167 +     * (non-null) level value.
 34.1168 +     *
 34.1169 +     * @param newLevel   the new value for the log level (may be null)
 34.1170 +     * @exception  SecurityException  if a security manager exists and if
 34.1171 +     *             the caller does not have LoggingPermission("control").
 34.1172 +     */
 34.1173 +    public void setLevel(Level newLevel) throws SecurityException {
 34.1174 +        checkAccess();
 34.1175 +        synchronized (treeLock) {
 34.1176 +            levelObject = newLevel;
 34.1177 +            updateEffectiveLevel();
 34.1178 +        }
 34.1179 +    }
 34.1180 +
 34.1181 +    /**
 34.1182 +     * Get the log Level that has been specified for this Logger.
 34.1183 +     * The result may be null, which means that this logger's
 34.1184 +     * effective level will be inherited from its parent.
 34.1185 +     *
 34.1186 +     * @return  this Logger's level
 34.1187 +     */
 34.1188 +    public Level getLevel() {
 34.1189 +        return levelObject;
 34.1190 +    }
 34.1191 +
 34.1192 +    /**
 34.1193 +     * Check if a message of the given level would actually be logged
 34.1194 +     * by this logger.  This check is based on the Loggers effective level,
 34.1195 +     * which may be inherited from its parent.
 34.1196 +     *
 34.1197 +     * @param   level   a message logging level
 34.1198 +     * @return  true if the given message level is currently being logged.
 34.1199 +     */
 34.1200 +    public boolean isLoggable(Level level) {
 34.1201 +        if (level.intValue() < levelValue || levelValue == offValue) {
 34.1202 +            return false;
 34.1203 +        }
 34.1204 +        return true;
 34.1205 +    }
 34.1206 +
 34.1207 +    /**
 34.1208 +     * Get the name for this logger.
 34.1209 +     * @return logger name.  Will be null for anonymous Loggers.
 34.1210 +     */
 34.1211 +    public String getName() {
 34.1212 +        return name;
 34.1213 +    }
 34.1214 +
 34.1215 +    /**
 34.1216 +     * Add a log Handler to receive logging messages.
 34.1217 +     * <p>
 34.1218 +     * By default, Loggers also send their output to their parent logger.
 34.1219 +     * Typically the root Logger is configured with a set of Handlers
 34.1220 +     * that essentially act as default handlers for all loggers.
 34.1221 +     *
 34.1222 +     * @param   handler a logging Handler
 34.1223 +     * @exception  SecurityException  if a security manager exists and if
 34.1224 +     *             the caller does not have LoggingPermission("control").
 34.1225 +     */
 34.1226 +    public void addHandler(Handler handler) throws SecurityException {
 34.1227 +        // Check for null handler
 34.1228 +        handler.getClass();
 34.1229 +        checkAccess();
 34.1230 +        handlers.add(handler);
 34.1231 +    }
 34.1232 +
 34.1233 +    /**
 34.1234 +     * Remove a log Handler.
 34.1235 +     * <P>
 34.1236 +     * Returns silently if the given Handler is not found or is null
 34.1237 +     *
 34.1238 +     * @param   handler a logging Handler
 34.1239 +     * @exception  SecurityException  if a security manager exists and if
 34.1240 +     *             the caller does not have LoggingPermission("control").
 34.1241 +     */
 34.1242 +    public void removeHandler(Handler handler) throws SecurityException {
 34.1243 +        checkAccess();
 34.1244 +        if (handler == null) {
 34.1245 +            return;
 34.1246 +        }
 34.1247 +        handlers.remove(handler);
 34.1248 +    }
 34.1249 +
 34.1250 +    /**
 34.1251 +     * Get the Handlers associated with this logger.
 34.1252 +     * <p>
 34.1253 +     * @return  an array of all registered Handlers
 34.1254 +     */
 34.1255 +    public Handler[] getHandlers() {
 34.1256 +        return handlers.toArray(emptyHandlers);
 34.1257 +    }
 34.1258 +
 34.1259 +    /**
 34.1260 +     * Specify whether or not this logger should send its output
 34.1261 +     * to its parent Logger.  This means that any LogRecords will
 34.1262 +     * also be written to the parent's Handlers, and potentially
 34.1263 +     * to its parent, recursively up the namespace.
 34.1264 +     *
 34.1265 +     * @param useParentHandlers   true if output is to be sent to the
 34.1266 +     *          logger's parent.
 34.1267 +     * @exception  SecurityException  if a security manager exists and if
 34.1268 +     *             the caller does not have LoggingPermission("control").
 34.1269 +     */
 34.1270 +    public void setUseParentHandlers(boolean useParentHandlers) {
 34.1271 +        checkAccess();
 34.1272 +        this.useParentHandlers = useParentHandlers;
 34.1273 +    }
 34.1274 +
 34.1275 +    /**
 34.1276 +     * Discover whether or not this logger is sending its output
 34.1277 +     * to its parent logger.
 34.1278 +     *
 34.1279 +     * @return  true if output is to be sent to the logger's parent
 34.1280 +     */
 34.1281 +    public boolean getUseParentHandlers() {
 34.1282 +        return useParentHandlers;
 34.1283 +    }
 34.1284 +
 34.1285 +    // Private utility method to map a resource bundle name to an
 34.1286 +    // actual resource bundle, using a simple one-entry cache.
 34.1287 +    // Returns null for a null name.
 34.1288 +    // May also return null if we can't find the resource bundle and
 34.1289 +    // there is no suitable previous cached value.
 34.1290 +
 34.1291 +    private synchronized ResourceBundle findResourceBundle(String name) {
 34.1292 +        // Return a null bundle for a null name.
 34.1293 +        if (name == null) {
 34.1294 +            return null;
 34.1295 +        }
 34.1296 +
 34.1297 +        Locale currentLocale = Locale.getDefault();
 34.1298 +
 34.1299 +        // Normally we should hit on our simple one entry cache.
 34.1300 +        if (catalog != null && currentLocale == catalogLocale
 34.1301 +                                        && name == catalogName) {
 34.1302 +            return catalog;
 34.1303 +        }
 34.1304 +
 34.1305 +        // Use the thread's context ClassLoader.  If there isn't one,
 34.1306 +        // use the SystemClassloader.
 34.1307 +        ClassLoader cl = Thread.currentThread().getContextClassLoader();
 34.1308 +        if (cl == null) {
 34.1309 +            cl = ClassLoader.getSystemClassLoader();
 34.1310 +        }
 34.1311 +        try {
 34.1312 +            catalog = ResourceBundle.getBundle(name, currentLocale, cl);
 34.1313 +            catalogName = name;
 34.1314 +            catalogLocale = currentLocale;
 34.1315 +            return catalog;
 34.1316 +        } catch (MissingResourceException ex) {
 34.1317 +            // Woops.  We can't find the ResourceBundle in the default
 34.1318 +            // ClassLoader.  Drop through.
 34.1319 +        }
 34.1320 +
 34.1321 +
 34.1322 +        // Fall back to searching up the call stack and trying each
 34.1323 +        // calling ClassLoader.
 34.1324 +        for (int ix = 0; ; ix++) {
 34.1325 +            Class clz = sun.reflect.Reflection.getCallerClass(ix);
 34.1326 +            if (clz == null) {
 34.1327 +                break;
 34.1328 +            }
 34.1329 +            ClassLoader cl2 = clz.getClassLoader();
 34.1330 +            if (cl2 == null) {
 34.1331 +                cl2 = ClassLoader.getSystemClassLoader();
 34.1332 +            }
 34.1333 +            if (cl == cl2) {
 34.1334 +                // We've already checked this classloader.
 34.1335 +                continue;
 34.1336 +            }
 34.1337 +            cl = cl2;
 34.1338 +            try {
 34.1339 +                catalog = ResourceBundle.getBundle(name, currentLocale, cl);
 34.1340 +                catalogName = name;
 34.1341 +                catalogLocale = currentLocale;
 34.1342 +                return catalog;
 34.1343 +            } catch (MissingResourceException ex) {
 34.1344 +                // Ok, this one didn't work either.
 34.1345 +                // Drop through, and try the next one.
 34.1346 +            }
 34.1347 +        }
 34.1348 +
 34.1349 +        if (name.equals(catalogName)) {
 34.1350 +            // Return the previous cached value for that name.
 34.1351 +            // This may be null.
 34.1352 +            return catalog;
 34.1353 +        }
 34.1354 +        // Sorry, we're out of luck.
 34.1355 +        return null;
 34.1356 +    }
 34.1357 +
 34.1358 +    // Private utility method to initialize our one entry
 34.1359 +    // resource bundle cache.
 34.1360 +    // Note: for consistency reasons, we are careful to check
 34.1361 +    // that a suitable ResourceBundle exists before setting the
 34.1362 +    // ResourceBundleName.
 34.1363 +    private synchronized void setupResourceInfo(String name) {
 34.1364 +        if (name == null) {
 34.1365 +            return;
 34.1366 +        }
 34.1367 +        ResourceBundle rb = findResourceBundle(name);
 34.1368 +        if (rb == null) {
 34.1369 +            // We've failed to find an expected ResourceBundle.
 34.1370 +            throw new MissingResourceException("Can't find " + name + " bundle", name, "");
 34.1371 +        }
 34.1372 +        resourceBundleName = name;
 34.1373 +    }
 34.1374 +
 34.1375 +    /**
 34.1376 +     * Return the parent for this Logger.
 34.1377 +     * <p>
 34.1378 +     * This method returns the nearest extant parent in the namespace.
 34.1379 +     * Thus if a Logger is called "a.b.c.d", and a Logger called "a.b"
 34.1380 +     * has been created but no logger "a.b.c" exists, then a call of
 34.1381 +     * getParent on the Logger "a.b.c.d" will return the Logger "a.b".
 34.1382 +     * <p>
 34.1383 +     * The result will be null if it is called on the root Logger
 34.1384 +     * in the namespace.
 34.1385 +     *
 34.1386 +     * @return nearest existing parent Logger
 34.1387 +     */
 34.1388 +    public Logger getParent() {
 34.1389 +        // Note: this used to be synchronized on treeLock.  However, this only
 34.1390 +        // provided memory semantics, as there was no guarantee that the caller
 34.1391 +        // would synchronize on treeLock (in fact, there is no way for external
 34.1392 +        // callers to so synchronize).  Therefore, we have made parent volatile
 34.1393 +        // instead.
 34.1394 +        return parent;
 34.1395 +    }
 34.1396 +
 34.1397 +    /**
 34.1398 +     * Set the parent for this Logger.  This method is used by
 34.1399 +     * the LogManager to update a Logger when the namespace changes.
 34.1400 +     * <p>
 34.1401 +     * It should not be called from application code.
 34.1402 +     * <p>
 34.1403 +     * @param  parent   the new parent logger
 34.1404 +     * @exception  SecurityException  if a security manager exists and if
 34.1405 +     *             the caller does not have LoggingPermission("control").
 34.1406 +     */
 34.1407 +    public void setParent(Logger parent) {
 34.1408 +        if (parent == null) {
 34.1409 +            throw new NullPointerException();
 34.1410 +        }
 34.1411 +        manager.checkAccess();
 34.1412 +        doSetParent(parent);
 34.1413 +    }
 34.1414 +
 34.1415 +    // Private method to do the work for parenting a child
 34.1416 +    // Logger onto a parent logger.
 34.1417 +    private void doSetParent(Logger newParent) {
 34.1418 +
 34.1419 +        // System.err.println("doSetParent \"" + getName() + "\" \""
 34.1420 +        //                              + newParent.getName() + "\"");
 34.1421 +
 34.1422 +        synchronized (treeLock) {
 34.1423 +
 34.1424 +            // Remove ourself from any previous parent.
 34.1425 +            LogManager.LoggerWeakRef ref = null;
 34.1426 +            if (parent != null) {
 34.1427 +                // assert parent.kids != null;
 34.1428 +                for (Iterator<LogManager.LoggerWeakRef> iter = parent.kids.iterator(); iter.hasNext(); ) {
 34.1429 +                    ref = iter.next();
 34.1430 +                    Logger kid =  ref.get();
 34.1431 +                    if (kid == this) {
 34.1432 +                        // ref is used down below to complete the reparenting
 34.1433 +                        iter.remove();
 34.1434 +                        break;
 34.1435 +                    } else {
 34.1436 +                        ref = null;
 34.1437 +                    }
 34.1438 +                }
 34.1439 +                // We have now removed ourself from our parents' kids.
 34.1440 +            }
 34.1441 +
 34.1442 +            // Set our new parent.
 34.1443 +            parent = newParent;
 34.1444 +            if (parent.kids == null) {
 34.1445 +                parent.kids = new ArrayList<>(2);
 34.1446 +            }
 34.1447 +            if (ref == null) {
 34.1448 +                // we didn't have a previous parent
 34.1449 +                ref = manager.new LoggerWeakRef(this);
 34.1450 +            }
 34.1451 +            ref.setParentRef(new WeakReference<Logger>(parent));
 34.1452 +            parent.kids.add(ref);
 34.1453 +
 34.1454 +            // As a result of the reparenting, the effective level
 34.1455 +            // may have changed for us and our children.
 34.1456 +            updateEffectiveLevel();
 34.1457 +
 34.1458 +        }
 34.1459 +    }
 34.1460 +
 34.1461 +    // Package-level method.
 34.1462 +    // Remove the weak reference for the specified child Logger from the
 34.1463 +    // kid list. We should only be called from LoggerWeakRef.dispose().
 34.1464 +    final void removeChildLogger(LogManager.LoggerWeakRef child) {
 34.1465 +        synchronized (treeLock) {
 34.1466 +            for (Iterator<LogManager.LoggerWeakRef> iter = kids.iterator(); iter.hasNext(); ) {
 34.1467 +                LogManager.LoggerWeakRef ref = iter.next();
 34.1468 +                if (ref == child) {
 34.1469 +                    iter.remove();
 34.1470 +                    return;
 34.1471 +                }
 34.1472 +            }
 34.1473 +        }
 34.1474 +    }
 34.1475 +
 34.1476 +    // Recalculate the effective level for this node and
 34.1477 +    // recursively for our children.
 34.1478 +
 34.1479 +    private void updateEffectiveLevel() {
 34.1480 +        // assert Thread.holdsLock(treeLock);
 34.1481 +
 34.1482 +        // Figure out our current effective level.
 34.1483 +        int newLevelValue;
 34.1484 +        if (levelObject != null) {
 34.1485 +            newLevelValue = levelObject.intValue();
 34.1486 +        } else {
 34.1487 +            if (parent != null) {
 34.1488 +                newLevelValue = parent.levelValue;
 34.1489 +            } else {
 34.1490 +                // This may happen during initialization.
 34.1491 +                newLevelValue = Level.INFO.intValue();
 34.1492 +            }
 34.1493 +        }
 34.1494 +
 34.1495 +        // If our effective value hasn't changed, we're done.
 34.1496 +        if (levelValue == newLevelValue) {
 34.1497 +            return;
 34.1498 +        }
 34.1499 +
 34.1500 +        levelValue = newLevelValue;
 34.1501 +
 34.1502 +        // System.err.println("effective level: \"" + getName() + "\" := " + level);
 34.1503 +
 34.1504 +        // Recursively update the level on each of our kids.
 34.1505 +        if (kids != null) {
 34.1506 +            for (int i = 0; i < kids.size(); i++) {
 34.1507 +                LogManager.LoggerWeakRef ref = kids.get(i);
 34.1508 +                Logger kid =  ref.get();
 34.1509 +                if (kid != null) {
 34.1510 +                    kid.updateEffectiveLevel();
 34.1511 +                }
 34.1512 +            }
 34.1513 +        }
 34.1514 +    }
 34.1515 +
 34.1516 +
 34.1517 +    // Private method to get the potentially inherited
 34.1518 +    // resource bundle name for this Logger.
 34.1519 +    // May return null
 34.1520 +    private String getEffectiveResourceBundleName() {
 34.1521 +        Logger target = this;
 34.1522 +        while (target != null) {
 34.1523 +            String rbn = target.getResourceBundleName();
 34.1524 +            if (rbn != null) {
 34.1525 +                return rbn;
 34.1526 +            }
 34.1527 +            target = target.getParent();
 34.1528 +        }
 34.1529 +        return null;
 34.1530 +    }
 34.1531 +
 34.1532 +
 34.1533 +}