diff --git a/java/net/AbstractPlainDatagramSocketImpl.java b/java/net/AbstractPlainDatagramSocketImpl.java
new file mode 100644
index 0000000..a3c738a
--- /dev/null
+++ b/java/net/AbstractPlainDatagramSocketImpl.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+import libcore.io.IoBridge;
+import libcore.io.IoUtils;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.Enumeration;
+import java.security.AccessController;
+
+import dalvik.system.BlockGuard;
+import dalvik.system.CloseGuard;
+import sun.net.ResourceManager;
+
+/**
+ * Abstract datagram and multicast socket implementation base class.
+ * Note: This is not a public class, so that applets cannot call
+ * into the implementation directly and hence cannot bypass the
+ * security checks present in the DatagramSocket and MulticastSocket
+ * classes.
+ *
+ * @author Pavani Diwanji
+ */
+
+abstract class AbstractPlainDatagramSocketImpl extends DatagramSocketImpl
+{
+    /* timeout value for receive() */
+    int timeout = 0;
+    boolean connected = false;
+    private int trafficClass = 0;
+    protected InetAddress connectedAddress = null;
+    private int connectedPort = -1;
+
+    // Android-added: CloseGuard
+    private final CloseGuard guard = CloseGuard.get();
+
+    private static final String os = AccessController.doPrivileged(
+        new sun.security.action.GetPropertyAction("os.name")
+    );
+
+    /**
+     * flag set if the native connect() call not to be used
+     */
+    private final static boolean connectDisabled = os.contains("OS X");
+
+    // BEGIN Android-removed: Android doesn't need to load native net library
+    /**
+     * Load net library into runtime.
+     *
+    static {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("net");
+                    return null;
+                }
+            });
+    }
+    */
+    // END Android-removed: Android doesn't need to load native net library
+
+    /**
+     * Creates a datagram socket
+     */
+    protected synchronized void create() throws SocketException {
+        ResourceManager.beforeUdpCreate();
+        fd = new FileDescriptor();
+        try {
+            datagramSocketCreate();
+        } catch (SocketException ioe) {
+            ResourceManager.afterUdpClose();
+            fd = null;
+            throw ioe;
+        }
+
+        // Android-added: CloseGuard/fdsan
+        if (fd != null && fd.valid()) {
+            guard.open("close");
+            IoUtils.setFdOwner(fd, this);
+        }
+    }
+
+    /**
+     * Binds a datagram socket to a local port.
+     */
+    protected synchronized void bind(int lport, InetAddress laddr)
+        throws SocketException {
+        bind0(lport, laddr);
+    }
+
+    protected abstract void bind0(int lport, InetAddress laddr)
+        throws SocketException;
+
+    /**
+     * Sends a datagram packet. The packet contains the data and the
+     * destination address to send the packet to.
+     * @param p the packet to be sent.
+     */
+    protected abstract void send(DatagramPacket p) throws IOException;
+
+    /**
+     * Connects a datagram socket to a remote destination. This associates the remote
+     * address with the local socket so that datagrams may only be sent to this destination
+     * and received from this destination.
+     * @param address the remote InetAddress to connect to
+     * @param port the remote port number
+     */
+    protected void connect(InetAddress address, int port) throws SocketException {
+        // Android-added: BlockGuard
+        BlockGuard.getThreadPolicy().onNetwork();
+        connect0(address, port);
+        connectedAddress = address;
+        connectedPort = port;
+        connected = true;
+    }
+
+    /**
+     * Disconnects a previously connected socket. Does nothing if the socket was
+     * not connected already.
+     */
+    protected void disconnect() {
+        disconnect0(connectedAddress.holder().getFamily());
+        connected = false;
+        connectedAddress = null;
+        connectedPort = -1;
+    }
+
+    /**
+     * Peek at the packet to see who it is from.
+     * @param i the address to populate with the sender address
+     */
+    protected abstract int peek(InetAddress i) throws IOException;
+    protected abstract int peekData(DatagramPacket p) throws IOException;
+    /**
+     * Receive the datagram packet.
+     * @param p the packet to receive into
+     */
+    protected synchronized void receive(DatagramPacket p)
+        throws IOException {
+        receive0(p);
+    }
+
+    protected abstract void receive0(DatagramPacket p)
+        throws IOException;
+
+    /**
+     * Set the TTL (time-to-live) option.
+     * @param ttl TTL to be set.
+     */
+    protected abstract void setTimeToLive(int ttl) throws IOException;
+
+    /**
+     * Get the TTL (time-to-live) option.
+     */
+    protected abstract int getTimeToLive() throws IOException;
+
+    /**
+     * Set the TTL (time-to-live) option.
+     * @param ttl TTL to be set.
+     */
+    @Deprecated
+    protected abstract void setTTL(byte ttl) throws IOException;
+
+    /**
+     * Get the TTL (time-to-live) option.
+     */
+    @Deprecated
+    protected abstract byte getTTL() throws IOException;
+
+    /**
+     * Join the multicast group.
+     * @param inetaddr multicast address to join.
+     */
+    protected void join(InetAddress inetaddr) throws IOException {
+        join(inetaddr, null);
+    }
+
+    /**
+     * Leave the multicast group.
+     * @param inetaddr multicast address to leave.
+     */
+    protected void leave(InetAddress inetaddr) throws IOException {
+        leave(inetaddr, null);
+    }
+    /**
+     * Join the multicast group.
+     * @param mcastaddr multicast address to join.
+     * @param netIf specifies the local interface to receive multicast
+     *        datagram packets
+     * @throws  IllegalArgumentException if mcastaddr is null or is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     */
+
+    protected void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
+        throws IOException {
+        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+        join(((InetSocketAddress)mcastaddr).getAddress(), netIf);
+    }
+
+    protected abstract void join(InetAddress inetaddr, NetworkInterface netIf)
+        throws IOException;
+
+    /**
+     * Leave the multicast group.
+     * @param mcastaddr  multicast address to leave.
+     * @param netIf specified the local interface to leave the group at
+     * @throws  IllegalArgumentException if mcastaddr is null or is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     */
+    protected void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
+        throws IOException {
+        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+        leave(((InetSocketAddress)mcastaddr).getAddress(), netIf);
+    }
+
+    protected abstract void leave(InetAddress inetaddr, NetworkInterface netIf)
+        throws IOException;
+
+    /**
+     * Close the socket.
+     */
+    protected void close() {
+        // Android-added: CloseGuard
+        guard.close();
+
+        if (fd != null) {
+            datagramSocketClose();
+            ResourceManager.afterUdpClose();
+            fd = null;
+        }
+    }
+
+    protected boolean isClosed() {
+        return (fd == null) ? true : false;
+    }
+
+    protected void finalize() {
+        // Android-added: CloseGuard
+        if (guard != null) {
+            guard.warnIfOpen();
+        }
+
+        close();
+    }
+
+    /**
+     * set a value - since we only support (setting) binary options
+     * here, o must be a Boolean
+     */
+
+     public void setOption(int optID, Object o) throws SocketException {
+         if (isClosed()) {
+             throw new SocketException("Socket Closed");
+         }
+         switch (optID) {
+            /* check type safety b4 going native.  These should never
+             * fail, since only java.Socket* has access to
+             * PlainSocketImpl.setOption().
+             */
+         case SO_TIMEOUT:
+             if (o == null || !(o instanceof Integer)) {
+                 throw new SocketException("bad argument for SO_TIMEOUT");
+             }
+             int tmp = ((Integer) o).intValue();
+             if (tmp < 0)
+                 throw new IllegalArgumentException("timeout < 0");
+             timeout = tmp;
+             return;
+         case IP_TOS:
+             if (o == null || !(o instanceof Integer)) {
+                 throw new SocketException("bad argument for IP_TOS");
+             }
+             trafficClass = ((Integer)o).intValue();
+             break;
+         case SO_REUSEADDR:
+             if (o == null || !(o instanceof Boolean)) {
+                 throw new SocketException("bad argument for SO_REUSEADDR");
+             }
+             break;
+         case SO_BROADCAST:
+             if (o == null || !(o instanceof Boolean)) {
+                 throw new SocketException("bad argument for SO_BROADCAST");
+             }
+             break;
+         case SO_BINDADDR:
+             throw new SocketException("Cannot re-bind Socket");
+         case SO_RCVBUF:
+         case SO_SNDBUF:
+             if (o == null || !(o instanceof Integer) ||
+                 ((Integer)o).intValue() < 0) {
+                 throw new SocketException("bad argument for SO_SNDBUF or " +
+                                           "SO_RCVBUF");
+             }
+             break;
+         case IP_MULTICAST_IF:
+             if (o == null || !(o instanceof InetAddress))
+                 throw new SocketException("bad argument for IP_MULTICAST_IF");
+             break;
+         case IP_MULTICAST_IF2:
+             // Android-changed: Support Integer IP_MULTICAST_IF2 values for app compat. b/26790580
+             // if (o == null || !(o instanceof NetworkInterface))
+             if (o == null || !(o instanceof Integer || o instanceof NetworkInterface))
+                 throw new SocketException("bad argument for IP_MULTICAST_IF2");
+             if (o instanceof NetworkInterface) {
+                 o = new Integer(((NetworkInterface)o).getIndex());
+             }
+             break;
+         case IP_MULTICAST_LOOP:
+             if (o == null || !(o instanceof Boolean))
+                 throw new SocketException("bad argument for IP_MULTICAST_LOOP");
+             break;
+         default:
+             throw new SocketException("invalid option: " + optID);
+         }
+         socketSetOption(optID, o);
+     }
+
+    /*
+     * get option's state - set or not
+     */
+
+    public Object getOption(int optID) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket Closed");
+        }
+
+        Object result;
+
+        switch (optID) {
+            case SO_TIMEOUT:
+                result = new Integer(timeout);
+                break;
+
+            case IP_TOS:
+                result = socketGetOption(optID);
+                if ( ((Integer)result).intValue() == -1) {
+                    result = new Integer(trafficClass);
+                }
+                break;
+
+            case SO_BINDADDR:
+            case IP_MULTICAST_IF:
+            case IP_MULTICAST_IF2:
+            case SO_RCVBUF:
+            case SO_SNDBUF:
+            case IP_MULTICAST_LOOP:
+            case SO_REUSEADDR:
+            case SO_BROADCAST:
+                result = socketGetOption(optID);
+                // Android-added: Added for app compat reason. See methodgetNIFirstAddress
+                if (optID == IP_MULTICAST_IF) {
+                    return getNIFirstAddress((Integer)result);
+                }
+                break;
+
+            default:
+                throw new SocketException("invalid option: " + optID);
+        }
+
+        return result;
+    }
+
+    // BEGIN Android-added: Support Integer IP_MULTICAST_IF2 values for app compat. b/26790580
+    // Native code is changed to return the index of network interface when calling
+    // getOption(IP_MULTICAST_IF2) due to app compat reason.
+    //
+    // For getOption(IP_MULTICAST_IF), we should keep returning InetAddress instance. This method
+    // convert NetworkInterface index into InetAddress instance.
+    /** Return the first address bound to NetworkInterface with given ID.
+     * In case of niIndex == 0 or no address return anyLocalAddress
+     */
+    static InetAddress getNIFirstAddress(int niIndex) throws SocketException {
+        if (niIndex > 0) {
+            NetworkInterface networkInterface = NetworkInterface.getByIndex(niIndex);
+            Enumeration<InetAddress> addressesEnum = networkInterface.getInetAddresses();
+            if (addressesEnum.hasMoreElements()) {
+                return addressesEnum.nextElement();
+            }
+        }
+        return InetAddress.anyLocalAddress();
+    }
+    // END Android-added: Support Integer IP_MULTICAST_IF2 values for app compat. b/26790580
+
+    protected abstract void datagramSocketCreate() throws SocketException;
+    protected abstract void datagramSocketClose();
+    protected abstract void socketSetOption(int opt, Object val)
+        throws SocketException;
+    protected abstract Object socketGetOption(int opt) throws SocketException;
+
+    protected abstract void connect0(InetAddress address, int port) throws SocketException;
+    protected abstract void disconnect0(int family);
+
+    protected boolean nativeConnectDisabled() {
+        return connectDisabled;
+    }
+
+    // Android-changed: rewritten on the top of IoBridge
+    int dataAvailable() {
+        try {
+            return IoBridge.available(fd);
+        } catch (IOException e) {
+            return -1;
+        }
+    }
+}
diff --git a/java/net/AbstractPlainSocketImpl.java b/java/net/AbstractPlainSocketImpl.java
new file mode 100644
index 0000000..0500811
--- /dev/null
+++ b/java/net/AbstractPlainSocketImpl.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileDescriptor;
+
+import dalvik.annotation.optimization.ReachabilitySensitive;
+import dalvik.system.BlockGuard;
+import dalvik.system.CloseGuard;
+import dalvik.system.SocketTagger;
+import sun.net.ConnectionResetException;
+import sun.net.NetHooks;
+import sun.net.ResourceManager;
+
+/**
+ * Default Socket Implementation. This implementation does
+ * not implement any security checks.
+ * Note this class should <b>NOT</b> be public.
+ *
+ * @author  Steven B. Byrne
+ */
+abstract class AbstractPlainSocketImpl extends SocketImpl
+{
+    /* instance variable for SO_TIMEOUT */
+    int timeout;   // timeout in millisec
+    // Android-removed: traffic class is set through socket
+    // private int trafficClass;
+
+    private boolean shut_rd = false;
+    private boolean shut_wr = false;
+
+    private SocketInputStream socketInputStream = null;
+    private SocketOutputStream socketOutputStream = null;
+
+    /* number of threads using the FileDescriptor */
+    protected int fdUseCount = 0;
+
+    /* lock when increment/decrementing fdUseCount */
+    // Android-added: @ReachabilitySensitive
+    // Marked mostly because it's used where fd is, and fd isn't declared here.
+    // This adds reachabilityFences where we would if fd were annotated.
+    @ReachabilitySensitive
+    protected final Object fdLock = new Object();
+
+    /* indicates a close is pending on the file descriptor */
+    protected boolean closePending = false;
+
+    /* indicates connection reset state */
+    private int CONNECTION_NOT_RESET = 0;
+    private int CONNECTION_RESET_PENDING = 1;
+    private int CONNECTION_RESET = 2;
+    private int resetState;
+    private final Object resetLock = new Object();
+
+   /* whether this Socket is a stream (TCP) socket or not (UDP)
+    */
+    protected boolean stream;
+
+    // BEGIN Android-removed: Android doesn't need to load native net library
+    /*
+    /**
+     * Load net library into runtime.
+     *
+    static {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("net");
+                    return null;
+                }
+            });
+    }
+    */
+    // END Android-removed: Android doesn't need to load native net library
+
+    // Android-added: logs a warning if socket is not closed
+    @ReachabilitySensitive
+    private final CloseGuard guard = CloseGuard.get();
+
+    /**
+     * Creates a socket with a boolean that specifies whether this
+     * is a stream socket (true) or an unconnected UDP socket (false).
+     */
+    protected synchronized void create(boolean stream) throws IOException {
+        this.stream = stream;
+        if (!stream) {
+            ResourceManager.beforeUdpCreate();
+            // Android-removed: socketCreate should set fd if it succeeds
+            // fd = new FileDescriptor();
+            try {
+                socketCreate(false);
+            } catch (IOException ioe) {
+                ResourceManager.afterUdpClose();
+                // Android-removed: b/26470377 Represent closed sockets with invalid fd, not null.
+                // fd = null;
+                throw ioe;
+            }
+        } else {
+            // Android-removed: socketCreate should set fd if it succeeds
+            // fd = new FileDescriptor();
+            socketCreate(true);
+        }
+        if (socket != null)
+            socket.setCreated();
+        if (serverSocket != null)
+            serverSocket.setCreated();
+
+        // Android-added: CloseGuard
+        if (fd != null && fd.valid()) {
+            guard.open("close");
+        }
+    }
+
+    /**
+     * Creates a socket and connects it to the specified port on
+     * the specified host.
+     * @param host the specified host
+     * @param port the specified port
+     */
+    protected void connect(String host, int port)
+        throws UnknownHostException, IOException
+    {
+        boolean connected = false;
+        try {
+            InetAddress address = InetAddress.getByName(host);
+            this.port = port;
+            this.address = address;
+
+            connectToAddress(address, port, timeout);
+            connected = true;
+        } finally {
+            if (!connected) {
+                try {
+                    close();
+                } catch (IOException ioe) {
+                    /* Do nothing. If connect threw an exception then
+                       it will be passed up the call stack */
+                }
+            }
+        }
+    }
+
+    /**
+     * Creates a socket and connects it to the specified address on
+     * the specified port.
+     * @param address the address
+     * @param port the specified port
+     */
+    protected void connect(InetAddress address, int port) throws IOException {
+        this.port = port;
+        this.address = address;
+
+        try {
+            connectToAddress(address, port, timeout);
+            return;
+        } catch (IOException e) {
+            // everything failed
+            close();
+            throw e;
+        }
+    }
+
+    /**
+     * Creates a socket and connects it to the specified address on
+     * the specified port.
+     * @param address the address
+     * @param timeout the timeout value in milliseconds, or zero for no timeout.
+     * @throws IOException if connection fails
+     * @throws  IllegalArgumentException if address is null or is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     */
+    protected void connect(SocketAddress address, int timeout)
+            throws IOException {
+        boolean connected = false;
+        try {
+            if (address == null || !(address instanceof InetSocketAddress))
+                throw new IllegalArgumentException("unsupported address type");
+            InetSocketAddress addr = (InetSocketAddress) address;
+            if (addr.isUnresolved())
+                throw new UnknownHostException(addr.getHostName());
+            this.port = addr.getPort();
+            this.address = addr.getAddress();
+
+            connectToAddress(this.address, port, timeout);
+            connected = true;
+        } finally {
+            if (!connected) {
+                try {
+                    close();
+                } catch (IOException ioe) {
+                    /* Do nothing. If connect threw an exception then
+                       it will be passed up the call stack */
+                }
+            }
+        }
+    }
+
+    private void connectToAddress(InetAddress address, int port, int timeout) throws IOException {
+        if (address.isAnyLocalAddress()) {
+            doConnect(InetAddress.getLocalHost(), port, timeout);
+        } else {
+            doConnect(address, port, timeout);
+        }
+    }
+
+    public void setOption(int opt, Object val) throws SocketException {
+        if (isClosedOrPending()) {
+            throw new SocketException("Socket Closed");
+        }
+        // BEGIN Android-removed: Logic dealing with value type moved to socketSetOption.
+        /*
+        boolean on = true;
+        switch (opt) {
+            /* check type safety b4 going native.  These should never
+             * fail, since only java.Socket* has access to
+             * PlainSocketImpl.setOption().
+             *
+        case SO_LINGER:
+            if (val == null || (!(val instanceof Integer) && !(val instanceof Boolean)))
+                throw new SocketException("Bad parameter for option");
+            if (val instanceof Boolean) {
+                /* true only if disabling - enabling should be Integer *
+                on = false;
+            }
+            break;
+        case SO_TIMEOUT:
+            if (val == null || (!(val instanceof Integer)))
+                throw new SocketException("Bad parameter for SO_TIMEOUT");
+            int tmp = ((Integer) val).intValue();
+            if (tmp < 0)
+                throw new IllegalArgumentException("timeout < 0");
+            timeout = tmp;
+            break;
+        case IP_TOS:
+             if (val == null || !(val instanceof Integer)) {
+                 throw new SocketException("bad argument for IP_TOS");
+             }
+             trafficClass = ((Integer)val).intValue();
+             break;
+        case SO_BINDADDR:
+            throw new SocketException("Cannot re-bind socket");
+        case TCP_NODELAY:
+            if (val == null || !(val instanceof Boolean))
+                throw new SocketException("bad parameter for TCP_NODELAY");
+            on = ((Boolean)val).booleanValue();
+            break;
+        case SO_SNDBUF:
+        case SO_RCVBUF:
+            if (val == null || !(val instanceof Integer) ||
+                !(((Integer)val).intValue() > 0)) {
+                throw new SocketException("bad parameter for SO_SNDBUF " +
+                                          "or SO_RCVBUF");
+            }
+            break;
+        case SO_KEEPALIVE:
+            if (val == null || !(val instanceof Boolean))
+                throw new SocketException("bad parameter for SO_KEEPALIVE");
+            on = ((Boolean)val).booleanValue();
+            break;
+        case SO_OOBINLINE:
+            if (val == null || !(val instanceof Boolean))
+                throw new SocketException("bad parameter for SO_OOBINLINE");
+            on = ((Boolean)val).booleanValue();
+            break;
+        case SO_REUSEADDR:
+            if (val == null || !(val instanceof Boolean))
+                throw new SocketException("bad parameter for SO_REUSEADDR");
+            on = ((Boolean)val).booleanValue();
+            break;
+        default:
+            throw new SocketException("unrecognized TCP option: " + opt);
+        }
+        socketSetOption(opt, on, val);
+        */
+        // END Android-removed: Logic dealing with value type moved to socketSetOption.
+        // Android-added: Keep track of timeout value not handled by socketSetOption
+        if (opt == SO_TIMEOUT) {
+            timeout = (Integer) val;
+        }
+        socketSetOption(opt, val);
+    }
+    public Object getOption(int opt) throws SocketException {
+        if (isClosedOrPending()) {
+            throw new SocketException("Socket Closed");
+        }
+        if (opt == SO_TIMEOUT) {
+            return new Integer(timeout);
+        }
+        // BEGIN Android-changed: Logic dealing with value type moved to socketGetOption.
+        /*
+        int ret = 0;
+        /*
+         * The native socketGetOption() knows about 3 options.
+         * The 32 bit value it returns will be interpreted according
+         * to what we're asking.  A return of -1 means it understands
+         * the option but its turned off.  It will raise a SocketException
+         * if "opt" isn't one it understands.
+         *
+
+        switch (opt) {
+        case TCP_NODELAY:
+            ret = socketGetOption(opt, null);
+            return Boolean.valueOf(ret != -1);
+        case SO_OOBINLINE:
+            ret = socketGetOption(opt, null);
+            return Boolean.valueOf(ret != -1);
+        case SO_LINGER:
+            ret = socketGetOption(opt, null);
+            return (ret == -1) ? Boolean.FALSE: (Object)(new Integer(ret));
+        case SO_REUSEADDR:
+            ret = socketGetOption(opt, null);
+            return Boolean.valueOf(ret != -1);
+        case SO_BINDADDR:
+            InetAddressContainer in = new InetAddressContainer();
+            ret = socketGetOption(opt, in);
+            return in.addr;
+        case SO_SNDBUF:
+        case SO_RCVBUF:
+            ret = socketGetOption(opt, null);
+            return new Integer(ret);
+        case IP_TOS:
+            try {
+                ret = socketGetOption(opt, null);
+                if (ret == -1) { // ipv6 tos
+                    return trafficClass;
+                } else {
+                    return ret;
+                }
+            } catch (SocketException se) {
+                // TODO - should make better effort to read TOS or TCLASS
+                return trafficClass; // ipv6 tos
+            }
+        case SO_KEEPALIVE:
+            ret = socketGetOption(opt, null);
+            return Boolean.valueOf(ret != -1);
+        // should never get here
+        default:
+            return null;
+        }
+        */
+        return socketGetOption(opt);
+        // END Android-changed: Logic dealing with value type moved to socketGetOption.
+    }
+
+    /**
+     * The workhorse of the connection operation.  Tries several times to
+     * establish a connection to the given <host, port>.  If unsuccessful,
+     * throws an IOException indicating what went wrong.
+     */
+
+    synchronized void doConnect(InetAddress address, int port, int timeout) throws IOException {
+        synchronized (fdLock) {
+            if (!closePending && (socket == null || !socket.isBound())) {
+                NetHooks.beforeTcpConnect(fd, address, port);
+            }
+        }
+        try {
+            acquireFD();
+            try {
+                // Android-added: BlockGuard
+                BlockGuard.getThreadPolicy().onNetwork();
+                socketConnect(address, port, timeout);
+                /* socket may have been closed during poll/select */
+                synchronized (fdLock) {
+                    if (closePending) {
+                        throw new SocketException ("Socket closed");
+                    }
+                }
+                // If we have a ref. to the Socket, then sets the flags
+                // created, bound & connected to true.
+                // This is normally done in Socket.connect() but some
+                // subclasses of Socket may call impl.connect() directly!
+                if (socket != null) {
+                    socket.setBound();
+                    socket.setConnected();
+                }
+            } finally {
+                releaseFD();
+            }
+        } catch (IOException e) {
+            close();
+            throw e;
+        }
+    }
+
+    /**
+     * Binds the socket to the specified address of the specified local port.
+     * @param address the address
+     * @param lport the port
+     */
+    protected synchronized void bind(InetAddress address, int lport)
+        throws IOException
+    {
+       synchronized (fdLock) {
+            if (!closePending && (socket == null || !socket.isBound())) {
+                NetHooks.beforeTcpBind(fd, address, lport);
+            }
+        }
+        socketBind(address, lport);
+        if (socket != null)
+            socket.setBound();
+        if (serverSocket != null)
+            serverSocket.setBound();
+    }
+
+    /**
+     * Listens, for a specified amount of time, for connections.
+     * @param count the amount of time to listen for connections
+     */
+    protected synchronized void listen(int count) throws IOException {
+        socketListen(count);
+    }
+
+    /**
+     * Accepts connections.
+     * @param s the connection
+     */
+    protected void accept(SocketImpl s) throws IOException {
+        acquireFD();
+        try {
+            // Android-added: BlockGuard
+            BlockGuard.getThreadPolicy().onNetwork();
+            socketAccept(s);
+        } finally {
+            releaseFD();
+        }
+    }
+
+    /**
+     * Gets an InputStream for this socket.
+     */
+    protected synchronized InputStream getInputStream() throws IOException {
+        synchronized (fdLock) {
+            if (isClosedOrPending())
+                throw new IOException("Socket Closed");
+            if (shut_rd)
+                throw new IOException("Socket input is shutdown");
+            if (socketInputStream == null)
+                socketInputStream = new SocketInputStream(this);
+        }
+        return socketInputStream;
+    }
+
+    void setInputStream(SocketInputStream in) {
+        socketInputStream = in;
+    }
+
+    /**
+     * Gets an OutputStream for this socket.
+     */
+    protected synchronized OutputStream getOutputStream() throws IOException {
+        synchronized (fdLock) {
+            if (isClosedOrPending())
+                throw new IOException("Socket Closed");
+            if (shut_wr)
+                throw new IOException("Socket output is shutdown");
+            if (socketOutputStream == null)
+                socketOutputStream = new SocketOutputStream(this);
+        }
+        return socketOutputStream;
+    }
+
+    // Android-removed: this.fd is maintained by the concrete implementation.
+    /*
+    void setFileDescriptor(FileDescriptor fd) {
+        this.fd = fd;
+    }
+    */
+
+    void setAddress(InetAddress address) {
+        this.address = address;
+    }
+
+    void setPort(int port) {
+        this.port = port;
+    }
+
+    void setLocalPort(int localport) {
+        this.localport = localport;
+    }
+
+    /**
+     * Returns the number of bytes that can be read without blocking.
+     */
+    protected synchronized int available() throws IOException {
+        if (isClosedOrPending()) {
+            throw new IOException("Stream closed.");
+        }
+
+        /*
+         * If connection has been reset or shut down for input, then return 0
+         * to indicate there are no buffered bytes.
+         */
+        if (isConnectionReset() || shut_rd) {
+            return 0;
+        }
+
+        /*
+         * If no bytes available and we were previously notified
+         * of a connection reset then we move to the reset state.
+         *
+         * If are notified of a connection reset then check
+         * again if there are bytes buffered on the socket.
+         */
+        int n = 0;
+        try {
+            n = socketAvailable();
+            if (n == 0 && isConnectionResetPending()) {
+                setConnectionReset();
+            }
+        } catch (ConnectionResetException exc1) {
+            setConnectionResetPending();
+            try {
+                n = socketAvailable();
+                if (n == 0) {
+                    setConnectionReset();
+                }
+            } catch (ConnectionResetException exc2) {
+            }
+        }
+        return n;
+    }
+
+    /**
+     * Closes the socket.
+     */
+    protected void close() throws IOException {
+        synchronized(fdLock) {
+            if (fd != null && fd.valid()) {
+                if (!stream) {
+                    ResourceManager.afterUdpClose();
+                }
+                // Android-changed:
+                // Socket should be untagged before the preclose. After preclose,
+                // socket will dup2-ed to marker_fd, therefore, it won't describe the same file.
+                // If closingPending is true, then the socket has been preclosed.
+                //
+                // Also, close the CloseGuard when the #close is called.
+                if (!closePending) {
+                    closePending = true;
+                    guard.close();
+
+                    if (fdUseCount == 0) {
+                        /*
+                         * We close the FileDescriptor in two-steps - first the
+                         * "pre-close" which closes the socket but doesn't
+                         * release the underlying file descriptor. This operation
+                         * may be lengthy due to untransmitted data and a long
+                         * linger interval. Once the pre-close is done we do the
+                         * actual socket to release the fd.
+                         */
+                        try {
+                            socketPreClose();
+                        } finally {
+                            socketClose();
+                        }
+                        // Android-changed(http://b/26470377): Some Android code doesn't expect file
+                        // descriptor to be null. socketClose invalidates the fd by closing the fd.
+                        // fd = null;
+                        return;
+                    } else {
+                        /*
+                         * If a thread has acquired the fd and a close
+                         * isn't pending then use a deferred close.
+                         * Also decrement fdUseCount to signal the last
+                         * thread that releases the fd to close it.
+                         */
+                        fdUseCount--;
+                        socketPreClose();
+                    }
+                }
+            }
+        }
+    }
+
+    void reset() throws IOException {
+        if (fd != null && fd.valid()) {
+            socketClose();
+            // Android-changed: Notified the CloseGuard object as the fd has been released.
+            guard.close();
+        }
+        // Android-removed: b/26470377 Represent closed sockets with invalid fd, not null.
+        // fd = null;
+        super.reset();
+    }
+
+
+    /**
+     * Shutdown read-half of the socket connection;
+     */
+    protected void shutdownInput() throws IOException {
+      // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+      if (fd != null && fd.valid()) {
+          socketShutdown(SHUT_RD);
+          if (socketInputStream != null) {
+              socketInputStream.setEOF(true);
+          }
+          shut_rd = true;
+      }
+    }
+
+    /**
+     * Shutdown write-half of the socket connection;
+     */
+    protected void shutdownOutput() throws IOException {
+      // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+      if (fd != null && fd.valid()) {
+          socketShutdown(SHUT_WR);
+          shut_wr = true;
+      }
+    }
+
+    protected boolean supportsUrgentData () {
+        return true;
+    }
+
+    protected void sendUrgentData (int data) throws IOException {
+        // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+        if (fd == null || !fd.valid()) {
+            throw new IOException("Socket Closed");
+        }
+        socketSendUrgentData (data);
+    }
+
+    /**
+     * Cleans up if the user forgets to close it.
+     */
+    protected void finalize() throws IOException {
+        // Android-added: CloseGuard
+        if (guard != null) {
+            guard.warnIfOpen();
+        }
+
+        close();
+    }
+
+    /*
+     * "Acquires" and returns the FileDescriptor for this impl
+     *
+     * A corresponding releaseFD is required to "release" the
+     * FileDescriptor.
+     */
+    FileDescriptor acquireFD() {
+        synchronized (fdLock) {
+            fdUseCount++;
+            return fd;
+        }
+    }
+
+    /*
+     * "Release" the FileDescriptor for this impl.
+     *
+     * If the use count goes to -1 then the socket is closed.
+     */
+    void releaseFD() {
+        synchronized (fdLock) {
+            fdUseCount--;
+            if (fdUseCount == -1) {
+                if (fd != null) {
+                    try {
+                        socketClose();
+                    } catch (IOException e) {
+                        // Android-removed: b/26470377 Some Android code doesn't expect file
+                        // descriptor to be null. socketClose invalidates the fd by closing the fd.
+                        // } finally {
+                        //     fd = null;
+                    }
+                }
+            }
+        }
+    }
+
+    public boolean isConnectionReset() {
+        synchronized (resetLock) {
+            return (resetState == CONNECTION_RESET);
+        }
+    }
+
+    public boolean isConnectionResetPending() {
+        synchronized (resetLock) {
+            return (resetState == CONNECTION_RESET_PENDING);
+        }
+    }
+
+    public void setConnectionReset() {
+        synchronized (resetLock) {
+            resetState = CONNECTION_RESET;
+        }
+    }
+
+    public void setConnectionResetPending() {
+        synchronized (resetLock) {
+            if (resetState == CONNECTION_NOT_RESET) {
+                resetState = CONNECTION_RESET_PENDING;
+            }
+        }
+
+    }
+
+    /*
+     * Return true if already closed or close is pending
+     */
+    public boolean isClosedOrPending() {
+        /*
+         * Lock on fdLock to ensure that we wait if a
+         * close is in progress.
+         */
+        synchronized (fdLock) {
+            // Android-changed: b/26470377 Represent closed sockets with invalid fd, not null.
+            if (closePending || (fd == null) || !fd.valid()) {
+                return true;
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /*
+     * Return the current value of SO_TIMEOUT
+     */
+    public int getTimeout() {
+        return timeout;
+    }
+
+    /*
+     * "Pre-close" a socket by dup'ing the file descriptor - this enables
+     * the socket to be closed without releasing the file descriptor.
+     */
+    private void socketPreClose() throws IOException {
+        socketClose0(true);
+    }
+
+    /*
+     * Close the socket (and release the file descriptor).
+     */
+    protected void socketClose() throws IOException {
+        socketClose0(false);
+    }
+
+    abstract void socketCreate(boolean isServer) throws IOException;
+    abstract void socketConnect(InetAddress address, int port, int timeout)
+        throws IOException;
+    abstract void socketBind(InetAddress address, int port)
+        throws IOException;
+    abstract void socketListen(int count)
+        throws IOException;
+    abstract void socketAccept(SocketImpl s)
+        throws IOException;
+    abstract int socketAvailable()
+        throws IOException;
+    abstract void socketClose0(boolean useDeferredClose)
+        throws IOException;
+    abstract void socketShutdown(int howto)
+        throws IOException;
+
+    // Android-changed: Method signature changed, socket{Get,Set}Option work directly with Object
+    // values.
+    abstract void socketSetOption(int cmd, Object value) throws SocketException;
+    abstract Object socketGetOption(int opt) throws SocketException;
+
+    abstract void socketSendUrgentData(int data)
+        throws IOException;
+
+    public final static int SHUT_RD = 0;
+    public final static int SHUT_WR = 1;
+}
diff --git a/java/net/AddressCache.java b/java/net/AddressCache.java
new file mode 100644
index 0000000..3026923
--- /dev/null
+++ b/java/net/AddressCache.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import libcore.util.BasicLruCache;
+
+/**
+ * Implements caching for {@code InetAddress}. We use a unified cache for both positive and negative
+ * cache entries.
+ *
+ * TODO: benchmark and optimize InetAddress until we get to the point where we can just rely on
+ * the C library level caching. The main thing caching at this level buys us is avoiding repeated
+ * conversions from 'struct sockaddr's to InetAddress[].
+ */
+class AddressCache {
+    /**
+     * When the cache contains more entries than this, we start dropping the oldest ones.
+     * This should be a power of two to avoid wasted space in our custom map.
+     */
+    private static final int MAX_ENTRIES = 16;
+
+    // The TTL for the Java-level cache is short, just 2s.
+    private static final long TTL_NANOS = 2 * 1000000000L;
+
+    // The actual cache.
+    @UnsupportedAppUsage
+    private final BasicLruCache<AddressCacheKey, AddressCacheEntry> cache
+            = new BasicLruCache<AddressCacheKey, AddressCacheEntry>(MAX_ENTRIES);
+
+    static class AddressCacheKey {
+        @UnsupportedAppUsage
+        private final String mHostname;
+        private final int mNetId;
+
+        AddressCacheKey(String hostname, int netId) {
+            mHostname = hostname;
+            mNetId = netId;
+        }
+
+        @Override public boolean equals(Object o) {
+            if (this == o) {
+                return true;
+            }
+            if (!(o instanceof AddressCacheKey)) {
+                return false;
+            }
+            AddressCacheKey lhs = (AddressCacheKey) o;
+            return mHostname.equals(lhs.mHostname) && mNetId == lhs.mNetId;
+        }
+
+        @Override public int hashCode() {
+            int result = 17;
+            result = 31 * result + mNetId;
+            result = 31 * result + mHostname.hashCode();
+            return result;
+        }
+    }
+
+    static class AddressCacheEntry {
+        // Either an InetAddress[] for a positive entry,
+        // or a String detail message for a negative entry.
+        @UnsupportedAppUsage
+        final Object value;
+
+        /**
+         * The absolute expiry time in nanoseconds. Nanoseconds from System.nanoTime is ideal
+         * because -- unlike System.currentTimeMillis -- it can never go backwards.
+         *
+         * We don't need to worry about overflow with a TTL_NANOS of 2s.
+         */
+        @UnsupportedAppUsage
+        final long expiryNanos;
+
+        @UnsupportedAppUsage
+        AddressCacheEntry(Object value) {
+            this.value = value;
+            this.expiryNanos = System.nanoTime() + TTL_NANOS;
+        }
+    }
+
+    /**
+     * Removes all entries from the cache.
+     */
+    public void clear() {
+        cache.evictAll();
+    }
+
+    /**
+     * Returns the cached InetAddress[] for 'hostname' on network 'netId'. Returns null
+     * if nothing is known about 'hostname'. Returns a String suitable for use as an
+     * UnknownHostException detail message if 'hostname' is known not to exist.
+     */
+    public Object get(String hostname, int netId) {
+        AddressCacheEntry entry = cache.get(new AddressCacheKey(hostname, netId));
+        // Do we have a valid cache entry?
+        if (entry != null && entry.expiryNanos >= System.nanoTime()) {
+            return entry.value;
+        }
+        // Either we didn't find anything, or it had expired.
+        // No need to remove expired entries: the caller will provide a replacement shortly.
+        return null;
+    }
+
+    /**
+     * Associates the given 'addresses' with 'hostname'. The association will expire after a
+     * certain length of time.
+     */
+    public void put(String hostname, int netId, InetAddress[] addresses) {
+        cache.put(new AddressCacheKey(hostname, netId), new AddressCacheEntry(addresses));
+    }
+
+    /**
+     * Records that 'hostname' is known not to have any associated addresses. (I.e. insert a
+     * negative cache entry.)
+     */
+    public void putUnknownHost(String hostname, int netId, String detailMessage) {
+        cache.put(new AddressCacheKey(hostname, netId), new AddressCacheEntry(detailMessage));
+    }
+}
diff --git a/java/net/Authenticator.java b/java/net/Authenticator.java
new file mode 100644
index 0000000..c88a600
--- /dev/null
+++ b/java/net/Authenticator.java
@@ -0,0 +1,425 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * The class Authenticator represents an object that knows how to obtain
+ * authentication for a network connection.  Usually, it will do this
+ * by prompting the user for information.
+ * <p>
+ * Applications use this class by overriding {@link
+ * #getPasswordAuthentication()} in a sub-class. This method will
+ * typically use the various getXXX() accessor methods to get information
+ * about the entity requesting authentication. It must then acquire a
+ * username and password either by interacting with the user or through
+ * some other non-interactive means. The credentials are then returned
+ * as a {@link PasswordAuthentication} return value.
+ * <p>
+ * An instance of this concrete sub-class is then registered
+ * with the system by calling {@link #setDefault(Authenticator)}.
+ * When authentication is required, the system will invoke one of the
+ * requestPasswordAuthentication() methods which in turn will call the
+ * getPasswordAuthentication() method of the registered object.
+ * <p>
+ * All methods that request authentication have a default implementation
+ * that fails.
+ *
+ * @see java.net.Authenticator#setDefault(java.net.Authenticator)
+ * @see java.net.Authenticator#getPasswordAuthentication()
+ *
+ * @author  Bill Foote
+ * @since   1.2
+ */
+
+// There are no abstract methods, but to be useful the user must
+// subclass.
+public abstract
+class Authenticator {
+
+    // The system-wide authenticator object.  See setDefault().
+    private static Authenticator theAuthenticator;
+
+    private String requestingHost;
+    private InetAddress requestingSite;
+    private int requestingPort;
+    private String requestingProtocol;
+    private String requestingPrompt;
+    private String requestingScheme;
+    private URL requestingURL;
+    private RequestorType requestingAuthType;
+
+    /**
+     * The type of the entity requesting authentication.
+     *
+     * @since 1.5
+     */
+    public enum RequestorType {
+        /**
+         * Entity requesting authentication is a HTTP proxy server.
+         */
+        PROXY,
+        /**
+         * Entity requesting authentication is a HTTP origin server.
+         */
+        SERVER
+    }
+
+    private void reset() {
+        requestingHost = null;
+        requestingSite = null;
+        requestingPort = -1;
+        requestingProtocol = null;
+        requestingPrompt = null;
+        requestingScheme = null;
+        requestingURL = null;
+        requestingAuthType = RequestorType.SERVER;
+    }
+
+
+    /**
+     * Sets the authenticator that will be used by the networking code
+     * when a proxy or an HTTP server asks for authentication.
+     * <p>
+     * First, if there is a security manager, its {@code checkPermission}
+     * method is called with a
+     * {@code NetPermission("setDefaultAuthenticator")} permission.
+     * This may result in a java.lang.SecurityException.
+     *
+     * @param   a       The authenticator to be set. If a is {@code null} then
+     *                  any previously set authenticator is removed.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        setting the default authenticator.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.net.NetPermission
+     */
+    public synchronized static void setDefault(Authenticator a) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            NetPermission setDefaultPermission
+                = new NetPermission("setDefaultAuthenticator");
+            sm.checkPermission(setDefaultPermission);
+        }
+
+        theAuthenticator = a;
+    }
+
+    /**
+     * Ask the authenticator that has been registered with the system
+     * for a password.
+     * <p>
+     * First, if there is a security manager, its {@code checkPermission}
+     * method is called with a
+     * {@code NetPermission("requestPasswordAuthentication")} permission.
+     * This may result in a java.lang.SecurityException.
+     *
+     * @param addr The InetAddress of the site requesting authorization,
+     *             or null if not known.
+     * @param port the port for the requested connection
+     * @param protocol The protocol that's requesting the connection
+     *          ({@link java.net.Authenticator#getRequestingProtocol()})
+     * @param prompt A prompt string for the user
+     * @param scheme The authentication scheme
+     *
+     * @return The username/password, or null if one can't be gotten.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        the password authentication request.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.net.NetPermission
+     */
+    public static PasswordAuthentication requestPasswordAuthentication(
+                                            InetAddress addr,
+                                            int port,
+                                            String protocol,
+                                            String prompt,
+                                            String scheme) {
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            NetPermission requestPermission
+                = new NetPermission("requestPasswordAuthentication");
+            sm.checkPermission(requestPermission);
+        }
+
+        Authenticator a = theAuthenticator;
+        if (a == null) {
+            return null;
+        } else {
+            synchronized(a) {
+                a.reset();
+                a.requestingSite = addr;
+                a.requestingPort = port;
+                a.requestingProtocol = protocol;
+                a.requestingPrompt = prompt;
+                a.requestingScheme = scheme;
+                return a.getPasswordAuthentication();
+            }
+        }
+    }
+
+    /**
+     * Ask the authenticator that has been registered with the system
+     * for a password. This is the preferred method for requesting a password
+     * because the hostname can be provided in cases where the InetAddress
+     * is not available.
+     * <p>
+     * First, if there is a security manager, its {@code checkPermission}
+     * method is called with a
+     * {@code NetPermission("requestPasswordAuthentication")} permission.
+     * This may result in a java.lang.SecurityException.
+     *
+     * @param host The hostname of the site requesting authentication.
+     * @param addr The InetAddress of the site requesting authentication,
+     *             or null if not known.
+     * @param port the port for the requested connection.
+     * @param protocol The protocol that's requesting the connection
+     *          ({@link java.net.Authenticator#getRequestingProtocol()})
+     * @param prompt A prompt string for the user which identifies the authentication realm.
+     * @param scheme The authentication scheme
+     *
+     * @return The username/password, or null if one can't be gotten.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        the password authentication request.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.net.NetPermission
+     * @since 1.4
+     */
+    public static PasswordAuthentication requestPasswordAuthentication(
+                                            String host,
+                                            InetAddress addr,
+                                            int port,
+                                            String protocol,
+                                            String prompt,
+                                            String scheme) {
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            NetPermission requestPermission
+                = new NetPermission("requestPasswordAuthentication");
+            sm.checkPermission(requestPermission);
+        }
+
+        Authenticator a = theAuthenticator;
+        if (a == null) {
+            return null;
+        } else {
+            synchronized(a) {
+                a.reset();
+                a.requestingHost = host;
+                a.requestingSite = addr;
+                a.requestingPort = port;
+                a.requestingProtocol = protocol;
+                a.requestingPrompt = prompt;
+                a.requestingScheme = scheme;
+                return a.getPasswordAuthentication();
+            }
+        }
+    }
+
+    /**
+     * Ask the authenticator that has been registered with the system
+     * for a password.
+     * <p>
+     * First, if there is a security manager, its {@code checkPermission}
+     * method is called with a
+     * {@code NetPermission("requestPasswordAuthentication")} permission.
+     * This may result in a java.lang.SecurityException.
+     *
+     * @param host The hostname of the site requesting authentication.
+     * @param addr The InetAddress of the site requesting authorization,
+     *             or null if not known.
+     * @param port the port for the requested connection
+     * @param protocol The protocol that's requesting the connection
+     *          ({@link java.net.Authenticator#getRequestingProtocol()})
+     * @param prompt A prompt string for the user
+     * @param scheme The authentication scheme
+     * @param url The requesting URL that caused the authentication
+     * @param reqType The type (server or proxy) of the entity requesting
+     *              authentication.
+     *
+     * @return The username/password, or null if one can't be gotten.
+     *
+     * @throws SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        the password authentication request.
+     *
+     * @see SecurityManager#checkPermission
+     * @see java.net.NetPermission
+     *
+     * @since 1.5
+     */
+    public static PasswordAuthentication requestPasswordAuthentication(
+                                    String host,
+                                    InetAddress addr,
+                                    int port,
+                                    String protocol,
+                                    String prompt,
+                                    String scheme,
+                                    URL url,
+                                    RequestorType reqType) {
+
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            NetPermission requestPermission
+                = new NetPermission("requestPasswordAuthentication");
+            sm.checkPermission(requestPermission);
+        }
+
+        Authenticator a = theAuthenticator;
+        if (a == null) {
+            return null;
+        } else {
+            synchronized(a) {
+                a.reset();
+                a.requestingHost = host;
+                a.requestingSite = addr;
+                a.requestingPort = port;
+                a.requestingProtocol = protocol;
+                a.requestingPrompt = prompt;
+                a.requestingScheme = scheme;
+                a.requestingURL = url;
+                a.requestingAuthType = reqType;
+                return a.getPasswordAuthentication();
+            }
+        }
+    }
+
+    /**
+     * Gets the {@code hostname} of the
+     * site or proxy requesting authentication, or {@code null}
+     * if not available.
+     *
+     * @return the hostname of the connection requiring authentication, or null
+     *          if it's not available.
+     * @since 1.4
+     */
+    protected final String getRequestingHost() {
+        return requestingHost;
+    }
+
+    /**
+     * Gets the {@code InetAddress} of the
+     * site requesting authorization, or {@code null}
+     * if not available.
+     *
+     * @return the InetAddress of the site requesting authorization, or null
+     *          if it's not available.
+     */
+    protected final InetAddress getRequestingSite() {
+        return requestingSite;
+    }
+
+    /**
+     * Gets the port number for the requested connection.
+     * @return an {@code int} indicating the
+     * port for the requested connection.
+     */
+    protected final int getRequestingPort() {
+        return requestingPort;
+    }
+
+    /**
+     * Give the protocol that's requesting the connection.  Often this
+     * will be based on a URL, but in a future JDK it could be, for
+     * example, "SOCKS" for a password-protected SOCKS5 firewall.
+     *
+     * @return the protocol, optionally followed by "/version", where
+     *          version is a version number.
+     *
+     * @see java.net.URL#getProtocol()
+     */
+    protected final String getRequestingProtocol() {
+        return requestingProtocol;
+    }
+
+    /**
+     * Gets the prompt string given by the requestor.
+     *
+     * @return the prompt string given by the requestor (realm for
+     *          http requests)
+     */
+    protected final String getRequestingPrompt() {
+        return requestingPrompt;
+    }
+
+    /**
+     * Gets the scheme of the requestor (the HTTP scheme
+     * for an HTTP firewall, for example).
+     *
+     * @return the scheme of the requestor
+     *
+     */
+    protected final String getRequestingScheme() {
+        return requestingScheme;
+    }
+
+    /**
+     * Called when password authorization is needed.  Subclasses should
+     * override the default implementation, which returns null.
+     * @return The PasswordAuthentication collected from the
+     *          user, or null if none is provided.
+     */
+    protected PasswordAuthentication getPasswordAuthentication() {
+        return null;
+    }
+
+    /**
+     * Returns the URL that resulted in this
+     * request for authentication.
+     *
+     * @since 1.5
+     *
+     * @return the requesting URL
+     *
+     */
+    protected URL getRequestingURL () {
+        return requestingURL;
+    }
+
+    /**
+     * Returns whether the requestor is a Proxy or a Server.
+     *
+     * @since 1.5
+     *
+     * @return the authentication type of the requestor
+     *
+     */
+    protected RequestorType getRequestorType () {
+        return requestingAuthType;
+    }
+}
diff --git a/java/net/BindException.java b/java/net/BindException.java
new file mode 100644
index 0000000..9c2bb48
--- /dev/null
+++ b/java/net/BindException.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Signals that an error occurred while attempting to bind a
+ * socket to a local address and port.  Typically, the port is
+ * in use, or the requested local address could not be assigned.
+ *
+ * @since   JDK1.1
+ */
+
+public class BindException extends SocketException {
+    private static final long serialVersionUID = -5945005768251722951L;
+
+    /**
+     * Constructs a new BindException with the specified detail
+     * message as to why the bind error occurred.
+     * A detail message is a String that gives a specific
+     * description of this error.
+     * @param msg the detail message
+     */
+    public BindException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Construct a new BindException with no detailed message.
+     */
+    public BindException() {}
+
+    // Android-added: Constructor called by IoBridge
+    /** @hide */
+    public BindException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}
diff --git a/java/net/CacheRequest.java b/java/net/CacheRequest.java
new file mode 100644
index 0000000..a6fbbc3
--- /dev/null
+++ b/java/net/CacheRequest.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.OutputStream;
+import java.io.IOException;
+
+/**
+ * Represents channels for storing resources in the
+ * ResponseCache. Instances of such a class provide an
+ * OutputStream object which is called by protocol handlers to
+ * store the resource data into the cache, and also an abort() method
+ * which allows a cache store operation to be interrupted and
+ * abandoned. If an IOException is encountered while reading the
+ * response or writing to the cache, the current cache store operation
+ * will be aborted.
+ *
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class CacheRequest {
+
+    /**
+     * Returns an OutputStream to which the response body can be
+     * written.
+     *
+     * @return an OutputStream to which the response body can
+     *         be written
+     * @throws IOException if an I/O error occurs while
+     *         writing the response body
+     */
+    public abstract OutputStream getBody() throws IOException;
+
+    /**
+     * Aborts the attempt to cache the response. If an IOException is
+     * encountered while reading the response or writing to the cache,
+     * the current cache store operation will be abandoned.
+     */
+    public abstract void abort();
+}
diff --git a/java/net/CacheResponse.java b/java/net/CacheResponse.java
new file mode 100644
index 0000000..272b3d9
--- /dev/null
+++ b/java/net/CacheResponse.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.InputStream;
+import java.util.Map;
+import java.util.List;
+import java.io.IOException;
+
+/**
+ * Represent channels for retrieving resources from the
+ * ResponseCache. Instances of such a class provide an
+ * InputStream that returns the entity body, and also a
+ * getHeaders() method which returns the associated response headers.
+ *
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class CacheResponse {
+
+    /**
+     * Returns the response headers as a Map.
+     *
+     * @return An immutable Map from response header field names to
+     *         lists of field values. The status line has null as its
+     *         field name.
+     * @throws IOException if an I/O error occurs
+     *            while getting the response headers
+     */
+    public abstract Map<String, List<String>> getHeaders() throws IOException;
+
+    /**
+     * Returns the response body as an InputStream.
+     *
+     * @return an InputStream from which the response body can
+     *         be accessed
+     * @throws IOException if an I/O error occurs while
+     *         getting the response body
+     */
+    public abstract InputStream getBody() throws IOException;
+}
diff --git a/java/net/ConnectException.java b/java/net/ConnectException.java
new file mode 100644
index 0000000..ff58643
--- /dev/null
+++ b/java/net/ConnectException.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Signals that an error occurred while attempting to connect a
+ * socket to a remote address and port.  Typically, the connection
+ * was refused remotely (e.g., no process is listening on the
+ * remote address/port).
+ *
+ * @since   JDK1.1
+ */
+public class ConnectException extends SocketException {
+    private static final long serialVersionUID = 3831404271622369215L;
+
+    /**
+     * Constructs a new ConnectException with the specified detail
+     * message as to why the connect error occurred.
+     * A detail message is a String that gives a specific
+     * description of this error.
+     * @param msg the detail message
+     */
+    public ConnectException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Construct a new ConnectException with no detailed message.
+     */
+    public ConnectException() {}
+
+    // Android-added: Constructor called by IoBridge
+    /** @hide */
+    public ConnectException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}
diff --git a/java/net/ContentHandler.java b/java/net/ContentHandler.java
new file mode 100644
index 0000000..c658585
--- /dev/null
+++ b/java/net/ContentHandler.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * The abstract class {@code ContentHandler} is the superclass
+ * of all classes that read an {@code Object} from a
+ * {@code URLConnection}.
+ * <p>
+ * An application does not generally call the
+ * {@code getContent} method in this class directly. Instead, an
+ * application calls the {@code getContent} method in class
+ * {@code URL} or in {@code URLConnection}.
+ * The application's content handler factory (an instance of a class that
+ * implements the interface {@code ContentHandlerFactory} set
+ * up by a call to {@code setContentHandler}) is
+ * called with a {@code String} giving the MIME type of the
+ * object being received on the socket. The factory returns an
+ * instance of a subclass of {@code ContentHandler}, and its
+ * {@code getContent} method is called to create the object.
+ * <p>
+ * If no content handler could be found, URLConnection will
+ * look for a content handler in a user-defineable set of places.
+ * By default it looks in sun.net.www.content, but users can define a
+ * vertical-bar delimited set of class prefixes to search through in
+ * addition by defining the java.content.handler.pkgs property.
+ * The class name must be of the form:
+ * <pre>
+ *     {package-prefix}.{major}.{minor}
+ * e.g.
+ *     YoyoDyne.experimental.text.plain
+ * </pre>
+ * If the loading of the content handler class would be performed by
+ * a classloader that is outside of the delegation chain of the caller,
+ * the JVM will need the RuntimePermission "getClassLoader".
+ *
+ * @author  James Gosling
+ * @see     java.net.ContentHandler#getContent(java.net.URLConnection)
+ * @see     java.net.ContentHandlerFactory
+ * @see     java.net.URL#getContent()
+ * @see     java.net.URLConnection
+ * @see     java.net.URLConnection#getContent()
+ * @see     java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
+ * @since   JDK1.0
+ */
+abstract public class ContentHandler {
+    /**
+     * Given a URL connect stream positioned at the beginning of the
+     * representation of an object, this method reads that stream and
+     * creates an object from it.
+     *
+     * @param      urlc   a URL connection.
+     * @return     the object read by the {@code ContentHandler}.
+     * @exception  IOException  if an I/O error occurs while reading the object.
+     */
+    abstract public Object getContent(URLConnection urlc) throws IOException;
+
+    /**
+     * Given a URL connect stream positioned at the beginning of the
+     * representation of an object, this method reads that stream and
+     * creates an object that matches one of the types specified.
+     *
+     * The default implementation of this method should call getContent()
+     * and screen the return type for a match of the suggested types.
+     *
+     * @param      urlc   a URL connection.
+     * @param      classes      an array of types requested
+     * @return     the object read by the {@code ContentHandler} that is
+     *                 the first match of the suggested types.
+     *                 null if none of the requested  are supported.
+     * @exception  IOException  if an I/O error occurs while reading the object.
+     * @since 1.3
+     */
+    @SuppressWarnings("rawtypes")
+    public Object getContent(URLConnection urlc, Class[] classes) throws IOException {
+        Object obj = getContent(urlc);
+
+        for (int i = 0; i < classes.length; i++) {
+          if (classes[i].isInstance(obj)) {
+                return obj;
+          }
+        }
+        return null;
+    }
+
+}
diff --git a/java/net/ContentHandlerFactory.java b/java/net/ContentHandlerFactory.java
new file mode 100644
index 0000000..64112e3
--- /dev/null
+++ b/java/net/ContentHandlerFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This interface defines a factory for content handlers. An
+ * implementation of this interface should map a MIME type into an
+ * instance of {@code ContentHandler}.
+ * <p>
+ * This interface is used by the {@code URLStreamHandler} class
+ * to create a {@code ContentHandler} for a MIME type.
+ *
+ * @author  James Gosling
+ * @see     java.net.ContentHandler
+ * @see     java.net.URLStreamHandler
+ * @since   JDK1.0
+ */
+public interface ContentHandlerFactory {
+    /**
+     * Creates a new {@code ContentHandler} to read an object from
+     * a {@code URLStreamHandler}.
+     *
+     * @param   mimetype   the MIME type for which a content handler is desired.
+
+     * @return  a new {@code ContentHandler} to read an object from a
+     *          {@code URLStreamHandler}.
+     * @see     java.net.ContentHandler
+     * @see     java.net.URLStreamHandler
+     */
+    ContentHandler createContentHandler(String mimetype);
+}
diff --git a/java/net/CookieHandler.java b/java/net/CookieHandler.java
new file mode 100644
index 0000000..ef91d00
--- /dev/null
+++ b/java/net/CookieHandler.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.util.Map;
+import java.util.List;
+import java.io.IOException;
+import sun.security.util.SecurityConstants;
+
+/**
+ * A CookieHandler object provides a callback mechanism to hook up a
+ * HTTP state management policy implementation into the HTTP protocol
+ * handler. The HTTP state management mechanism specifies a way to
+ * create a stateful session with HTTP requests and responses.
+ *
+ * <p>A system-wide CookieHandler that to used by the HTTP protocol
+ * handler can be registered by doing a
+ * CookieHandler.setDefault(CookieHandler). The currently registered
+ * CookieHandler can be retrieved by calling
+ * CookieHandler.getDefault().
+ *
+ * For more information on HTTP state management, see <a
+ * href="http://www.ietf.org/rfc/rfc2965.txt"><i>RFC&nbsp;2965: HTTP
+ * State Management Mechanism</i></a>
+ *
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class CookieHandler {
+    /**
+     * The system-wide cookie handler that will apply cookies to the
+     * request headers and manage cookies from the response headers.
+     *
+     * @see setDefault(CookieHandler)
+     * @see getDefault()
+     */
+    private static CookieHandler cookieHandler;
+
+    /**
+     * Gets the system-wide cookie handler.
+     *
+     * @return the system-wide cookie handler; A null return means
+     *        there is no system-wide cookie handler currently set.
+     * @throws SecurityException
+     *       If a security manager has been installed and it denies
+     * {@link NetPermission}{@code ("getCookieHandler")}
+     * @see #setDefault(CookieHandler)
+     */
+    public synchronized static CookieHandler getDefault() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION);
+        }
+        return cookieHandler;
+    }
+
+    /**
+     * Sets (or unsets) the system-wide cookie handler.
+     *
+     * Note: non-standard http protocol handlers may ignore this setting.
+     *
+     * @param cHandler The HTTP cookie handler, or
+     *       {@code null} to unset.
+     * @throws SecurityException
+     *       If a security manager has been installed and it denies
+     * {@link NetPermission}{@code ("setCookieHandler")}
+     * @see #getDefault()
+     */
+    public synchronized static void setDefault(CookieHandler cHandler) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION);
+        }
+        cookieHandler = cHandler;
+    }
+
+    /**
+     * Gets all the applicable cookies from a cookie cache for the
+     * specified uri in the request header.
+     *
+     * <P>The {@code URI} passed as an argument specifies the intended use for
+     * the cookies. In particular the scheme should reflect whether the cookies
+     * will be sent over http, https or used in another context like javascript.
+     * The host part should reflect either the destination of the cookies or
+     * their origin in the case of javascript.</P>
+     * <P>It is up to the implementation to take into account the {@code URI} and
+     * the cookies attributes and security settings to determine which ones
+     * should be returned.</P>
+     *
+     * <P>HTTP protocol implementers should make sure that this method is
+     * called after all request headers related to choosing cookies
+     * are added, and before the request is sent.</P>
+     *
+     * @param uri a {@code URI} representing the intended use for the
+     *            cookies
+     * @param requestHeaders - a Map from request header
+     *            field names to lists of field values representing
+     *            the current request headers
+     * @return an immutable map from state management headers, with
+     *            field names "Cookie" or "Cookie2" to a list of
+     *            cookies containing state information
+     *
+     * @throws IOException if an I/O error occurs
+     * @throws IllegalArgumentException if either argument is null
+     * @see #put(URI, Map)
+     */
+    public abstract Map<String, List<String>>
+        get(URI uri, Map<String, List<String>> requestHeaders)
+        throws IOException;
+
+    /**
+     * Sets all the applicable cookies, examples are response header
+     * fields that are named Set-Cookie2, present in the response
+     * headers into a cookie cache.
+     *
+     * @param uri a {@code URI} where the cookies come from
+     * @param responseHeaders an immutable map from field names to
+     *            lists of field values representing the response
+     *            header fields returned
+     * @throws  IOException if an I/O error occurs
+     * @throws  IllegalArgumentException if either argument is null
+     * @see #get(URI, Map)
+     */
+    public abstract void
+        put(URI uri, Map<String, List<String>> responseHeaders)
+        throws IOException;
+}
diff --git a/java/net/CookieManager.java b/java/net/CookieManager.java
new file mode 100644
index 0000000..dfd3b86
--- /dev/null
+++ b/java/net/CookieManager.java
@@ -0,0 +1,491 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.util.Map;
+import java.util.List;
+import java.util.Collections;
+import java.util.Comparator;
+import java.io.IOException;
+import sun.util.logging.PlatformLogger;
+
+/**
+ * CookieManager provides a concrete implementation of {@link CookieHandler},
+ * which separates the storage of cookies from the policy surrounding accepting
+ * and rejecting cookies. A CookieManager is initialized with a {@link CookieStore}
+ * which manages storage, and a {@link CookiePolicy} object, which makes
+ * policy decisions on cookie acceptance/rejection.
+ *
+ * <p> The HTTP cookie management in java.net package looks like:
+ * <blockquote>
+ * <pre>{@code
+ *                  use
+ * CookieHandler <------- HttpURLConnection
+ *       ^
+ *       | impl
+ *       |         use
+ * CookieManager -------> CookiePolicy
+ *             |   use
+ *             |--------> HttpCookie
+ *             |              ^
+ *             |              | use
+ *             |   use        |
+ *             |--------> CookieStore
+ *                            ^
+ *                            | impl
+ *                            |
+ *                  Internal in-memory implementation
+ * }</pre>
+ * <ul>
+ *   <li>
+ *     CookieHandler is at the core of cookie management. User can call
+ *     CookieHandler.setDefault to set a concrete CookieHanlder implementation
+ *     to be used.
+ *   </li>
+ *   <li>
+ *     CookiePolicy.shouldAccept will be called by CookieManager.put to see whether
+ *     or not one cookie should be accepted and put into cookie store. User can use
+ *     any of three pre-defined CookiePolicy, namely ACCEPT_ALL, ACCEPT_NONE and
+ *     ACCEPT_ORIGINAL_SERVER, or user can define his own CookiePolicy implementation
+ *     and tell CookieManager to use it.
+ *   </li>
+ *   <li>
+ *     CookieStore is the place where any accepted HTTP cookie is stored in.
+ *     If not specified when created, a CookieManager instance will use an internal
+ *     in-memory implementation. Or user can implements one and tell CookieManager
+ *     to use it.
+ *   </li>
+ *   <li>
+ *     Currently, only CookieStore.add(URI, HttpCookie) and CookieStore.get(URI)
+ *     are used by CookieManager. Others are for completeness and might be needed
+ *     by a more sophisticated CookieStore implementation, e.g. a NetscapeCookieSotre.
+ *   </li>
+ * </ul>
+ * </blockquote>
+ *
+ * <p>There're various ways user can hook up his own HTTP cookie management behavior, e.g.
+ * <blockquote>
+ * <ul>
+ *   <li>Use CookieHandler.setDefault to set a brand new {@link CookieHandler} implementation
+ *   <li>Let CookieManager be the default {@link CookieHandler} implementation,
+ *       but implement user's own {@link CookieStore} and {@link CookiePolicy}
+ *       and tell default CookieManager to use them:
+ *     <blockquote><pre>
+ *       // this should be done at the beginning of an HTTP session
+ *       CookieHandler.setDefault(new CookieManager(new MyCookieStore(), new MyCookiePolicy()));
+ *     </pre></blockquote>
+ *   <li>Let CookieManager be the default {@link CookieHandler} implementation, but
+ *       use customized {@link CookiePolicy}:
+ *     <blockquote><pre>
+ *       // this should be done at the beginning of an HTTP session
+ *       CookieHandler.setDefault(new CookieManager());
+ *       // this can be done at any point of an HTTP session
+ *       ((CookieManager)CookieHandler.getDefault()).setCookiePolicy(new MyCookiePolicy());
+ *     </pre></blockquote>
+ * </ul>
+ * </blockquote>
+ *
+ * <p>The implementation conforms to <a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>, section 3.3.
+ *
+ * @see CookiePolicy
+ * @author Edward Wang
+ * @since 1.6
+ */
+public class CookieManager extends CookieHandler
+{
+    /* ---------------- Fields -------------- */
+
+    private CookiePolicy policyCallback;
+
+
+    private CookieStore cookieJar = null;
+
+
+    /* ---------------- Ctors -------------- */
+
+    /**
+     * Create a new cookie manager.
+     *
+     * <p>This constructor will create new cookie manager with default
+     * cookie store and accept policy. The effect is same as
+     * {@code CookieManager(null, null)}.
+     */
+    public CookieManager() {
+        this(null, null);
+    }
+
+
+    /**
+     * Create a new cookie manager with specified cookie store and cookie policy.
+     *
+     * @param store     a {@code CookieStore} to be used by cookie manager.
+     *                  if {@code null}, cookie manager will use a default one,
+     *                  which is an in-memory CookieStore implementation.
+     * @param cookiePolicy      a {@code CookiePolicy} instance
+     *                          to be used by cookie manager as policy callback.
+     *                          if {@code null}, ACCEPT_ORIGINAL_SERVER will
+     *                          be used.
+     */
+    public CookieManager(CookieStore store,
+                         CookiePolicy cookiePolicy)
+    {
+        // use default cookie policy if not specify one
+        policyCallback = (cookiePolicy == null) ? CookiePolicy.ACCEPT_ORIGINAL_SERVER
+                                                : cookiePolicy;
+
+        // if not specify CookieStore to use, use default one
+        if (store == null) {
+            cookieJar = new InMemoryCookieStore();
+        } else {
+            cookieJar = store;
+        }
+    }
+
+
+    /* ---------------- Public operations -------------- */
+
+    /**
+     * To set the cookie policy of this cookie manager.
+     *
+     * <p> A instance of {@code CookieManager} will have
+     * cookie policy ACCEPT_ORIGINAL_SERVER by default. Users always
+     * can call this method to set another cookie policy.
+     *
+     * @param cookiePolicy      the cookie policy. Can be {@code null}, which
+     *                          has no effects on current cookie policy.
+     */
+    public void setCookiePolicy(CookiePolicy cookiePolicy) {
+        if (cookiePolicy != null) policyCallback = cookiePolicy;
+    }
+
+
+    /**
+     * To retrieve current cookie store.
+     *
+     * @return  the cookie store currently used by cookie manager.
+     */
+    public CookieStore getCookieStore() {
+        return cookieJar;
+    }
+
+
+    public Map<String, List<String>>
+        get(URI uri, Map<String, List<String>> requestHeaders)
+        throws IOException
+    {
+        // pre-condition check
+        if (uri == null || requestHeaders == null) {
+            throw new IllegalArgumentException("Argument is null");
+        }
+
+        Map<String, List<String>> cookieMap =
+                        new java.util.HashMap<String, List<String>>();
+        // if there's no default CookieStore, no way for us to get any cookie
+        if (cookieJar == null)
+            return Collections.unmodifiableMap(cookieMap);
+
+        boolean secureLink = "https".equalsIgnoreCase(uri.getScheme());
+        List<HttpCookie> cookies = new java.util.ArrayList<HttpCookie>();
+        // BEGIN Android-removed: The logic of converting null path is moved into pathMatches.
+        /*
+        String path = uri.getPath();
+        if (path == null || path.isEmpty()) {
+            path = "/";
+        }
+        */
+        // END Android-removed: The logic of converting null path is moved into pathMatches.
+        for (HttpCookie cookie : cookieJar.get(uri)) {
+            // apply path-matches rule (RFC 2965 sec. 3.3.4)
+            // and check for the possible "secure" tag (i.e. don't send
+            // 'secure' cookies over unsecure links)
+            if (pathMatches(uri, cookie) &&
+                    (secureLink || !cookie.getSecure())) {
+                // BEGIN Android-removed: App compat: b/25897688 InMemoryCookieStore ignores scheme.
+                /*
+                if (cookie.isHttpOnly()) {
+                    String s = uri.getScheme();
+                    if (!"http".equalsIgnoreCase(s) && !"https".equalsIgnoreCase(s)) {
+                        continue;
+                    }
+                }
+                */
+                // END Android-removed: App compat: b/25897688 InMemoryCookieStore ignores scheme.
+
+                // Let's check the authorize port list if it exists
+                String ports = cookie.getPortlist();
+                if (ports != null && !ports.isEmpty()) {
+                    int port = uri.getPort();
+                    if (port == -1) {
+                        port = "https".equals(uri.getScheme()) ? 443 : 80;
+                    }
+                    if (isInPortList(ports, port)) {
+                        cookies.add(cookie);
+                    }
+                } else {
+                    cookies.add(cookie);
+                }
+            }
+        }
+        // Android-added: b/25897688 A fix to return empty map if cookies list is empty
+        if (cookies.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        // apply sort rule (RFC 2965 sec. 3.3.4)
+        List<String> cookieHeader = sortByPath(cookies);
+
+        cookieMap.put("Cookie", cookieHeader);
+        return Collections.unmodifiableMap(cookieMap);
+    }
+
+    public void
+        put(URI uri, Map<String, List<String>> responseHeaders)
+        throws IOException
+    {
+        // pre-condition check
+        if (uri == null || responseHeaders == null) {
+            throw new IllegalArgumentException("Argument is null");
+        }
+
+
+        // if there's no default CookieStore, no need to remember any cookie
+        if (cookieJar == null)
+            return;
+
+    PlatformLogger logger = PlatformLogger.getLogger("java.net.CookieManager");
+        for (String headerKey : responseHeaders.keySet()) {
+            // RFC 2965 3.2.2, key must be 'Set-Cookie2'
+            // we also accept 'Set-Cookie' here for backward compatibility
+            if (headerKey == null
+                || !(headerKey.equalsIgnoreCase("Set-Cookie2")
+                     || headerKey.equalsIgnoreCase("Set-Cookie")
+                    )
+                )
+            {
+                continue;
+            }
+
+            for (String headerValue : responseHeaders.get(headerKey)) {
+                try {
+                    List<HttpCookie> cookies;
+                    try {
+                        cookies = HttpCookie.parse(headerValue);
+                    } catch (IllegalArgumentException e) {
+                        // Bogus header, make an empty list and log the error
+                        cookies = java.util.Collections.emptyList();
+                        if (logger.isLoggable(PlatformLogger.Level.SEVERE)) {
+                            logger.severe("Invalid cookie for " + uri + ": " + headerValue);
+                        }
+                    }
+                    for (HttpCookie cookie : cookies) {
+                        if (cookie.getPath() == null) {
+                            // If no path is specified, then by default
+                            // the path is the directory of the page/doc
+                            String path = uri.getPath();
+                            if (!path.endsWith("/")) {
+                                int i = path.lastIndexOf("/");
+                                if (i > 0) {
+                                    path = path.substring(0, i + 1);
+                                } else {
+                                    path = "/";
+                                }
+                            }
+                            cookie.setPath(path);
+                        // Android-added: b/25763487 A fix to verify cookie URI before removal
+                        } else {
+                            // Validate existing path
+                            if (!pathMatches(uri, cookie)) {
+                                continue;
+                            }
+                        }
+
+                        // As per RFC 2965, section 3.3.1:
+                        // Domain  Defaults to the effective request-host.  (Note that because
+                        // there is no dot at the beginning of effective request-host,
+                        // the default Domain can only domain-match itself.)
+                        if (cookie.getDomain() == null) {
+                            String host = uri.getHost();
+                            if (host != null && !host.contains("."))
+                                host += ".local";
+                            cookie.setDomain(host);
+                        }
+                        String ports = cookie.getPortlist();
+                        if (ports != null) {
+                            int port = uri.getPort();
+                            if (port == -1) {
+                                port = "https".equals(uri.getScheme()) ? 443 : 80;
+                            }
+                            if (ports.isEmpty()) {
+                                // Empty port list means this should be restricted
+                                // to the incoming URI port
+                                cookie.setPortlist("" + port );
+                                if (shouldAcceptInternal(uri, cookie)) {
+                                    cookieJar.add(uri, cookie);
+                                }
+                            } else {
+                                // Only store cookies with a port list
+                                // IF the URI port is in that list, as per
+                                // RFC 2965 section 3.3.2
+                                if (isInPortList(ports, port) &&
+                                        shouldAcceptInternal(uri, cookie)) {
+                                    cookieJar.add(uri, cookie);
+                                }
+                            }
+                        } else {
+                            if (shouldAcceptInternal(uri, cookie)) {
+                                cookieJar.add(uri, cookie);
+                            }
+                        }
+                    }
+                } catch (IllegalArgumentException e) {
+                    // invalid set-cookie header string
+                    // no-op
+                }
+            }
+        }
+    }
+
+
+    /* ---------------- Private operations -------------- */
+
+    // to determine whether or not accept this cookie
+    private boolean shouldAcceptInternal(URI uri, HttpCookie cookie) {
+        try {
+            return policyCallback.shouldAccept(uri, cookie);
+        } catch (Exception ignored) { // pretect against malicious callback
+            return false;
+        }
+    }
+
+
+    static private boolean isInPortList(String lst, int port) {
+        int i = lst.indexOf(",");
+        int val = -1;
+        while (i > 0) {
+            try {
+                val = Integer.parseInt(lst.substring(0, i));
+                if (val == port) {
+                    return true;
+                }
+            } catch (NumberFormatException numberFormatException) {
+            }
+            lst = lst.substring(i+1);
+            i = lst.indexOf(",");
+        }
+        if (!lst.isEmpty()) {
+            try {
+                val = Integer.parseInt(lst);
+                if (val == port) {
+                    return true;
+                }
+            } catch (NumberFormatException numberFormatException) {
+            }
+        }
+        return false;
+    }
+
+    // Android-changed: b/25763487 Cookie path matching logic in OpenJDK was wrong
+    /**
+     * Return true iff. the path from {@code cookie} matches the path from {@code uri}.
+     */
+    private static boolean pathMatches(URI uri, HttpCookie cookie) {
+        return normalizePath(uri.getPath()).startsWith(normalizePath(cookie.getPath()));
+    }
+
+    private static String normalizePath(String path) {
+        if (path == null) {
+            path = "";
+        }
+
+        if (!path.endsWith("/")) {
+            path = path + "/";
+        }
+
+        return path;
+    }
+
+
+    /*
+     * sort cookies with respect to their path: those with more specific Path attributes
+     * precede those with less specific, as defined in RFC 2965 sec. 3.3.4
+     */
+    private List<String> sortByPath(List<HttpCookie> cookies) {
+        Collections.sort(cookies, new CookiePathComparator());
+
+        // BEGIN Android-changed: Netscape cookie spec and RFC 2965 have different format
+        // of Cookie header; RFC 2965 requires a leading $Version="1" string while Netscape does not
+        // The workaround here is to add a $Version="1" string in advance
+        final StringBuilder result = new StringBuilder();
+        int minVersion = 1;
+        for (HttpCookie cookie : cookies) {
+            if (cookie.getVersion() < minVersion) {
+                minVersion = cookie.getVersion();
+            }
+        }
+
+        if (minVersion == 1) {
+            result.append("$Version=\"1\"; ");
+        }
+
+        for (int i = 0; i < cookies.size(); ++i) {
+            if (i != 0) {
+                result.append("; ");
+            }
+
+            result.append(cookies.get(i).toString());
+        }
+
+        List<String> cookieHeader = new java.util.ArrayList<String>();
+        cookieHeader.add(result.toString());
+        // END Android-changed: Netscape cookie spec and RFC 2965 have different format
+        return cookieHeader;
+    }
+
+
+    static class CookiePathComparator implements Comparator<HttpCookie> {
+        public int compare(HttpCookie c1, HttpCookie c2) {
+            if (c1 == c2) return 0;
+            if (c1 == null) return -1;
+            if (c2 == null) return 1;
+
+            // path rule only applies to the cookies with same name
+            if (!c1.getName().equals(c2.getName())) return 0;
+
+            // Android-changed: normalize before comparison
+            final String c1Path = normalizePath(c1.getPath());
+            final String c2Path = normalizePath(c2.getPath());
+
+            // those with more specific Path attributes precede those with less specific
+            if (c1Path.startsWith(c2Path))
+                return -1;
+            else if (c2Path.startsWith(c1Path))
+                return 1;
+            else
+                return 0;
+        }
+    }
+}
diff --git a/java/net/CookiePolicy.java b/java/net/CookiePolicy.java
new file mode 100644
index 0000000..8094835
--- /dev/null
+++ b/java/net/CookiePolicy.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * CookiePolicy implementations decide which cookies should be accepted
+ * and which should be rejected. Three pre-defined policy implementations
+ * are provided, namely ACCEPT_ALL, ACCEPT_NONE and ACCEPT_ORIGINAL_SERVER.
+ *
+ * <p>See RFC 2965 sec. 3.3 and 7 for more detail.
+ *
+ * @author Edward Wang
+ * @since 1.6
+ */
+public interface CookiePolicy {
+    /**
+     * One pre-defined policy which accepts all cookies.
+     */
+    public static final CookiePolicy ACCEPT_ALL = new CookiePolicy(){
+        public boolean shouldAccept(URI uri, HttpCookie cookie) {
+            return true;
+        }
+    };
+
+    /**
+     * One pre-defined policy which accepts no cookies.
+     */
+    public static final CookiePolicy ACCEPT_NONE = new CookiePolicy(){
+        public boolean shouldAccept(URI uri, HttpCookie cookie) {
+            return false;
+        }
+    };
+
+    /**
+     * One pre-defined policy which only accepts cookies from original server.
+     */
+    public static final CookiePolicy ACCEPT_ORIGINAL_SERVER  = new CookiePolicy(){
+        public boolean shouldAccept(URI uri, HttpCookie cookie) {
+            if (uri == null || cookie == null)
+                return false;
+            return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost());
+        }
+    };
+
+
+    /**
+     * Will be called to see whether or not this cookie should be accepted.
+     *
+     * @param uri       the URI to consult accept policy with
+     * @param cookie    the HttpCookie object in question
+     * @return          {@code true} if this cookie should be accepted;
+     *                  otherwise, {@code false}
+     */
+    public boolean shouldAccept(URI uri, HttpCookie cookie);
+}
diff --git a/java/net/CookieStore.java b/java/net/CookieStore.java
new file mode 100644
index 0000000..105cc66
--- /dev/null
+++ b/java/net/CookieStore.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A CookieStore object represents a storage for cookie. Can store and retrieve
+ * cookies.
+ *
+ * <p>{@link CookieManager} will call {@code CookieStore.add} to save cookies
+ * for every incoming HTTP response, and call {@code CookieStore.get} to
+ * retrieve cookie for every outgoing HTTP request. A CookieStore
+ * is responsible for removing HttpCookie instances which have expired.
+ *
+ * @author Edward Wang
+ * @since 1.6
+ */
+public interface CookieStore {
+    /**
+     * Adds one HTTP cookie to the store. This is called for every
+     * incoming HTTP response.
+     *
+     * <p>A cookie to store may or may not be associated with an URI. If it
+     * is not associated with an URI, the cookie's domain and path attribute
+     * will indicate where it comes from. If it is associated with an URI and
+     * its domain and path attribute are not specified, given URI will indicate
+     * where this cookie comes from.
+     *
+     * <p>If a cookie corresponding to the given URI already exists,
+     * then it is replaced with the new one.
+     *
+     * @param uri       the uri this cookie associated with.
+     *                  if {@code null}, this cookie will not be associated
+     *                  with an URI
+     * @param cookie    the cookie to store
+     *
+     * @throws NullPointerException if {@code cookie} is {@code null}
+     *
+     * @see #get
+     *
+     */
+    public void add(URI uri, HttpCookie cookie);
+
+
+    /**
+     * Retrieve cookies associated with given URI, or whose domain matches the
+     * given URI. Only cookies that have not expired are returned.
+     * This is called for every outgoing HTTP request.
+     *
+     * @return          an immutable list of HttpCookie,
+     *                  return empty list if no cookies match the given URI
+     *
+     * @param uri       the uri associated with the cookies to be returned
+     *
+     * @throws NullPointerException if {@code uri} is {@code null}
+     *
+     * @see #add
+     *
+     */
+    public List<HttpCookie> get(URI uri);
+
+
+    /**
+     * Get all not-expired cookies in cookie store.
+     *
+     * @return          an immutable list of http cookies;
+     *                  return empty list if there's no http cookie in store
+     */
+    public List<HttpCookie> getCookies();
+
+
+    /**
+     * Get all URIs which identify the cookies in this cookie store.
+     *
+     * @return          an immutable list of URIs;
+     *                  return empty list if no cookie in this cookie store
+     *                  is associated with an URI
+     */
+    public List<URI> getURIs();
+
+
+    /**
+     * Remove a cookie from store.
+     *
+     * @param uri       the uri this cookie associated with.
+     *                  if {@code null}, the cookie to be removed is not associated
+     *                  with an URI when added; if not {@code null}, the cookie
+     *                  to be removed is associated with the given URI when added.
+     * @param cookie    the cookie to remove
+     *
+     * @return          {@code true} if this store contained the specified cookie
+     *
+     * @throws NullPointerException if {@code cookie} is {@code null}
+     */
+    public boolean remove(URI uri, HttpCookie cookie);
+
+
+    /**
+     * Remove all cookies in this cookie store.
+     *
+     * @return          {@code true} if this store changed as a result of the call
+     */
+    public boolean removeAll();
+}
diff --git a/java/net/DatagramPacket.java b/java/net/DatagramPacket.java
new file mode 100644
index 0000000..c1bd692
--- /dev/null
+++ b/java/net/DatagramPacket.java
@@ -0,0 +1,415 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This class represents a datagram packet.
+ * <p>
+ * Datagram packets are used to implement a connectionless packet
+ * delivery service. Each message is routed from one machine to
+ * another based solely on information contained within that packet.
+ * Multiple packets sent from one machine to another might be routed
+ * differently, and might arrive in any order. Packet delivery is
+ * not guaranteed.
+ *
+ * @author  Pavani Diwanji
+ * @author  Benjamin Renaud
+ * @since   JDK1.0
+ */
+public final
+class DatagramPacket {
+
+    // BEGIN Android-removed: Android doesn't need to load native net library.
+    /**
+     * Perform class initialization
+     *
+    static {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("net");
+                    return null;
+                }
+            });
+        init();
+    }
+    */
+    // END Android-removed: Android doesn't need to load native net library.
+
+    /*
+     * The fields of this class are package-private since DatagramSocketImpl
+     * classes needs to access them.
+     */
+    byte[] buf;
+    int offset;
+    int length;
+    int bufLength;
+    InetAddress address;
+    int port;
+
+    /**
+     * Constructs a {@code DatagramPacket} for receiving packets of
+     * length {@code length}, specifying an offset into the buffer.
+     * <p>
+     * The {@code length} argument must be less than or equal to
+     * {@code buf.length}.
+     *
+     * @param   buf      buffer for holding the incoming datagram.
+     * @param   offset   the offset for the buffer
+     * @param   length   the number of bytes to read.
+     *
+     * @since 1.2
+     */
+    public DatagramPacket(byte buf[], int offset, int length) {
+        setData(buf, offset, length);
+        this.address = null;
+        this.port = -1;
+    }
+
+    /**
+     * Constructs a {@code DatagramPacket} for receiving packets of
+     * length {@code length}.
+     * <p>
+     * The {@code length} argument must be less than or equal to
+     * {@code buf.length}.
+     *
+     * @param   buf      buffer for holding the incoming datagram.
+     * @param   length   the number of bytes to read.
+     */
+    public DatagramPacket(byte buf[], int length) {
+        this (buf, 0, length);
+    }
+
+    /**
+     * Constructs a datagram packet for sending packets of length
+     * {@code length} with offset {@code ioffset}to the
+     * specified port number on the specified host. The
+     * {@code length} argument must be less than or equal to
+     * {@code buf.length}.
+     *
+     * @param   buf      the packet data.
+     * @param   offset   the packet data offset.
+     * @param   length   the packet data length.
+     * @param   address  the destination address.
+     * @param   port     the destination port number.
+     * @see java.net.InetAddress
+     *
+     * @since 1.2
+     */
+    public DatagramPacket(byte buf[], int offset, int length,
+                          InetAddress address, int port) {
+        setData(buf, offset, length);
+        setAddress(address);
+        setPort(port);
+    }
+
+    // Android-changed: Added Android-specific notes regarding the exception signature change.
+    /**
+     * Constructs a datagram packet for sending packets of length
+     * {@code length} with offset {@code ioffset}to the
+     * specified port number on the specified host. The
+     * {@code length} argument must be less than or equal to
+     * {@code buf.length}.
+     *
+     * <p>
+     * <em>Android note</em>: Up to and including API 25 this method declared that a SocketException
+     * can be thrown, although the exception is never thrown. Code compiled against a newer SDK does
+     * not need to catch the exception and will be binary compatible with older versions of Android.
+     *
+     * @param   buf      the packet data.
+     * @param   offset   the packet data offset.
+     * @param   length   the packet data length.
+     * @param   address  the destination socket address.
+     * @throws  IllegalArgumentException if address type is not supported
+     * @see java.net.InetAddress
+     *
+     * @since 1.4
+     */
+    public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
+        setData(buf, offset, length);
+        setSocketAddress(address);
+    }
+
+    // Android-changed: Added Android-specific notes regarding the exception signature change.
+    /**
+     * Constructs a datagram packet for sending packets of length
+     * {@code length} to the specified port number on the specified
+     * host. The {@code length} argument must be less than or equal
+     * to {@code buf.length}.
+     *
+     * <p>
+     * <em>Android note</em>: Up to and including API 25 this method declared that a SocketException
+     * can be thrown, although the exception is never thrown. Code compiled against a newer SDK does
+     * not need to catch the exception and will be binary compatible with older versions of Android.
+     *
+     * @param   buf      the packet data.
+     * @param   length   the packet length.
+     * @param   address  the destination address.
+     * @param   port     the destination port number.
+     * @see     java.net.InetAddress
+     */
+    public DatagramPacket(byte buf[], int length,
+                          InetAddress address, int port) {
+        this(buf, 0, length, address, port);
+    }
+
+    /**
+     * Constructs a datagram packet for sending packets of length
+     * {@code length} to the specified port number on the specified
+     * host. The {@code length} argument must be less than or equal
+     * to {@code buf.length}.
+     *
+     * @param   buf      the packet data.
+     * @param   length   the packet length.
+     * @param   address  the destination address.
+     * @throws  IllegalArgumentException if address type is not supported
+     * @since 1.4
+     * @see     java.net.InetAddress
+     */
+    public DatagramPacket(byte buf[], int length, SocketAddress address) {
+        this(buf, 0, length, address);
+    }
+
+    /**
+     * Returns the IP address of the machine to which this datagram is being
+     * sent or from which the datagram was received.
+     *
+     * @return  the IP address of the machine to which this datagram is being
+     *          sent or from which the datagram was received.
+     * @see     java.net.InetAddress
+     * @see #setAddress(java.net.InetAddress)
+     */
+    public synchronized InetAddress getAddress() {
+        return address;
+    }
+
+    /**
+     * Returns the port number on the remote host to which this datagram is
+     * being sent or from which the datagram was received.
+     *
+     * @return  the port number on the remote host to which this datagram is
+     *          being sent or from which the datagram was received.
+     * @see #setPort(int)
+     */
+    public synchronized int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns the data buffer. The data received or the data to be sent
+     * starts from the {@code offset} in the buffer,
+     * and runs for {@code length} long.
+     *
+     * @return  the buffer used to receive or  send data
+     * @see #setData(byte[], int, int)
+     */
+    public synchronized byte[] getData() {
+        return buf;
+    }
+
+    /**
+     * Returns the offset of the data to be sent or the offset of the
+     * data received.
+     *
+     * @return  the offset of the data to be sent or the offset of the
+     *          data received.
+     *
+     * @since 1.2
+     */
+    public synchronized int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Returns the length of the data to be sent or the length of the
+     * data received.
+     *
+     * @return  the length of the data to be sent or the length of the
+     *          data received.
+     * @see #setLength(int)
+     */
+    public synchronized int getLength() {
+        return length;
+    }
+
+    /**
+     * Set the data buffer for this packet. This sets the
+     * data, length and offset of the packet.
+     *
+     * @param buf the buffer to set for this packet
+     *
+     * @param offset the offset into the data
+     *
+     * @param length the length of the data
+     *       and/or the length of the buffer used to receive data
+     *
+     * @exception NullPointerException if the argument is null
+     *
+     * @see #getData
+     * @see #getOffset
+     * @see #getLength
+     *
+     * @since 1.2
+     */
+    public synchronized void setData(byte[] buf, int offset, int length) {
+        /* this will check to see if buf is null */
+        if (length < 0 || offset < 0 ||
+            (length + offset) < 0 ||
+            ((length + offset) > buf.length)) {
+            throw new IllegalArgumentException("illegal length or offset");
+        }
+        this.buf = buf;
+        this.length = length;
+        this.bufLength = length;
+        this.offset = offset;
+    }
+
+    /**
+     * Sets the IP address of the machine to which this datagram
+     * is being sent.
+     * @param iaddr the {@code InetAddress}
+     * @since   JDK1.1
+     * @see #getAddress()
+     */
+    public synchronized void setAddress(InetAddress iaddr) {
+        address = iaddr;
+    }
+
+    // BEGIN Android-changed
+    /**
+     * Sets 'length' without changing 'userSuppliedLength', after receiving a packet.
+     * @hide for IoBridge
+     */
+    public void setReceivedLength(int length) {
+        this.length = length;
+    }
+    // END Android-changed
+
+    /**
+     * Sets the port number on the remote host to which this datagram
+     * is being sent.
+     * @param iport the port number
+     * @since   JDK1.1
+     * @see #getPort()
+     */
+    public synchronized void setPort(int iport) {
+        if (iport < 0 || iport > 0xFFFF) {
+            throw new IllegalArgumentException("Port out of range:"+ iport);
+        }
+        port = iport;
+    }
+
+    /**
+     * Sets the SocketAddress (usually IP address + port number) of the remote
+     * host to which this datagram is being sent.
+     *
+     * @param address the {@code SocketAddress}
+     * @throws  IllegalArgumentException if address is null or is a
+     *          SocketAddress subclass not supported by this socket
+     *
+     * @since 1.4
+     * @see #getSocketAddress
+     */
+    public synchronized void setSocketAddress(SocketAddress address) {
+        if (address == null || !(address instanceof InetSocketAddress))
+            throw new IllegalArgumentException("unsupported address type");
+        InetSocketAddress addr = (InetSocketAddress) address;
+        if (addr.isUnresolved())
+            throw new IllegalArgumentException("unresolved address");
+        setAddress(addr.getAddress());
+        setPort(addr.getPort());
+    }
+
+    /**
+     * Gets the SocketAddress (usually IP address + port number) of the remote
+     * host that this packet is being sent to or is coming from.
+     *
+     * @return the {@code SocketAddress}
+     * @since 1.4
+     * @see #setSocketAddress
+     */
+    public synchronized SocketAddress getSocketAddress() {
+        return new InetSocketAddress(getAddress(), getPort());
+    }
+
+    /**
+     * Set the data buffer for this packet. With the offset of
+     * this DatagramPacket set to 0, and the length set to
+     * the length of {@code buf}.
+     *
+     * @param buf the buffer to set for this packet.
+     *
+     * @exception NullPointerException if the argument is null.
+     *
+     * @see #getLength
+     * @see #getData
+     *
+     * @since JDK1.1
+     */
+    public synchronized void setData(byte[] buf) {
+        if (buf == null) {
+            throw new NullPointerException("null packet buffer");
+        }
+        this.buf = buf;
+        this.offset = 0;
+        this.length = buf.length;
+        this.bufLength = buf.length;
+    }
+
+    /**
+     * Set the length for this packet. The length of the packet is
+     * the number of bytes from the packet's data buffer that will be
+     * sent, or the number of bytes of the packet's data buffer that
+     * will be used for receiving data. The length must be lesser or
+     * equal to the offset plus the length of the packet's buffer.
+     *
+     * @param length the length to set for this packet.
+     *
+     * @exception IllegalArgumentException if the length is negative
+     * of if the length is greater than the packet's data buffer
+     * length.
+     *
+     * @see #getLength
+     * @see #setData
+     *
+     * @since JDK1.1
+     */
+    public synchronized void setLength(int length) {
+        if ((length + offset) > buf.length || length < 0 ||
+            (length + offset) < 0) {
+            throw new IllegalArgumentException("illegal length");
+        }
+        this.length = length;
+        this.bufLength = this.length;
+    }
+
+    // Android-removed: JNI has been removed
+    // /**
+    //  * Perform class load-time initializations.
+    //  */
+    // private native static void init();
+}
diff --git a/java/net/DatagramSocket.annotated.java b/java/net/DatagramSocket.annotated.java
new file mode 100644
index 0000000..b462769
--- /dev/null
+++ b/java/net/DatagramSocket.annotated.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+import java.nio.channels.DatagramChannel;
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class DatagramSocket implements java.io.Closeable {
+
+public DatagramSocket() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+protected DatagramSocket(java.net.DatagramSocketImpl impl) { throw new RuntimeException("Stub!"); }
+
+public DatagramSocket(java.net.SocketAddress bindaddr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public DatagramSocket(int port) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public DatagramSocket(int port, java.net.InetAddress laddr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void bind(java.net.SocketAddress addr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.InetAddress address, int port) { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.SocketAddress addr) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void disconnect() { throw new RuntimeException("Stub!"); }
+
+public boolean isBound() { throw new RuntimeException("Stub!"); }
+
+public boolean isConnected() { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+public int getPort() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getRemoteSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getLocalSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public void send(java.net.DatagramPacket p) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public synchronized void receive(java.net.DatagramPacket p) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSoTimeout(int timeout) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSoTimeout() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSendBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSendBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getReceiveBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReuseAddress(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean getReuseAddress() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setBroadcast(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized boolean getBroadcast() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setTrafficClass(int tc) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getTrafficClass() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void close() { throw new RuntimeException("Stub!"); }
+
+public boolean isClosed() { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.DatagramChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setDatagramSocketImplFactory(java.net.DatagramSocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.io.FileDescriptor getFileDescriptor$() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/net/DatagramSocket.java b/java/net/DatagramSocket.java
new file mode 100644
index 0000000..3e3faf7
--- /dev/null
+++ b/java/net/DatagramSocket.java
@@ -0,0 +1,1358 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import static android.system.OsConstants.SOL_SOCKET;
+import static android.system.OsConstants.SO_BINDTODEVICE;
+
+import android.system.ErrnoException;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.channels.DatagramChannel;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import libcore.io.Libcore;
+
+/**
+ * This class represents a socket for sending and receiving datagram packets.
+ *
+ * <p>A datagram socket is the sending or receiving point for a packet
+ * delivery service. Each packet sent or received on a datagram socket
+ * is individually addressed and routed. Multiple packets sent from
+ * one machine to another may be routed differently, and may arrive in
+ * any order.
+ *
+ * <p> Where possible, a newly constructed {@code DatagramSocket} has the
+ * {@link SocketOptions#SO_BROADCAST SO_BROADCAST} socket option enabled so as
+ * to allow the transmission of broadcast datagrams. In order to receive
+ * broadcast packets a DatagramSocket should be bound to the wildcard address.
+ * In some implementations, broadcast packets may also be received when
+ * a DatagramSocket is bound to a more specific address.
+ * <p>
+ * Example:
+ * {@code
+ *              DatagramSocket s = new DatagramSocket(null);
+ *              s.bind(new InetSocketAddress(8888));
+ * }
+ * Which is equivalent to:
+ * {@code
+ *              DatagramSocket s = new DatagramSocket(8888);
+ * }
+ * Both cases will create a DatagramSocket able to receive broadcasts on
+ * UDP port 8888.
+ *
+ * @author  Pavani Diwanji
+ * @see     java.net.DatagramPacket
+ * @see     java.nio.channels.DatagramChannel
+ * @since JDK1.0
+ */
+public
+class DatagramSocket implements java.io.Closeable {
+    /**
+     * Various states of this socket.
+     */
+    private boolean created = false;
+    private boolean bound = false;
+    private boolean closed = false;
+    private Object closeLock = new Object();
+
+    /*
+     * The implementation of this DatagramSocket.
+     */
+    DatagramSocketImpl impl;
+
+    /**
+     * Are we using an older DatagramSocketImpl?
+     */
+    boolean oldImpl = false;
+
+    /**
+     * Set when a socket is ST_CONNECTED until we are certain
+     * that any packets which might have been received prior
+     * to calling connect() but not read by the application
+     * have been read. During this time we check the source
+     * address of all packets received to be sure they are from
+     * the connected destination. Other packets are read but
+     * silently dropped.
+     */
+    private boolean explicitFilter = false;
+    private int bytesLeftToFilter;
+    /*
+     * Connection state:
+     * ST_NOT_CONNECTED = socket not connected
+     * ST_CONNECTED = socket connected
+     * ST_CONNECTED_NO_IMPL = socket connected but not at impl level
+     */
+    static final int ST_NOT_CONNECTED = 0;
+    static final int ST_CONNECTED = 1;
+    static final int ST_CONNECTED_NO_IMPL = 2;
+
+    int connectState = ST_NOT_CONNECTED;
+
+    /*
+     * Connected address & port
+     */
+    InetAddress connectedAddress = null;
+    int connectedPort = -1;
+
+    // Android-added: Store pending exception from connect
+    private SocketException pendingConnectException;
+
+    /**
+     * Connects this socket to a remote socket address (IP address + port number).
+     * Binds socket if not already bound.
+     * <p>
+     * @param   address The remote address.
+     * @param   port    The remote port
+     * @throws  SocketException if binding the socket fails.
+     */
+    private synchronized void connectInternal(InetAddress address, int port) throws SocketException {
+        if (port < 0 || port > 0xFFFF) {
+            throw new IllegalArgumentException("connect: " + port);
+        }
+        if (address == null) {
+            throw new IllegalArgumentException("connect: null address");
+        }
+        checkAddress (address, "connect");
+        if (isClosed())
+            return;
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            if (address.isMulticastAddress()) {
+                security.checkMulticast(address);
+            } else {
+                security.checkConnect(address.getHostAddress(), port);
+                security.checkAccept(address.getHostAddress(), port);
+            }
+        }
+
+        if (!isBound())
+          bind(new InetSocketAddress(0));
+
+        // Android-changed: This section now throws any SocketException generated by connect()
+        // to enable it to be recorded as the pendingConnectException. It has been enclosed in a
+        // try-finally to ensure connectedAddress and connectedPort are set when the exception
+        // is thrown.
+        try {
+            // old impls do not support connect/disconnect
+            // Android-changed: Added special handling for AbstractPlainDatagramSocketImpl in
+            // the condition below.
+            if (oldImpl || (impl instanceof AbstractPlainDatagramSocketImpl &&
+                    ((AbstractPlainDatagramSocketImpl)impl).nativeConnectDisabled())) {
+                connectState = ST_CONNECTED_NO_IMPL;
+            } else {
+                try {
+                    getImpl().connect(address, port);
+
+                    // socket is now connected by the impl
+                    connectState = ST_CONNECTED;
+
+                    // Do we need to filter some packets?
+                    int avail = getImpl().dataAvailable();
+                    if (avail == -1) {
+                        throw new SocketException();
+                    }
+                    explicitFilter = avail > 0;
+                    if (explicitFilter) {
+                        bytesLeftToFilter = getReceiveBufferSize();
+                    }
+                } catch (SocketException se) {
+                    // connection will be emulated by DatagramSocket
+                    connectState = ST_CONNECTED_NO_IMPL;
+                    // Android-changed: Propagate the SocketException so connect() can store it.
+                    throw se;
+                }
+           }
+        } finally {
+            connectedAddress = address;
+            connectedPort = port;
+        }
+    }
+
+
+    /**
+     * Constructs a datagram socket and binds it to any available port
+     * on the local host machine.  The socket will be bound to the
+     * {@link InetAddress#isAnyLocalAddress wildcard} address,
+     * an IP address chosen by the kernel.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with 0 as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @exception  SocketException  if the socket could not be opened,
+     *               or the socket could not bind to the specified local port.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     *
+     * @see SecurityManager#checkListen
+     */
+    public DatagramSocket() throws SocketException {
+        this(new InetSocketAddress(0));
+    }
+
+    /**
+     * Creates an unbound datagram socket with the specified
+     * DatagramSocketImpl.
+     *
+     * @param impl an instance of a <B>DatagramSocketImpl</B>
+     *        the subclass wishes to use on the DatagramSocket.
+     * @since   1.4
+     */
+    protected DatagramSocket(DatagramSocketImpl impl) {
+        if (impl == null)
+            throw new NullPointerException();
+        this.impl = impl;
+        checkOldImpl();
+    }
+
+    /**
+     * Creates a datagram socket, bound to the specified local
+     * socket address.
+     * <p>
+     * If, if the address is {@code null}, creates an unbound socket.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with the port from the socket address
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param bindaddr local socket address to bind, or {@code null}
+     *                 for an unbound socket.
+     *
+     * @exception  SocketException  if the socket could not be opened,
+     *               or the socket could not bind to the specified local port.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     *
+     * @see SecurityManager#checkListen
+     * @since   1.4
+     */
+    public DatagramSocket(SocketAddress bindaddr) throws SocketException {
+        // create a datagram socket.
+        createImpl();
+        if (bindaddr != null) {
+            try {
+                bind(bindaddr);
+            } finally {
+                if (!isBound())
+                    close();
+            }
+        }
+    }
+
+    /**
+     * Constructs a datagram socket and binds it to the specified port
+     * on the local host machine.  The socket will be bound to the
+     * {@link InetAddress#isAnyLocalAddress wildcard} address,
+     * an IP address chosen by the kernel.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with the {@code port} argument
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param      port port to use.
+     * @exception  SocketException  if the socket could not be opened,
+     *               or the socket could not bind to the specified local port.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     *
+     * @see SecurityManager#checkListen
+     */
+    public DatagramSocket(int port) throws SocketException {
+        this(port, null);
+    }
+
+    /**
+     * Creates a datagram socket, bound to the specified local
+     * address.  The local port must be between 0 and 65535 inclusive.
+     * If the IP address is 0.0.0.0, the socket will be bound to the
+     * {@link InetAddress#isAnyLocalAddress wildcard} address,
+     * an IP address chosen by the kernel.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with the {@code port} argument
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param port local port to use
+     * @param laddr local address to bind
+     *
+     * @exception  SocketException  if the socket could not be opened,
+     *               or the socket could not bind to the specified local port.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     *
+     * @see SecurityManager#checkListen
+     * @since   JDK1.1
+     */
+    public DatagramSocket(int port, InetAddress laddr) throws SocketException {
+        this(new InetSocketAddress(laddr, port));
+    }
+
+    private void checkOldImpl() {
+        if (impl == null)
+            return;
+        // DatagramSocketImpl.peekdata() is a protected method, therefore we need to use
+        // getDeclaredMethod, therefore we need permission to access the member
+        try {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                    public Void run() throws NoSuchMethodException {
+                        Class<?>[] cl = new Class<?>[1];
+                        cl[0] = DatagramPacket.class;
+                        impl.getClass().getDeclaredMethod("peekData", cl);
+                        return null;
+                    }
+                });
+        } catch (java.security.PrivilegedActionException e) {
+            oldImpl = true;
+        }
+    }
+
+    static Class<?> implClass = null;
+
+    void createImpl() throws SocketException {
+        if (impl == null) {
+            if (factory != null) {
+                impl = factory.createDatagramSocketImpl();
+                checkOldImpl();
+            } else {
+                boolean isMulticast = (this instanceof MulticastSocket) ? true : false;
+                impl = DefaultDatagramSocketImplFactory.createDatagramSocketImpl(isMulticast);
+
+                checkOldImpl();
+            }
+        }
+        // creates a udp socket
+        impl.create();
+        impl.setDatagramSocket(this);
+        created = true;
+    }
+
+    /**
+     * Get the {@code DatagramSocketImpl} attached to this socket,
+     * creating it if necessary.
+     *
+     * @return  the {@code DatagramSocketImpl} attached to that
+     *          DatagramSocket
+     * @throws SocketException if creation fails.
+     * @since 1.4
+     */
+    DatagramSocketImpl getImpl() throws SocketException {
+        if (!created)
+            createImpl();
+        return impl;
+    }
+
+    /**
+     * Binds this DatagramSocket to a specific address and port.
+     * <p>
+     * If the address is {@code null}, then the system will pick up
+     * an ephemeral port and a valid local address to bind the socket.
+     *<p>
+     * @param   addr The address and port to bind to.
+     * @throws  SocketException if any error happens during the bind, or if the
+     *          socket is already bound.
+     * @throws  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     * @throws IllegalArgumentException if addr is a SocketAddress subclass
+     *         not supported by this socket.
+     * @since 1.4
+     */
+    public synchronized void bind(SocketAddress addr) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (isBound())
+            throw new SocketException("already bound");
+        if (addr == null)
+            addr = new InetSocketAddress(0);
+        if (!(addr instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type!");
+        InetSocketAddress epoint = (InetSocketAddress) addr;
+        if (epoint.isUnresolved())
+            throw new SocketException("Unresolved address");
+        InetAddress iaddr = epoint.getAddress();
+        int port = epoint.getPort();
+        checkAddress(iaddr, "bind");
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) {
+            sec.checkListen(port);
+        }
+        try {
+            getImpl().bind(port, iaddr);
+        } catch (SocketException e) {
+            getImpl().close();
+            throw e;
+        }
+        bound = true;
+    }
+
+    void checkAddress (InetAddress addr, String op) {
+        if (addr == null) {
+            return;
+        }
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
+            throw new IllegalArgumentException(op + ": invalid address type");
+        }
+    }
+
+    /**
+     * Connects the socket to a remote address for this socket. When a
+     * socket is connected to a remote address, packets may only be
+     * sent to or received from that address. By default a datagram
+     * socket is not connected.
+     *
+     * <p>If the remote destination to which the socket is connected does not
+     * exist, or is otherwise unreachable, and if an ICMP destination unreachable
+     * packet has been received for that address, then a subsequent call to
+     * send or receive may throw a PortUnreachableException. Note, there is no
+     * guarantee that the exception will be thrown.
+     *
+     * <p> If a security manager has been installed then it is invoked to check
+     * access to the remote address. Specifically, if the given {@code address}
+     * is a {@link InetAddress#isMulticastAddress multicast address},
+     * the security manager's {@link
+     * java.lang.SecurityManager#checkMulticast(InetAddress)
+     * checkMulticast} method is invoked with the given {@code address}.
+     * Otherwise, the security manager's {@link
+     * java.lang.SecurityManager#checkConnect(String,int) checkConnect}
+     * and {@link java.lang.SecurityManager#checkAccept checkAccept} methods
+     * are invoked, with the given {@code address} and {@code port}, to
+     * verify that datagrams are permitted to be sent and received
+     * respectively.
+     *
+     * <p> When a socket is connected, {@link #receive receive} and
+     * {@link #send send} <b>will not perform any security checks</b>
+     * on incoming and outgoing packets, other than matching the packet's
+     * and the socket's address and port. On a send operation, if the
+     * packet's address is set and the packet's address and the socket's
+     * address do not match, an {@code IllegalArgumentException} will be
+     * thrown. A socket connected to a multicast address may only be used
+     * to send packets.
+     *
+     * @param address the remote address for the socket
+     *
+     * @param port the remote port for the socket.
+     *
+     * @throws IllegalArgumentException
+     *         if the address is null, or the port is out of range.
+     *
+     * @throws SecurityException
+     *         if a security manager has been installed and it does
+     *         not permit access to the given remote address
+     *
+     * @see #disconnect
+     */
+    public void connect(InetAddress address, int port) {
+        try {
+            connectInternal(address, port);
+        } catch (SocketException se) {
+            // Android-changed: this method can't throw checked SocketException. Throw it later
+            // throw new Error("connect failed", se);
+            // TODO: or just use SneakyThrow? There's a clear API bug here.
+            pendingConnectException = se;
+        }
+    }
+
+    /**
+     * Connects this socket to a remote socket address (IP address + port number).
+     *
+     * <p> If given an {@link InetSocketAddress InetSocketAddress}, this method
+     * behaves as if invoking {@link #connect(InetAddress,int) connect(InetAddress,int)}
+     * with the the given socket addresses IP address and port number.
+     *
+     * @param   addr    The remote address.
+     *
+     * @throws  SocketException
+     *          if the connect fails
+     *
+     * @throws IllegalArgumentException
+     *         if {@code addr} is {@code null}, or {@code addr} is a SocketAddress
+     *         subclass not supported by this socket
+     *
+     * @throws SecurityException
+     *         if a security manager has been installed and it does
+     *         not permit access to the given remote address
+     *
+     * @since 1.4
+     */
+    public void connect(SocketAddress addr) throws SocketException {
+        if (addr == null)
+            throw new IllegalArgumentException("Address can't be null");
+        if (!(addr instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+        InetSocketAddress epoint = (InetSocketAddress) addr;
+        if (epoint.isUnresolved())
+            throw new SocketException("Unresolved address");
+        connectInternal(epoint.getAddress(), epoint.getPort());
+    }
+
+    /**
+     * Disconnects the socket. If the socket is closed or not connected,
+     * then this method has no effect.
+     *
+     * @see #connect
+     */
+    public void disconnect() {
+        synchronized (this) {
+            if (isClosed())
+                return;
+            if (connectState == ST_CONNECTED) {
+                impl.disconnect ();
+            }
+            connectedAddress = null;
+            connectedPort = -1;
+            connectState = ST_NOT_CONNECTED;
+            explicitFilter = false;
+        }
+    }
+
+    /**
+     * Returns the binding state of the socket.
+     * <p>
+     * If the socket was bound prior to being {@link #close closed},
+     * then this method will continue to return {@code true}
+     * after the socket is closed.
+     *
+     * @return true if the socket successfully bound to an address
+     * @since 1.4
+     */
+    public boolean isBound() {
+        return bound;
+    }
+
+    /**
+     * Returns the connection state of the socket.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return {@code true}
+     * after the socket is closed.
+     *
+     * @return true if the socket successfully connected to a server
+     * @since 1.4
+     */
+    public boolean isConnected() {
+        return connectState != ST_NOT_CONNECTED;
+    }
+
+    /**
+     * Returns the address to which this socket is connected. Returns
+     * {@code null} if the socket is not connected.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return the connected address
+     * after the socket is closed.
+     *
+     * @return the address to which this socket is connected.
+     */
+    public InetAddress getInetAddress() {
+        return connectedAddress;
+    }
+
+    /**
+     * Returns the port number to which this socket is connected.
+     * Returns {@code -1} if the socket is not connected.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return the connected port number
+     * after the socket is closed.
+     *
+     * @return the port number to which this socket is connected.
+     */
+    public int getPort() {
+        return connectedPort;
+    }
+
+    /**
+     * Returns the address of the endpoint this socket is connected to, or
+     * {@code null} if it is unconnected.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return the connected address
+     * after the socket is closed.
+     *
+     * @return a {@code SocketAddress} representing the remote
+     *         endpoint of this socket, or {@code null} if it is
+     *         not connected yet.
+     * @see #getInetAddress()
+     * @see #getPort()
+     * @see #connect(SocketAddress)
+     * @since 1.4
+     */
+    public SocketAddress getRemoteSocketAddress() {
+        if (!isConnected())
+            return null;
+        return new InetSocketAddress(getInetAddress(), getPort());
+    }
+
+    /**
+     * Returns the address of the endpoint this socket is bound to.
+     *
+     * @return a {@code SocketAddress} representing the local endpoint of this
+     *         socket, or {@code null} if it is closed or not bound yet.
+     * @see #getLocalAddress()
+     * @see #getLocalPort()
+     * @see #bind(SocketAddress)
+     * @since 1.4
+     */
+
+    public SocketAddress getLocalSocketAddress() {
+        if (isClosed())
+            return null;
+        if (!isBound())
+            return null;
+        return new InetSocketAddress(getLocalAddress(), getLocalPort());
+    }
+
+    /**
+     * Sends a datagram packet from this socket. The
+     * {@code DatagramPacket} includes information indicating the
+     * data to be sent, its length, the IP address of the remote host,
+     * and the port number on the remote host.
+     *
+     * <p>If there is a security manager, and the socket is not currently
+     * connected to a remote address, this method first performs some
+     * security checks. First, if {@code p.getAddress().isMulticastAddress()}
+     * is true, this method calls the
+     * security manager's {@code checkMulticast} method
+     * with {@code p.getAddress()} as its argument.
+     * If the evaluation of that expression is false,
+     * this method instead calls the security manager's
+     * {@code checkConnect} method with arguments
+     * {@code p.getAddress().getHostAddress()} and
+     * {@code p.getPort()}. Each call to a security manager method
+     * could result in a SecurityException if the operation is not allowed.
+     *
+     * @param      p   the {@code DatagramPacket} to be sent.
+     *
+     * @exception  IOException  if an I/O error occurs.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkMulticast} or {@code checkConnect}
+     *             method doesn't allow the send.
+     * @exception  PortUnreachableException may be thrown if the socket is connected
+     *             to a currently unreachable destination. Note, there is no
+     *             guarantee that the exception will be thrown.
+     * @exception  java.nio.channels.IllegalBlockingModeException
+     *             if this socket has an associated channel,
+     *             and the channel is in non-blocking mode.
+     * @exception  IllegalArgumentException if the socket is connected,
+     *             and connected address and packet address differ.
+     *
+     * @see        java.net.DatagramPacket
+     * @see        SecurityManager#checkMulticast(InetAddress)
+     * @see        SecurityManager#checkConnect
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public void send(DatagramPacket p) throws IOException  {
+        InetAddress packetAddress = null;
+        synchronized (p) {
+            // BEGIN Android-changed
+            if (pendingConnectException != null) {
+                throw new SocketException("Pending connect failure", pendingConnectException);
+            }
+            // END Android-changed
+            if (isClosed())
+                throw new SocketException("Socket is closed");
+            checkAddress (p.getAddress(), "send");
+            if (connectState == ST_NOT_CONNECTED) {
+                // check the address is ok wiht the security manager on every send.
+                SecurityManager security = System.getSecurityManager();
+
+                // The reason you want to synchronize on datagram packet
+                // is because you don't want an applet to change the address
+                // while you are trying to send the packet for example
+                // after the security check but before the send.
+                if (security != null) {
+                    if (p.getAddress().isMulticastAddress()) {
+                        security.checkMulticast(p.getAddress());
+                    } else {
+                        security.checkConnect(p.getAddress().getHostAddress(),
+                                              p.getPort());
+                    }
+                }
+            } else {
+                // we're connected
+                packetAddress = p.getAddress();
+                if (packetAddress == null) {
+                    p.setAddress(connectedAddress);
+                    p.setPort(connectedPort);
+                } else if ((!packetAddress.equals(connectedAddress)) ||
+                           p.getPort() != connectedPort) {
+                    throw new IllegalArgumentException("connected address " +
+                                                       "and packet address" +
+                                                       " differ");
+                }
+            }
+            // Check whether the socket is bound
+            if (!isBound())
+                bind(new InetSocketAddress(0));
+            // call the  method to send
+            getImpl().send(p);
+        }
+    }
+
+    /**
+     * Receives a datagram packet from this socket. When this method
+     * returns, the {@code DatagramPacket}'s buffer is filled with
+     * the data received. The datagram packet also contains the sender's
+     * IP address, and the port number on the sender's machine.
+     * <p>
+     * This method blocks until a datagram is received. The
+     * {@code length} field of the datagram packet object contains
+     * the length of the received message. If the message is longer than
+     * the packet's length, the message is truncated.
+     * <p>
+     * If there is a security manager, a packet cannot be received if the
+     * security manager's {@code checkAccept} method
+     * does not allow it.
+     *
+     * @param      p   the {@code DatagramPacket} into which to place
+     *                 the incoming data.
+     * @exception  IOException  if an I/O error occurs.
+     * @exception  SocketTimeoutException  if setSoTimeout was previously called
+     *                 and the timeout has expired.
+     * @exception  PortUnreachableException may be thrown if the socket is connected
+     *             to a currently unreachable destination. Note, there is no guarantee that the
+     *             exception will be thrown.
+     * @exception  java.nio.channels.IllegalBlockingModeException
+     *             if this socket has an associated channel,
+     *             and the channel is in non-blocking mode.
+     * @see        java.net.DatagramPacket
+     * @see        java.net.DatagramSocket
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public synchronized void receive(DatagramPacket p) throws IOException {
+        synchronized (p) {
+            if (!isBound())
+                bind(new InetSocketAddress(0));
+
+            // BEGIN Android-changed
+            if (pendingConnectException != null) {
+                throw new SocketException("Pending connect failure", pendingConnectException);
+            }
+            // END Android-changed
+
+            if (connectState == ST_NOT_CONNECTED) {
+                // check the address is ok with the security manager before every recv.
+                SecurityManager security = System.getSecurityManager();
+                if (security != null) {
+                    while(true) {
+                        String peekAd = null;
+                        int peekPort = 0;
+                        // peek at the packet to see who it is from.
+                        if (!oldImpl) {
+                            // We can use the new peekData() API
+                            DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
+                            peekPort = getImpl().peekData(peekPacket);
+                            peekAd = peekPacket.getAddress().getHostAddress();
+                        } else {
+                            InetAddress adr = new InetAddress();
+                            peekPort = getImpl().peek(adr);
+                            peekAd = adr.getHostAddress();
+                        }
+                        try {
+                            security.checkAccept(peekAd, peekPort);
+                            // security check succeeded - so now break
+                            // and recv the packet.
+                            break;
+                        } catch (SecurityException se) {
+                            // Throw away the offending packet by consuming
+                            // it in a tmp buffer.
+                            DatagramPacket tmp = new DatagramPacket(new byte[1], 1);
+                            getImpl().receive(tmp);
+
+                            // silently discard the offending packet
+                            // and continue: unknown/malicious
+                            // entities on nets should not make
+                            // runtime throw security exception and
+                            // disrupt the applet by sending random
+                            // datagram packets.
+                            continue;
+                        }
+                    } // end of while
+                }
+            }
+            DatagramPacket tmp = null;
+            if ((connectState == ST_CONNECTED_NO_IMPL) || explicitFilter) {
+                // We have to do the filtering the old fashioned way since
+                // the native impl doesn't support connect or the connect
+                // via the impl failed, or .. "explicitFilter" may be set when
+                // a socket is connected via the impl, for a period of time
+                // when packets from other sources might be queued on socket.
+                boolean stop = false;
+                while (!stop) {
+                    InetAddress peekAddress = null;
+                    int peekPort = -1;
+                    // peek at the packet to see who it is from.
+                    if (!oldImpl) {
+                        // We can use the new peekData() API
+                        DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1);
+                        peekPort = getImpl().peekData(peekPacket);
+                        peekAddress = peekPacket.getAddress();
+                    } else {
+                        // this api only works for IPv4
+                        peekAddress = new InetAddress();
+                        peekPort = getImpl().peek(peekAddress);
+                    }
+                    if ((!connectedAddress.equals(peekAddress)) ||
+                        (connectedPort != peekPort)) {
+                        // throw the packet away and silently continue
+                        tmp = new DatagramPacket(
+                                                new byte[1024], 1024);
+                        getImpl().receive(tmp);
+                        if (explicitFilter) {
+                            if (checkFiltering(tmp)) {
+                                stop = true;
+                            }
+                        }
+                    } else {
+                        stop = true;
+                    }
+                }
+            }
+            // If the security check succeeds, or the datagram is
+            // connected then receive the packet
+            getImpl().receive(p);
+            if (explicitFilter && tmp == null) {
+                // packet was not filtered, account for it here
+                checkFiltering(p);
+            }
+        }
+    }
+
+    private boolean checkFiltering(DatagramPacket p) throws SocketException {
+        bytesLeftToFilter -= p.getLength();
+        if (bytesLeftToFilter <= 0 || getImpl().dataAvailable() <= 0) {
+            explicitFilter = false;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Gets the local address to which the socket is bound.
+     *
+     * <p>If there is a security manager, its
+     * {@code checkConnect} method is first called
+     * with the host address and {@code -1}
+     * as its arguments to see if the operation is allowed.
+     *
+     * @see SecurityManager#checkConnect
+     * @return  the local address to which the socket is bound,
+     *          {@code null} if the socket is closed, or
+     *          an {@code InetAddress} representing
+     *          {@link InetAddress#isAnyLocalAddress wildcard}
+     *          address if either the socket is not bound, or
+     *          the security manager {@code checkConnect}
+     *          method does not allow the operation
+     * @since   1.1
+     */
+    public InetAddress getLocalAddress() {
+        if (isClosed())
+            return null;
+        InetAddress in = null;
+        try {
+            in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+            if (in.isAnyLocalAddress()) {
+                in = InetAddress.anyLocalAddress();
+            }
+            SecurityManager s = System.getSecurityManager();
+            if (s != null) {
+                s.checkConnect(in.getHostAddress(), -1);
+            }
+        } catch (Exception e) {
+            in = InetAddress.anyLocalAddress(); // "0.0.0.0"
+        }
+        return in;
+    }
+
+    /**
+     * Returns the port number on the local host to which this socket
+     * is bound.
+     *
+     * @return  the port number on the local host to which this socket is bound,
+                {@code -1} if the socket is closed, or
+                {@code 0} if it is not bound yet.
+     */
+    public int getLocalPort() {
+        if (isClosed())
+            return -1;
+        try {
+            return getImpl().getLocalPort();
+        } catch (Exception e) {
+            return 0;
+        }
+    }
+
+    /** Enable/disable SO_TIMEOUT with the specified timeout, in
+     *  milliseconds. With this option set to a non-zero timeout,
+     *  a call to receive() for this DatagramSocket
+     *  will block for only this amount of time.  If the timeout expires,
+     *  a <B>java.net.SocketTimeoutException</B> is raised, though the
+     *  DatagramSocket is still valid.  The option <B>must</B> be enabled
+     *  prior to entering the blocking operation to have effect.  The
+     *  timeout must be {@code > 0}.
+     *  A timeout of zero is interpreted as an infinite timeout.
+     *
+     * @param timeout the specified timeout in milliseconds.
+     * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
+     * @since   JDK1.1
+     * @see #getSoTimeout()
+     */
+    public synchronized void setSoTimeout(int timeout) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+    }
+
+    /**
+     * Retrieve setting for SO_TIMEOUT.  0 returns implies that the
+     * option is disabled (i.e., timeout of infinity).
+     *
+     * @return the setting for SO_TIMEOUT
+     * @throws SocketException if there is an error in the underlying protocol, such as an UDP error.
+     * @since   JDK1.1
+     * @see #setSoTimeout(int)
+     */
+    public synchronized int getSoTimeout() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (getImpl() == null)
+            return 0;
+        Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
+        /* extra type safety */
+        if (o instanceof Integer) {
+            return ((Integer) o).intValue();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Sets the SO_SNDBUF option to the specified value for this
+     * {@code DatagramSocket}. The SO_SNDBUF option is used by the
+     * network implementation as a hint to size the underlying
+     * network I/O buffers. The SO_SNDBUF setting may also be used
+     * by the network implementation to determine the maximum size
+     * of the packet that can be sent on this socket.
+     * <p>
+     * As SO_SNDBUF is a hint, applications that want to verify
+     * what size the buffer is should call {@link #getSendBufferSize()}.
+     * <p>
+     * Increasing the buffer size may allow multiple outgoing packets
+     * to be queued by the network implementation when the send rate
+     * is high.
+     * <p>
+     * Note: If {@link #send(DatagramPacket)} is used to send a
+     * {@code DatagramPacket} that is larger than the setting
+     * of SO_SNDBUF then it is implementation specific if the
+     * packet is sent or discarded.
+     *
+     * @param size the size to which to set the send buffer
+     * size. This value must be greater than 0.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as an UDP error.
+     * @exception IllegalArgumentException if the value is 0 or is
+     * negative.
+     * @see #getSendBufferSize()
+     */
+    public synchronized void setSendBufferSize(int size)
+    throws SocketException{
+        if (!(size > 0)) {
+            throw new IllegalArgumentException("negative send size");
+        }
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
+    }
+
+    /**
+     * Get value of the SO_SNDBUF option for this {@code DatagramSocket}, that is the
+     * buffer size used by the platform for output on this {@code DatagramSocket}.
+     *
+     * @return the value of the SO_SNDBUF option for this {@code DatagramSocket}
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as an UDP error.
+     * @see #setSendBufferSize
+     */
+    public synchronized int getSendBufferSize() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        int result = 0;
+        Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
+        if (o instanceof Integer) {
+            result = ((Integer)o).intValue();
+        }
+        return result;
+    }
+
+    /**
+     * Sets the SO_RCVBUF option to the specified value for this
+     * {@code DatagramSocket}. The SO_RCVBUF option is used by the
+     * the network implementation as a hint to size the underlying
+     * network I/O buffers. The SO_RCVBUF setting may also be used
+     * by the network implementation to determine the maximum size
+     * of the packet that can be received on this socket.
+     * <p>
+     * Because SO_RCVBUF is a hint, applications that want to
+     * verify what size the buffers were set to should call
+     * {@link #getReceiveBufferSize()}.
+     * <p>
+     * Increasing SO_RCVBUF may allow the network implementation
+     * to buffer multiple packets when packets arrive faster than
+     * are being received using {@link #receive(DatagramPacket)}.
+     * <p>
+     * Note: It is implementation specific if a packet larger
+     * than SO_RCVBUF can be received.
+     *
+     * @param size the size to which to set the receive buffer
+     * size. This value must be greater than 0.
+     *
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as an UDP error.
+     * @exception IllegalArgumentException if the value is 0 or is
+     * negative.
+     * @see #getReceiveBufferSize()
+     */
+    public synchronized void setReceiveBufferSize(int size)
+    throws SocketException{
+        if (size <= 0) {
+            throw new IllegalArgumentException("invalid receive size");
+        }
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+    }
+
+    /**
+     * Get value of the SO_RCVBUF option for this {@code DatagramSocket}, that is the
+     * buffer size used by the platform for input on this {@code DatagramSocket}.
+     *
+     * @return the value of the SO_RCVBUF option for this {@code DatagramSocket}
+     * @exception SocketException if there is an error in the underlying protocol, such as an UDP error.
+     * @see #setReceiveBufferSize(int)
+     */
+    public synchronized int getReceiveBufferSize()
+    throws SocketException{
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        int result = 0;
+        Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
+        if (o instanceof Integer) {
+            result = ((Integer)o).intValue();
+        }
+        return result;
+    }
+
+    /**
+     * Enable/disable the SO_REUSEADDR socket option.
+     * <p>
+     * For UDP sockets it may be necessary to bind more than one
+     * socket to the same socket address. This is typically for the
+     * purpose of receiving multicast packets
+     * (See {@link java.net.MulticastSocket}). The
+     * {@code SO_REUSEADDR} socket option allows multiple
+     * sockets to be bound to the same socket address if the
+     * {@code SO_REUSEADDR} socket option is enabled prior
+     * to binding the socket using {@link #bind(SocketAddress)}.
+     * <p>
+     * Note: This functionality is not supported by all existing platforms,
+     * so it is implementation specific whether this option will be ignored
+     * or not. However, if it is not supported then
+     * {@link #getReuseAddress()} will always return {@code false}.
+     * <p>
+     * When a {@code DatagramSocket} is created the initial setting
+     * of {@code SO_REUSEADDR} is disabled.
+     * <p>
+     * The behaviour when {@code SO_REUSEADDR} is enabled or
+     * disabled after a socket is bound (See {@link #isBound()})
+     * is not defined.
+     *
+     * @param on  whether to enable or disable the
+     * @exception SocketException if an error occurs enabling or
+     *            disabling the {@code SO_RESUEADDR} socket option,
+     *            or the socket is closed.
+     * @since 1.4
+     * @see #getReuseAddress()
+     * @see #bind(SocketAddress)
+     * @see #isBound()
+     * @see #isClosed()
+     */
+    public synchronized void setReuseAddress(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        // Integer instead of Boolean for compatibility with older DatagramSocketImpl
+        if (oldImpl)
+            getImpl().setOption(SocketOptions.SO_REUSEADDR, new Integer(on?-1:0));
+        else
+            getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if SO_REUSEADDR is enabled.
+     *
+     * @return a {@code boolean} indicating whether or not SO_REUSEADDR is enabled.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as an UDP error.
+     * @since   1.4
+     * @see #setReuseAddress(boolean)
+     */
+    public synchronized boolean getReuseAddress() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        Object o = getImpl().getOption(SocketOptions.SO_REUSEADDR);
+        return ((Boolean)o).booleanValue();
+    }
+
+    /**
+     * Enable/disable SO_BROADCAST.
+     *
+     * <p> Some operating systems may require that the Java virtual machine be
+     * started with implementation specific privileges to enable this option or
+     * send broadcast datagrams.
+     *
+     * @param  on
+     *         whether or not to have broadcast turned on.
+     *
+     * @throws  SocketException
+     *          if there is an error in the underlying protocol, such as an UDP
+     *          error.
+     *
+     * @since 1.4
+     * @see #getBroadcast()
+     */
+    public synchronized void setBroadcast(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_BROADCAST, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if SO_BROADCAST is enabled.
+     * @return a {@code boolean} indicating whether or not SO_BROADCAST is enabled.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as an UDP error.
+     * @since 1.4
+     * @see #setBroadcast(boolean)
+     */
+    public synchronized boolean getBroadcast() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Boolean)(getImpl().getOption(SocketOptions.SO_BROADCAST))).booleanValue();
+    }
+
+    /**
+     * Sets traffic class or type-of-service octet in the IP
+     * datagram header for datagrams sent from this DatagramSocket.
+     * As the underlying network implementation may ignore this
+     * value applications should consider it a hint.
+     *
+     * <P> The tc <B>must</B> be in the range {@code 0 <= tc <=
+     * 255} or an IllegalArgumentException will be thrown.
+     * <p>Notes:
+     * <p>For Internet Protocol v4 the value consists of an
+     * {@code integer}, the least significant 8 bits of which
+     * represent the value of the TOS octet in IP packets sent by
+     * the socket.
+     * RFC 1349 defines the TOS values as follows:
+     *
+     * <UL>
+     * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
+     * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
+     * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
+     * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
+     * </UL>
+     * The last low order bit is always ignored as this
+     * corresponds to the MBZ (must be zero) bit.
+     * <p>
+     * Setting bits in the precedence field may result in a
+     * SocketException indicating that the operation is not
+     * permitted.
+     * <p>
+     * for Internet Protocol v6 {@code tc} is the value that
+     * would be placed into the sin6_flowinfo field of the IP header.
+     *
+     * @param tc        an {@code int} value for the bitset.
+     * @throws SocketException if there is an error setting the
+     * traffic class or type-of-service
+     * @since 1.4
+     * @see #getTrafficClass
+     */
+    public synchronized void setTrafficClass(int tc) throws SocketException {
+        if (tc < 0 || tc > 255)
+            throw new IllegalArgumentException("tc is not in range 0 -- 255");
+
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        try {
+            getImpl().setOption(SocketOptions.IP_TOS, tc);
+        } catch (SocketException se) {
+            // not supported if socket already connected
+            // Solaris returns error in such cases
+            if(!isConnected())
+                throw se;
+        }
+    }
+
+    /**
+     * Gets traffic class or type-of-service in the IP datagram
+     * header for packets sent from this DatagramSocket.
+     * <p>
+     * As the underlying network implementation may ignore the
+     * traffic class or type-of-service set using {@link #setTrafficClass(int)}
+     * this method may return a different value than was previously
+     * set using the {@link #setTrafficClass(int)} method on this
+     * DatagramSocket.
+     *
+     * @return the traffic class or type-of-service already set
+     * @throws SocketException if there is an error obtaining the
+     * traffic class or type-of-service value.
+     * @since 1.4
+     * @see #setTrafficClass(int)
+     */
+    public synchronized int getTrafficClass() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Integer)(getImpl().getOption(SocketOptions.IP_TOS))).intValue();
+    }
+
+    /**
+     * Closes this datagram socket.
+     * <p>
+     * Any thread currently blocked in {@link #receive} upon this socket
+     * will throw a {@link SocketException}.
+     *
+     * <p> If this socket has an associated channel then the channel is closed
+     * as well.
+     *
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public void close() {
+        synchronized(closeLock) {
+            if (isClosed())
+                return;
+            impl.close();
+            closed = true;
+        }
+    }
+
+    /**
+     * Returns whether the socket is closed or not.
+     *
+     * @return true if the socket has been closed
+     * @since 1.4
+     */
+    public boolean isClosed() {
+        synchronized(closeLock) {
+            return closed;
+        }
+    }
+
+    /**
+     * Returns the unique {@link java.nio.channels.DatagramChannel} object
+     * associated with this datagram socket, if any.
+     *
+     * <p> A datagram socket will have a channel if, and only if, the channel
+     * itself was created via the {@link java.nio.channels.DatagramChannel#open
+     * DatagramChannel.open} method.
+     *
+     * @return  the datagram channel associated with this datagram socket,
+     *          or {@code null} if this socket was not created for a channel
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public DatagramChannel getChannel() {
+        return null;
+    }
+
+    /**
+     * User defined factory for all datagram sockets.
+     */
+    static DatagramSocketImplFactory factory;
+
+    /**
+     * Sets the datagram socket implementation factory for the
+     * application. The factory can be specified only once.
+     * <p>
+     * When an application creates a new datagram socket, the socket
+     * implementation factory's {@code createDatagramSocketImpl} method is
+     * called to create the actual datagram socket implementation.
+     * <p>
+     * Passing {@code null} to the method is a no-op unless the factory
+     * was already set.
+     *
+     * <p>If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param      fac   the desired factory.
+     * @exception  IOException  if an I/O error occurs when setting the
+     *              datagram socket factory.
+     * @exception  SocketException  if the factory is already defined.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't allow the
+     operation.
+     * @see
+     java.net.DatagramSocketImplFactory#createDatagramSocketImpl()
+     * @see       SecurityManager#checkSetFactory
+     * @since 1.3
+     */
+    public static synchronized void
+    setDatagramSocketImplFactory(DatagramSocketImplFactory fac)
+       throws IOException
+    {
+        if (factory != null) {
+            throw new SocketException("factory already defined");
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSetFactory();
+        }
+        factory = fac;
+    }
+
+    // Android-added: for testing and internal use.
+    /**
+     * @hide internal use only
+     */
+    public FileDescriptor getFileDescriptor$() {
+        return impl.fd;
+    }
+
+}
diff --git a/java/net/DatagramSocketImpl.java b/java/net/DatagramSocketImpl.java
new file mode 100644
index 0000000..537edfe
--- /dev/null
+++ b/java/net/DatagramSocketImpl.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+
+/**
+ * Abstract datagram and multicast socket implementation base class.
+ * @author Pavani Diwanji
+ * @since  JDK1.1
+ */
+
+public abstract class DatagramSocketImpl implements SocketOptions {
+
+    /**
+     * The local port number.
+     */
+    protected int localPort;
+
+    /**
+     * The file descriptor object.
+     */
+    protected FileDescriptor fd;
+
+    int dataAvailable() {
+        // default impl returns zero, which disables the calling
+        // functionality
+        return 0;
+    }
+
+    /**
+     * The DatagramSocket or MulticastSocket
+     * that owns this impl
+     */
+    DatagramSocket socket;
+
+    void setDatagramSocket(DatagramSocket socket) {
+        this.socket = socket;
+    }
+
+    DatagramSocket getDatagramSocket() {
+        return socket;
+    }
+
+    /**
+     * Creates a datagram socket.
+     * @exception SocketException if there is an error in the
+     * underlying protocol, such as a TCP error.
+     */
+    protected abstract void create() throws SocketException;
+
+    /**
+     * Binds a datagram socket to a local port and address.
+     * @param lport the local port
+     * @param laddr the local address
+     * @exception SocketException if there is an error in the
+     * underlying protocol, such as a TCP error.
+     */
+    protected abstract void bind(int lport, InetAddress laddr) throws SocketException;
+
+    /**
+     * Sends a datagram packet. The packet contains the data and the
+     * destination address to send the packet to.
+     * @param p the packet to be sent.
+     * @exception IOException if an I/O exception occurs while sending the
+     * datagram packet.
+     * @exception  PortUnreachableException may be thrown if the socket is connected
+     * to a currently unreachable destination. Note, there is no guarantee that
+     * the exception will be thrown.
+     */
+    protected abstract void send(DatagramPacket p) throws IOException;
+
+    /**
+     * Connects a datagram socket to a remote destination. This associates the remote
+     * address with the local socket so that datagrams may only be sent to this destination
+     * and received from this destination. This may be overridden to call a native
+     * system connect.
+     *
+     * <p>If the remote destination to which the socket is connected does not
+     * exist, or is otherwise unreachable, and if an ICMP destination unreachable
+     * packet has been received for that address, then a subsequent call to
+     * send or receive may throw a PortUnreachableException.
+     * Note, there is no guarantee that the exception will be thrown.
+     * @param address the remote InetAddress to connect to
+     * @param port the remote port number
+     * @exception   SocketException may be thrown if the socket cannot be
+     * connected to the remote destination
+     * @since 1.4
+     */
+    protected void connect(InetAddress address, int port) throws SocketException {}
+
+    /**
+     * Disconnects a datagram socket from its remote destination.
+     * @since 1.4
+     */
+    protected void disconnect() {}
+
+    /**
+     * Peek at the packet to see who it is from. Updates the specified {@code InetAddress}
+     * to the address which the packet came from.
+     * @param i an InetAddress object
+     * @return the port number which the packet came from.
+     * @exception IOException if an I/O exception occurs
+     * @exception  PortUnreachableException may be thrown if the socket is connected
+     *       to a currently unreachable destination. Note, there is no guarantee that the
+     *       exception will be thrown.
+     */
+    protected abstract int peek(InetAddress i) throws IOException;
+
+    /**
+     * Peek at the packet to see who it is from. The data is copied into the specified
+     * {@code DatagramPacket}. The data is returned,
+     * but not consumed, so that a subsequent peekData/receive operation
+     * will see the same data.
+     * @param p the Packet Received.
+     * @return the port number which the packet came from.
+     * @exception IOException if an I/O exception occurs
+     * @exception  PortUnreachableException may be thrown if the socket is connected
+     *       to a currently unreachable destination. Note, there is no guarantee that the
+     *       exception will be thrown.
+     * @since 1.4
+     */
+    protected abstract int peekData(DatagramPacket p) throws IOException;
+    /**
+     * Receive the datagram packet.
+     * @param p the Packet Received.
+     * @exception IOException if an I/O exception occurs
+     * while receiving the datagram packet.
+     * @exception  PortUnreachableException may be thrown if the socket is connected
+     *       to a currently unreachable destination. Note, there is no guarantee that the
+     *       exception will be thrown.
+     */
+    protected abstract void receive(DatagramPacket p) throws IOException;
+
+    /**
+     * Set the TTL (time-to-live) option.
+     * @param ttl a byte specifying the TTL value
+     *
+     * @deprecated use setTimeToLive instead.
+     * @exception IOException if an I/O exception occurs while setting
+     * the time-to-live option.
+     * @see #getTTL()
+     */
+    @Deprecated
+    protected abstract void setTTL(byte ttl) throws IOException;
+
+    /**
+     * Retrieve the TTL (time-to-live) option.
+     *
+     * @exception IOException if an I/O exception occurs
+     * while retrieving the time-to-live option
+     * @deprecated use getTimeToLive instead.
+     * @return a byte representing the TTL value
+     * @see #setTTL(byte)
+     */
+    @Deprecated
+    protected abstract byte getTTL() throws IOException;
+
+    /**
+     * Set the TTL (time-to-live) option.
+     * @param ttl an {@code int} specifying the time-to-live value
+     * @exception IOException if an I/O exception occurs
+     * while setting the time-to-live option.
+     * @see #getTimeToLive()
+     */
+    protected abstract void setTimeToLive(int ttl) throws IOException;
+
+    /**
+     * Retrieve the TTL (time-to-live) option.
+     * @exception IOException if an I/O exception occurs
+     * while retrieving the time-to-live option
+     * @return an {@code int} representing the time-to-live value
+     * @see #setTimeToLive(int)
+     */
+    protected abstract int getTimeToLive() throws IOException;
+
+    /**
+     * Join the multicast group.
+     * @param inetaddr multicast address to join.
+     * @exception IOException if an I/O exception occurs
+     * while joining the multicast group.
+     */
+    protected abstract void join(InetAddress inetaddr) throws IOException;
+
+    /**
+     * Leave the multicast group.
+     * @param inetaddr multicast address to leave.
+     * @exception IOException if an I/O exception occurs
+     * while leaving the multicast group.
+     */
+    protected abstract void leave(InetAddress inetaddr) throws IOException;
+
+    /**
+     * Join the multicast group.
+     * @param mcastaddr address to join.
+     * @param netIf specifies the local interface to receive multicast
+     *        datagram packets
+     * @throws IOException if an I/O exception occurs while joining
+     * the multicast group
+     * @since 1.4
+     */
+    protected abstract void joinGroup(SocketAddress mcastaddr,
+                                      NetworkInterface netIf)
+        throws IOException;
+
+    /**
+     * Leave the multicast group.
+     * @param mcastaddr address to leave.
+     * @param netIf specified the local interface to leave the group at
+     * @throws IOException if an I/O exception occurs while leaving
+     * the multicast group
+     * @since 1.4
+     */
+    protected abstract void leaveGroup(SocketAddress mcastaddr,
+                                       NetworkInterface netIf)
+        throws IOException;
+
+    /**
+     * Close the socket.
+     */
+    protected abstract void close();
+
+    /**
+     * Gets the local port.
+     * @return an {@code int} representing the local port value
+     */
+    protected int getLocalPort() {
+        return localPort;
+    }
+
+    <T> void setOption(SocketOption<T> name, T value) throws IOException {
+        if (name == StandardSocketOptions.SO_SNDBUF) {
+            setOption(SocketOptions.SO_SNDBUF, value);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            setOption(SocketOptions.SO_RCVBUF, value);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            setOption(SocketOptions.SO_REUSEADDR, value);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            setOption(SocketOptions.IP_TOS, value);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
+            (getDatagramSocket() instanceof MulticastSocket)) {
+            setOption(SocketOptions.IP_MULTICAST_IF2, value);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_TTL &&
+            (getDatagramSocket() instanceof MulticastSocket)) {
+            if (! (value instanceof Integer)) {
+                throw new IllegalArgumentException("not an integer");
+            }
+            setTimeToLive((Integer)value);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP &&
+            (getDatagramSocket() instanceof MulticastSocket)) {
+            setOption(SocketOptions.IP_MULTICAST_LOOP, value);
+        } else {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+    }
+
+    <T> T getOption(SocketOption<T> name) throws IOException {
+        if (name == StandardSocketOptions.SO_SNDBUF) {
+            return (T) getOption(SocketOptions.SO_SNDBUF);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            return (T) getOption(SocketOptions.SO_RCVBUF);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            return (T) getOption(SocketOptions.SO_REUSEADDR);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            return (T) getOption(SocketOptions.IP_TOS);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_IF &&
+            (getDatagramSocket() instanceof MulticastSocket)) {
+            return (T) getOption(SocketOptions.IP_MULTICAST_IF2);
+        } else if (name == StandardSocketOptions.IP_MULTICAST_TTL &&
+            (getDatagramSocket() instanceof MulticastSocket)) {
+            Integer ttl = getTimeToLive();
+            return (T)ttl;
+        } else if (name == StandardSocketOptions.IP_MULTICAST_LOOP &&
+            (getDatagramSocket() instanceof MulticastSocket)) {
+            return (T) getOption(SocketOptions.IP_MULTICAST_LOOP);
+        } else {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+    }
+
+    /**
+     * Gets the datagram socket file descriptor.
+     * @return a {@code FileDescriptor} object representing the datagram socket
+     * file descriptor
+     */
+    protected FileDescriptor getFileDescriptor() {
+        return fd;
+    }
+}
diff --git a/java/net/DatagramSocketImplFactory.java b/java/net/DatagramSocketImplFactory.java
new file mode 100644
index 0000000..4d89196
--- /dev/null
+++ b/java/net/DatagramSocketImplFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This interface defines a factory for datagram socket implementations. It
+ * is used by the classes {@code DatagramSocket} to create actual socket
+ * implementations.
+ *
+ * @author  Yingxian Wang
+ * @see     java.net.DatagramSocket
+ * @since   1.3
+ */
+public
+interface DatagramSocketImplFactory {
+    /**
+     * Creates a new {@code DatagramSocketImpl} instance.
+     *
+     * @return  a new instance of {@code DatagramSocketImpl}.
+     * @see     java.net.DatagramSocketImpl
+     */
+    DatagramSocketImpl createDatagramSocketImpl();
+}
diff --git a/java/net/DefaultDatagramSocketImplFactory.java b/java/net/DefaultDatagramSocketImplFactory.java
new file mode 100644
index 0000000..ad62c58
--- /dev/null
+++ b/java/net/DefaultDatagramSocketImplFactory.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2007,2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+import java.security.AccessController;
+
+/**
+ * This class defines a factory for creating DatagramSocketImpls. It defaults
+ * to creating plain DatagramSocketImpls, but may create other DatagramSocketImpls
+ * by setting the impl.prefix system property.
+ *
+ * @author Chris Hegarty
+ */
+
+class DefaultDatagramSocketImplFactory {
+    static Class<?> prefixImplClass = null;
+
+    static {
+        String prefix = null;
+        try {
+            prefix = AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction("impl.prefix", null));
+            if (prefix != null)
+                prefixImplClass = Class.forName("java.net."+prefix+"DatagramSocketImpl");
+        } catch (Exception e) {
+            System.err.println("Can't find class: java.net." +
+                                prefix +
+                                "DatagramSocketImpl: check impl.prefix property");
+            //prefixImplClass = null;
+        }
+    }
+
+    /**
+     * Creates a new <code>DatagramSocketImpl</code> instance.
+     *
+     * @param   isMulticast     true if this impl if for a MutlicastSocket
+     * @return  a new instance of a <code>DatagramSocketImpl</code>.
+     */
+    static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast /*unused on unix*/)
+        throws SocketException {
+        if (prefixImplClass != null) {
+            try {
+                return (DatagramSocketImpl)prefixImplClass.newInstance();
+            } catch (Exception e) {
+                throw new SocketException("can't instantiate DatagramSocketImpl");
+            }
+        } else {
+            return new java.net.PlainDatagramSocketImpl();
+        }
+    }
+}
diff --git a/java/net/DefaultFileNameMap.java b/java/net/DefaultFileNameMap.java
new file mode 100644
index 0000000..da67d14
--- /dev/null
+++ b/java/net/DefaultFileNameMap.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package java.net;
+
+import libcore.content.type.MimeMap;
+
+/**
+ * Implements {@link FileNameMap} in terms of {@link MimeMap}.
+ */
+class DefaultFileNameMap implements FileNameMap {
+
+    public String getContentTypeFor(String filename) {
+        int fragmentIndex = filename.indexOf('#');
+        if (fragmentIndex >= 0) {
+            filename = filename.substring(0, fragmentIndex);
+        }
+        if (filename.endsWith("/")) { // a directory
+            return "text/html";
+        }
+
+        int slashIndex = filename.lastIndexOf('/');
+        if (slashIndex >= 0) {
+            filename = filename.substring(slashIndex);
+        }
+
+        MimeMap mimeMap = MimeMap.getDefault();
+        int dotIndex = -1;
+        do {
+            String ext = filename.substring(dotIndex + 1);
+            String result = mimeMap.guessMimeTypeFromExtension(ext);
+            if ((result != null) &&
+                    // Compat behavior: If there's a '/', then extension must not be the
+                    // whole string. http://b/144977800
+                    (slashIndex < 0 || dotIndex >= 0)) {
+                return result;
+            }
+            dotIndex = filename.indexOf('.', dotIndex + 1);
+        } while (dotIndex >= 0);
+        return null;
+    }
+}
diff --git a/java/net/DefaultInterface.java b/java/net/DefaultInterface.java
new file mode 100644
index 0000000..0c31cb6
--- /dev/null
+++ b/java/net/DefaultInterface.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Choose a network interface to be the default for
+ * outgoing IPv6 traffic that does not specify a scope_id (and which needs one).
+ *
+ * Platforms that do not require a default interface may return null
+ * which is what this implementation does.
+ */
+
+class DefaultInterface {
+
+    static NetworkInterface getDefault() {
+        return null;
+    }
+}
diff --git a/java/net/FileNameMap.java b/java/net/FileNameMap.java
new file mode 100644
index 0000000..393b5aa
--- /dev/null
+++ b/java/net/FileNameMap.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * A simple interface which provides a mechanism to map
+ * between a file name and a MIME type string.
+ *
+ * @author  Steven B. Byrne
+ * @since   JDK1.1
+ */
+public interface FileNameMap {
+
+    /**
+     * Gets the MIME type for the specified file name.
+     * @param fileName the specified file name
+     * @return a {@code String} indicating the MIME
+     * type for the specified file name.
+     */
+    public String getContentTypeFor(String fileName);
+}
diff --git a/java/net/HttpCookie.java b/java/net/HttpCookie.java
new file mode 100644
index 0000000..3ff33c7
--- /dev/null
+++ b/java/net/HttpCookie.java
@@ -0,0 +1,1213 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
+import libcore.net.http.HttpDate;
+
+/**
+ * An HttpCookie object represents an HTTP cookie, which carries state
+ * information between server and user agent. Cookie is widely adopted
+ * to create stateful sessions.
+ *
+ * <p> There are 3 HTTP cookie specifications:
+ * <blockquote>
+ *   Netscape draft<br>
+ *   RFC 2109 - <a href="http://www.ietf.org/rfc/rfc2109.txt">
+ * <i>http://www.ietf.org/rfc/rfc2109.txt</i></a><br>
+ *   RFC 2965 - <a href="http://www.ietf.org/rfc/rfc2965.txt">
+ * <i>http://www.ietf.org/rfc/rfc2965.txt</i></a>
+ * </blockquote>
+ *
+ * <p> HttpCookie class can accept all these 3 forms of syntax.
+ *
+ * @author Edward Wang
+ * @since 1.6
+ */
+public final class HttpCookie implements Cloneable {
+    // BEGIN Android-added: Reserved name can't be HttpCookie name
+    private static final Set<String> RESERVED_NAMES = new HashSet<String>();
+
+    static {
+        RESERVED_NAMES.add("comment");    //           RFC 2109  RFC 2965  RFC 6265
+        RESERVED_NAMES.add("commenturl"); //                     RFC 2965  RFC 6265
+        RESERVED_NAMES.add("discard");    //                     RFC 2965  RFC 6265
+        RESERVED_NAMES.add("domain");     // Netscape  RFC 2109  RFC 2965  RFC 6265
+        RESERVED_NAMES.add("expires");    // Netscape
+        RESERVED_NAMES.add("httponly");   //                               RFC 6265
+        RESERVED_NAMES.add("max-age");    //           RFC 2109  RFC 2965  RFC 6265
+        RESERVED_NAMES.add("path");       // Netscape  RFC 2109  RFC 2965  RFC 6265
+        RESERVED_NAMES.add("port");       //                     RFC 2965  RFC 6265
+        RESERVED_NAMES.add("secure");     // Netscape  RFC 2109  RFC 2965  RFC 6265
+        RESERVED_NAMES.add("version");    //           RFC 2109  RFC 2965  RFC 6265
+    }
+    // END Android-added: Reserved name can't be HttpCookie name
+
+    // ---------------- Fields --------------
+
+    // The value of the cookie itself.
+    private final String name;  // NAME= ... "$Name" style is reserved
+    private String value;       // value of NAME
+
+    // Attributes encoded in the header's cookie fields.
+    private String comment;     // Comment=VALUE ... describes cookie's use
+    private String commentURL;  // CommentURL="http URL" ... describes cookie's use
+    private boolean toDiscard;  // Discard ... discard cookie unconditionally
+    private String domain;      // Domain=VALUE ... domain that sees cookie
+    private long maxAge = MAX_AGE_UNSPECIFIED;  // Max-Age=VALUE ... cookies auto-expire
+    private String path;        // Path=VALUE ... URLs that see the cookie
+    private String portlist;    // Port[="portlist"] ... the port cookie may be returned to
+    private boolean secure;     // Secure ... e.g. use SSL
+    private boolean httpOnly;   // HttpOnly ... i.e. not accessible to scripts
+    private int version = 1;    // Version=1 ... RFC 2965 style
+
+    // The original header this cookie was consructed from, if it was
+    // constructed by parsing a header, otherwise null.
+    private final String header;
+
+    //
+    // Android-changed: Fixed units, s/seconds/milliseconds/, in comment below.
+    // Hold the creation time (in milliseconds) of the http cookie for later
+    // expiration calculation
+    private final long whenCreated;
+
+    // Since the positive and zero max-age have their meanings,
+    // this value serves as a hint as 'not specify max-age'
+    private final static long MAX_AGE_UNSPECIFIED = -1;
+
+    // BEGIN Android-removed: Use libcore.net.http.HttpDate for parsing.
+    // date formats used by Netscape's cookie draft
+    // as well as formats seen on various sites
+    /*
+    private final static String[] COOKIE_DATE_FORMATS = {
+        "EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'",
+        "EEE',' dd MMM yyyy HH:mm:ss 'GMT'",
+        "EEE MMM dd yyyy HH:mm:ss 'GMT'Z",
+        "EEE',' dd-MMM-yy HH:mm:ss 'GMT'",
+        "EEE',' dd MMM yy HH:mm:ss 'GMT'",
+        "EEE MMM dd yy HH:mm:ss 'GMT'Z"
+    };
+    */
+    // END Android-removed: Use libcore.net.http.HttpDate for parsing.
+
+    // constant strings represent set-cookie header token
+    private final static String SET_COOKIE = "set-cookie:";
+    private final static String SET_COOKIE2 = "set-cookie2:";
+
+    // ---------------- Ctors --------------
+
+    /**
+     * Constructs a cookie with a specified name and value.
+     *
+     * <p> The name must conform to RFC 2965. That means it can contain
+     * only ASCII alphanumeric characters and cannot contain commas,
+     * semicolons, or white space or begin with a $ character. The cookie's
+     * name cannot be changed after creation.
+     *
+     * <p> The value can be anything the server chooses to send. Its
+     * value is probably of interest only to the server. The cookie's
+     * value can be changed after creation with the
+     * {@code setValue} method.
+     *
+     * <p> By default, cookies are created according to the RFC 2965
+     * cookie specification. The version can be changed with the
+     * {@code setVersion} method.
+     *
+     *
+     * @param  name
+     *         a {@code String} specifying the name of the cookie
+     *
+     * @param  value
+     *         a {@code String} specifying the value of the cookie
+     *
+     * @throws  IllegalArgumentException
+     *          if the cookie name contains illegal characters
+     * @throws  NullPointerException
+     *          if {@code name} is {@code null}
+     *
+     * @see #setValue
+     * @see #setVersion
+     */
+    public HttpCookie(String name, String value) {
+        this(name, value, null /*header*/);
+    }
+
+    private HttpCookie(String name, String value, String header) {
+        name = name.trim();
+        if (name.length() == 0 || !isToken(name) || name.charAt(0) == '$') {
+            throw new IllegalArgumentException("Illegal cookie name");
+        }
+
+        this.name = name;
+        this.value = value;
+        toDiscard = false;
+        secure = false;
+
+        whenCreated = System.currentTimeMillis();
+        portlist = null;
+        this.header = header;
+    }
+
+    /**
+     * Constructs cookies from set-cookie or set-cookie2 header string.
+     * RFC 2965 section 3.2.2 set-cookie2 syntax indicates that one header line
+     * may contain more than one cookie definitions, so this is a static
+     * utility method instead of another constructor.
+     *
+     * @param  header
+     *         a {@code String} specifying the set-cookie header. The header
+     *         should start with "set-cookie", or "set-cookie2" token; or it
+     *         should have no leading token at all.
+     *
+     * @return  a List of cookie parsed from header line string
+     *
+     * @throws  IllegalArgumentException
+     *          if header string violates the cookie specification's syntax or
+     *          the cookie name contains illegal characters.
+     * @throws  NullPointerException
+     *          if the header string is {@code null}
+     */
+    public static List<HttpCookie> parse(String header) {
+        return parse(header, false);
+    }
+
+    // Private version of parse() that will store the original header used to
+    // create the cookie, in the cookie itself. This can be useful for filtering
+    // Set-Cookie[2] headers, using the internal parsing logic defined in this
+    // class.
+    private static List<HttpCookie> parse(String header, boolean retainHeader) {
+
+        int version = guessCookieVersion(header);
+
+        // if header start with set-cookie or set-cookie2, strip it off
+        if (startsWithIgnoreCase(header, SET_COOKIE2)) {
+            header = header.substring(SET_COOKIE2.length());
+        } else if (startsWithIgnoreCase(header, SET_COOKIE)) {
+            header = header.substring(SET_COOKIE.length());
+        }
+
+        List<HttpCookie> cookies = new java.util.ArrayList<>();
+        // The Netscape cookie may have a comma in its expires attribute, while
+        // the comma is the delimiter in rfc 2965/2109 cookie header string.
+        // so the parse logic is slightly different
+        if (version == 0) {
+            // Netscape draft cookie
+            HttpCookie cookie = parseInternal(header, retainHeader);
+            cookie.setVersion(0);
+            cookies.add(cookie);
+        } else {
+            // rfc2965/2109 cookie
+            // if header string contains more than one cookie,
+            // it'll separate them with comma
+            List<String> cookieStrings = splitMultiCookies(header);
+            for (String cookieStr : cookieStrings) {
+                HttpCookie cookie = parseInternal(cookieStr, retainHeader);
+                cookie.setVersion(1);
+                cookies.add(cookie);
+            }
+        }
+
+        return cookies;
+    }
+
+    // ---------------- Public operations --------------
+
+    /**
+     * Reports whether this HTTP cookie has expired or not.
+     *
+     * @return  {@code true} to indicate this HTTP cookie has expired;
+     *          otherwise, {@code false}
+     */
+    public boolean hasExpired() {
+        if (maxAge == 0) return true;
+
+        // if not specify max-age, this cookie should be
+        // discarded when user agent is to be closed, but
+        // it is not expired.
+        if (maxAge == MAX_AGE_UNSPECIFIED) return false;
+
+        long deltaSecond = (System.currentTimeMillis() - whenCreated) / 1000;
+        if (deltaSecond > maxAge)
+            return true;
+        else
+            return false;
+    }
+
+    /**
+     * Specifies a comment that describes a cookie's purpose.
+     * The comment is useful if the browser presents the cookie
+     * to the user. Comments are not supported by Netscape Version 0 cookies.
+     *
+     * @param  purpose
+     *         a {@code String} specifying the comment to display to the user
+     *
+     * @see  #getComment
+     */
+    public void setComment(String purpose) {
+        comment = purpose;
+    }
+
+    /**
+     * Returns the comment describing the purpose of this cookie, or
+     * {@code null} if the cookie has no comment.
+     *
+     * @return  a {@code String} containing the comment, or {@code null} if none
+     *
+     * @see  #setComment
+     */
+    public String getComment() {
+        return comment;
+    }
+
+    /**
+     * Specifies a comment URL that describes a cookie's purpose.
+     * The comment URL is useful if the browser presents the cookie
+     * to the user. Comment URL is RFC 2965 only.
+     *
+     * @param  purpose
+     *         a {@code String} specifying the comment URL to display to the user
+     *
+     * @see  #getCommentURL
+     */
+    public void setCommentURL(String purpose) {
+        commentURL = purpose;
+    }
+
+    /**
+     * Returns the comment URL describing the purpose of this cookie, or
+     * {@code null} if the cookie has no comment URL.
+     *
+     * @return  a {@code String} containing the comment URL, or {@code null}
+     *          if none
+     *
+     * @see  #setCommentURL
+     */
+    public String getCommentURL() {
+        return commentURL;
+    }
+
+    /**
+     * Specify whether user agent should discard the cookie unconditionally.
+     * This is RFC 2965 only attribute.
+     *
+     * @param  discard
+     *         {@code true} indicates to discard cookie unconditionally
+     *
+     * @see  #getDiscard
+     */
+    public void setDiscard(boolean discard) {
+        toDiscard = discard;
+    }
+
+    /**
+     * Returns the discard attribute of the cookie
+     *
+     * @return  a {@code boolean} to represent this cookie's discard attribute
+     *
+     * @see  #setDiscard
+     */
+    public boolean getDiscard() {
+        return toDiscard;
+    }
+
+    /**
+     * Specify the portlist of the cookie, which restricts the port(s)
+     * to which a cookie may be sent back in a Cookie header.
+     *
+     * @param  ports
+     *         a {@code String} specify the port list, which is comma separated
+     *         series of digits
+     *
+     * @see  #getPortlist
+     */
+    public void setPortlist(String ports) {
+        portlist = ports;
+    }
+
+    /**
+     * Returns the port list attribute of the cookie
+     *
+     * @return  a {@code String} contains the port list or {@code null} if none
+     *
+     * @see  #setPortlist
+     */
+    public String getPortlist() {
+        return portlist;
+    }
+
+    /**
+     * Specifies the domain within which this cookie should be presented.
+     *
+     * <p> The form of the domain name is specified by RFC 2965. A domain
+     * name begins with a dot ({@code .foo.com}) and means that
+     * the cookie is visible to servers in a specified Domain Name System
+     * (DNS) zone (for example, {@code www.foo.com}, but not
+     * {@code a.b.foo.com}). By default, cookies are only returned
+     * to the server that sent them.
+     *
+     * @param  pattern
+     *         a {@code String} containing the domain name within which this
+     *         cookie is visible; form is according to RFC 2965
+     *
+     * @see  #getDomain
+     */
+    public void setDomain(String pattern) {
+        if (pattern != null)
+            domain = pattern.toLowerCase();
+        else
+            domain = pattern;
+    }
+
+    /**
+     * Returns the domain name set for this cookie. The form of the domain name
+     * is set by RFC 2965.
+     *
+     * @return  a {@code String} containing the domain name
+     *
+     * @see  #setDomain
+     */
+    public String getDomain() {
+        return domain;
+    }
+
+    /**
+     * Sets the maximum age of the cookie in seconds.
+     *
+     * <p> A positive value indicates that the cookie will expire
+     * after that many seconds have passed. Note that the value is
+     * the <i>maximum</i> age when the cookie will expire, not the cookie's
+     * current age.
+     *
+     * <p> A negative value means that the cookie is not stored persistently
+     * and will be deleted when the Web browser exits. A zero value causes the
+     * cookie to be deleted.
+     *
+     * @param  expiry
+     *         an integer specifying the maximum age of the cookie in seconds;
+     *         if zero, the cookie should be discarded immediately; otherwise,
+     *         the cookie's max age is unspecified.
+     *
+     * @see  #getMaxAge
+     */
+    public void setMaxAge(long expiry) {
+        maxAge = expiry;
+    }
+
+    /**
+     * Returns the maximum age of the cookie, specified in seconds. By default,
+     * {@code -1} indicating the cookie will persist until browser shutdown.
+     *
+     * @return  an integer specifying the maximum age of the cookie in seconds
+     *
+     * @see  #setMaxAge
+     */
+    public long getMaxAge() {
+        return maxAge;
+    }
+
+    /**
+     * Specifies a path for the cookie to which the client should return
+     * the cookie.
+     *
+     * <p> The cookie is visible to all the pages in the directory
+     * you specify, and all the pages in that directory's subdirectories.
+     * A cookie's path must include the servlet that set the cookie,
+     * for example, <i>/catalog</i>, which makes the cookie
+     * visible to all directories on the server under <i>/catalog</i>.
+     *
+     * <p> Consult RFC 2965 (available on the Internet) for more
+     * information on setting path names for cookies.
+     *
+     * @param  uri
+     *         a {@code String} specifying a path
+     *
+     * @see  #getPath
+     */
+    public void setPath(String uri) {
+        path = uri;
+    }
+
+    /**
+     * Returns the path on the server to which the browser returns this cookie.
+     * The cookie is visible to all subpaths on the server.
+     *
+     * @return  a {@code String} specifying a path that contains a servlet name,
+     *          for example, <i>/catalog</i>
+     *
+     * @see  #setPath
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Indicates whether the cookie should only be sent using a secure protocol,
+     * such as HTTPS or SSL.
+     *
+     * <p> The default value is {@code false}.
+     *
+     * @param  flag
+     *         If {@code true}, the cookie can only be sent over a secure
+     *         protocol like HTTPS. If {@code false}, it can be sent over
+     *         any protocol.
+     *
+     * @see  #getSecure
+     */
+    public void setSecure(boolean flag) {
+        secure = flag;
+    }
+
+    /**
+     * Returns {@code true} if sending this cookie should be restricted to a
+     * secure protocol, or {@code false} if the it can be sent using any
+     * protocol.
+     *
+     * @return  {@code false} if the cookie can be sent over any standard
+     *          protocol; otherwise, {@code true}
+     *
+     * @see  #setSecure
+     */
+    public boolean getSecure() {
+        return secure;
+    }
+
+    /**
+     * Returns the name of the cookie. The name cannot be changed after
+     * creation.
+     *
+     * @return  a {@code String} specifying the cookie's name
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Assigns a new value to a cookie after the cookie is created.
+     * If you use a binary value, you may want to use BASE64 encoding.
+     *
+     * <p> With Version 0 cookies, values should not contain white space,
+     * brackets, parentheses, equals signs, commas, double quotes, slashes,
+     * question marks, at signs, colons, and semicolons. Empty values may not
+     * behave the same way on all browsers.
+     *
+     * @param  newValue
+     *         a {@code String} specifying the new value
+     *
+     * @see  #getValue
+     */
+    public void setValue(String newValue) {
+        value = newValue;
+    }
+
+    /**
+     * Returns the value of the cookie.
+     *
+     * @return  a {@code String} containing the cookie's present value
+     *
+     * @see  #setValue
+     */
+    public String getValue() {
+        return value;
+    }
+
+    /**
+     * Returns the version of the protocol this cookie complies with. Version 1
+     * complies with RFC 2965/2109, and version 0 complies with the original
+     * cookie specification drafted by Netscape. Cookies provided by a browser
+     * use and identify the browser's cookie version.
+     *
+     * @return  0 if the cookie complies with the original Netscape
+     *          specification; 1 if the cookie complies with RFC 2965/2109
+     *
+     * @see  #setVersion
+     */
+    public int getVersion() {
+        return version;
+    }
+
+    /**
+     * Sets the version of the cookie protocol this cookie complies
+     * with. Version 0 complies with the original Netscape cookie
+     * specification. Version 1 complies with RFC 2965/2109.
+     *
+     * @param  v
+     *         0 if the cookie should comply with the original Netscape
+     *         specification; 1 if the cookie should comply with RFC 2965/2109
+     *
+     * @throws  IllegalArgumentException
+     *          if {@code v} is neither 0 nor 1
+     *
+     * @see  #getVersion
+     */
+    public void setVersion(int v) {
+        if (v != 0 && v != 1) {
+            throw new IllegalArgumentException("cookie version should be 0 or 1");
+        }
+
+        version = v;
+    }
+
+    /**
+     * Returns {@code true} if this cookie contains the <i>HttpOnly</i>
+     * attribute. This means that the cookie should not be accessible to
+     * scripting engines, like javascript.
+     *
+     * @return  {@code true} if this cookie should be considered HTTPOnly
+     *
+     * @see  #setHttpOnly(boolean)
+     */
+    public boolean isHttpOnly() {
+        return httpOnly;
+    }
+
+    /**
+     * Indicates whether the cookie should be considered HTTP Only. If set to
+     * {@code true} it means the cookie should not be accessible to scripting
+     * engines like javascript.
+     *
+     * @param  httpOnly
+     *         if {@code true} make the cookie HTTP only, i.e. only visible as
+     *         part of an HTTP request.
+     *
+     * @see  #isHttpOnly()
+     */
+    public void setHttpOnly(boolean httpOnly) {
+        this.httpOnly = httpOnly;
+    }
+
+    /**
+     * The utility method to check whether a host name is in a domain or not.
+     *
+     * <p> This concept is described in the cookie specification.
+     * To understand the concept, some terminologies need to be defined first:
+     * <blockquote>
+     * effective host name = hostname if host name contains dot<br>
+     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+     * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or = hostname.local if not
+     * </blockquote>
+     * <p>Host A's name domain-matches host B's if:
+     * <blockquote><ul>
+     *   <li>their host name strings string-compare equal; or</li>
+     *   <li>A is a HDN string and has the form NB, where N is a non-empty
+     *   name string, B has the form .B', and B' is a HDN string.  (So,
+     *   x.y.com domain-matches .Y.com but not Y.com.)</li>
+     * </ul></blockquote>
+     *
+     * <p>A host isn't in a domain (RFC 2965 sec. 3.3.2) if:
+     * <blockquote><ul>
+     *   <li>The value for the Domain attribute contains no embedded dots,
+     *   and the value is not .local.</li>
+     *   <li>The effective host name that derives from the request-host does
+     *   not domain-match the Domain attribute.</li>
+     *   <li>The request-host is a HDN (not IP address) and has the form HD,
+     *   where D is the value of the Domain attribute, and H is a string
+     *   that contains one or more dots.</li>
+     * </ul></blockquote>
+     *
+     * <p>Examples:
+     * <blockquote><ul>
+     *   <li>A Set-Cookie2 from request-host y.x.foo.com for Domain=.foo.com
+     *   would be rejected, because H is y.x and contains a dot.</li>
+     *   <li>A Set-Cookie2 from request-host x.foo.com for Domain=.foo.com
+     *   would be accepted.</li>
+     *   <li>A Set-Cookie2 with Domain=.com or Domain=.com., will always be
+     *   rejected, because there is no embedded dot.</li>
+     *   <li>A Set-Cookie2 from request-host example for Domain=.local will
+     *   be accepted, because the effective host name for the request-
+     *   host is example.local, and example.local domain-matches .local.</li>
+     * </ul></blockquote>
+     *
+     * @param  domain
+     *         the domain name to check host name with
+     *
+     * @param  host
+     *         the host name in question
+     *
+     * @return  {@code true} if they domain-matches; {@code false} if not
+     */
+    public static boolean domainMatches(String domain, String host) {
+        if (domain == null || host == null)
+            return false;
+
+        // if there's no embedded dot in domain and domain is not .local
+        boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
+        int embeddedDotInDomain = domain.indexOf('.');
+        if (embeddedDotInDomain == 0)
+            embeddedDotInDomain = domain.indexOf('.', 1);
+        if (!isLocalDomain
+            && (embeddedDotInDomain == -1 ||
+                embeddedDotInDomain == domain.length() - 1))
+            return false;
+
+        // if the host name contains no dot and the domain name
+        // is .local or host.local
+        int firstDotInHost = host.indexOf('.');
+        if (firstDotInHost == -1 &&
+            (isLocalDomain ||
+             domain.equalsIgnoreCase(host + ".local"))) {
+            return true;
+        }
+
+        int domainLength = domain.length();
+        int lengthDiff = host.length() - domainLength;
+        if (lengthDiff == 0) {
+            // if the host name and the domain name are just string-compare euqal
+            return host.equalsIgnoreCase(domain);
+        }
+        else if (lengthDiff > 0) {
+            // need to check H & D component
+            String H = host.substring(0, lengthDiff);
+            String D = host.substring(lengthDiff);
+
+            // BEGIN Android-changed: App compat reason
+            // 1) Disregard RFC 2965 sec. 3.3.2, the "The request-host is a HDN..."
+            // 2) match "foo.local" for domain ".local".
+            // return (H.indexOf('.') == -1 && D.equalsIgnoreCase(domain));
+            return D.equalsIgnoreCase(domain) && ((domain.startsWith(".") && isFullyQualifiedDomainName(domain, 1))
+                || isLocalDomain);
+            // END Android-changed: App compat reason
+        }
+        else if (lengthDiff == -1) {
+            // if domain is actually .host
+            return (domain.charAt(0) == '.' &&
+                        host.equalsIgnoreCase(domain.substring(1)));
+        }
+
+        return false;
+    }
+
+    // BEGIN Android-added: App compat reason
+    private static boolean isFullyQualifiedDomainName(String s, int firstCharacter) {
+        int dotPosition = s.indexOf('.', firstCharacter + 1);
+        return dotPosition != -1 && dotPosition < s.length() - 1;
+    }
+    // END Android-added: App compat reason
+
+    /**
+     * Constructs a cookie header string representation of this cookie,
+     * which is in the format defined by corresponding cookie specification,
+     * but without the leading "Cookie:" token.
+     *
+     * @return  a string form of the cookie. The string has the defined format
+     */
+    @Override
+    public String toString() {
+        if (getVersion() > 0) {
+            return toRFC2965HeaderString();
+        } else {
+            return toNetscapeHeaderString();
+        }
+    }
+
+    /**
+     * Test the equality of two HTTP cookies.
+     *
+     * <p> The result is {@code true} only if two cookies come from same domain
+     * (case-insensitive), have same name (case-insensitive), and have same path
+     * (case-sensitive).
+     *
+     * @return  {@code true} if two HTTP cookies equal to each other;
+     *          otherwise, {@code false}
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this)
+            return true;
+        if (!(obj instanceof HttpCookie))
+            return false;
+        HttpCookie other = (HttpCookie)obj;
+
+        // One http cookie equals to another cookie (RFC 2965 sec. 3.3.3) if:
+        //   1. they come from same domain (case-insensitive),
+        //   2. have same name (case-insensitive),
+        //   3. and have same path (case-sensitive).
+        return equalsIgnoreCase(getName(), other.getName()) &&
+               equalsIgnoreCase(getDomain(), other.getDomain()) &&
+               Objects.equals(getPath(), other.getPath());
+    }
+
+    /**
+     * Returns the hash code of this HTTP cookie. The result is the sum of
+     * hash code value of three significant components of this cookie: name,
+     * domain, and path. That is, the hash code is the value of the expression:
+     * <blockquote>
+     * getName().toLowerCase().hashCode()<br>
+     * + getDomain().toLowerCase().hashCode()<br>
+     * + getPath().hashCode()
+     * </blockquote>
+     *
+     * @return  this HTTP cookie's hash code
+     */
+    @Override
+    public int hashCode() {
+        int h1 = name.toLowerCase().hashCode();
+        int h2 = (domain!=null) ? domain.toLowerCase().hashCode() : 0;
+        int h3 = (path!=null) ? path.hashCode() : 0;
+
+        return h1 + h2 + h3;
+    }
+
+    /**
+     * Create and return a copy of this object.
+     *
+     * @return  a clone of this HTTP cookie
+     */
+    @Override
+    public Object clone() {
+        try {
+            return super.clone();
+        } catch (CloneNotSupportedException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    // ---------------- Private operations --------------
+
+    // Note -- disabled for now to allow full Netscape compatibility
+    // from RFC 2068, token special case characters
+    //
+    // private static final String tspecials = "()<>@,;:\\\"/[]?={} \t";
+    // Android-changed: App compat reason. Disallow "=\t" as token
+    // private static final String tspecials = ",; ";  // deliberately includes space
+    private static final String tspecials = ",;= \t";
+
+    /*
+     * Tests a string and returns true if the string counts as a token.
+     *
+     * @param  value
+     *         the {@code String} to be tested
+     *
+     * @return  {@code true} if the {@code String} is a token;
+     *          {@code false} if it is not
+     */
+    private static boolean isToken(String value) {
+        // Android-added: Reserved name can't be a token
+        if (RESERVED_NAMES.contains(value.toLowerCase(Locale.US))) {
+            return false;
+        }
+
+        int len = value.length();
+
+        for (int i = 0; i < len; i++) {
+            char c = value.charAt(i);
+
+            if (c < 0x20 || c >= 0x7f || tspecials.indexOf(c) != -1)
+                return false;
+        }
+        return true;
+    }
+
+    /*
+     * Parse header string to cookie object.
+     *
+     * @param  header
+     *         header string; should contain only one NAME=VALUE pair
+     *
+     * @return  an HttpCookie being extracted
+     *
+     * @throws  IllegalArgumentException
+     *          if header string violates the cookie specification
+     */
+    private static HttpCookie parseInternal(String header,
+                                            boolean retainHeader)
+    {
+        HttpCookie cookie = null;
+        String namevaluePair = null;
+
+        StringTokenizer tokenizer = new StringTokenizer(header, ";");
+
+        // there should always have at least on name-value pair;
+        // it's cookie's name
+        try {
+            namevaluePair = tokenizer.nextToken();
+            int index = namevaluePair.indexOf('=');
+            if (index != -1) {
+                String name = namevaluePair.substring(0, index).trim();
+                String value = namevaluePair.substring(index + 1).trim();
+                if (retainHeader)
+                    cookie = new HttpCookie(name,
+                                            stripOffSurroundingQuote(value),
+                                            header);
+                else
+                    cookie = new HttpCookie(name,
+                                            stripOffSurroundingQuote(value));
+            } else {
+                // no "=" in name-value pair; it's an error
+                throw new IllegalArgumentException("Invalid cookie name-value pair");
+            }
+        } catch (NoSuchElementException ignored) {
+            throw new IllegalArgumentException("Empty cookie header string");
+        }
+
+        // remaining name-value pairs are cookie's attributes
+        while (tokenizer.hasMoreTokens()) {
+            namevaluePair = tokenizer.nextToken();
+            int index = namevaluePair.indexOf('=');
+            String name, value;
+            if (index != -1) {
+                name = namevaluePair.substring(0, index).trim();
+                value = namevaluePair.substring(index + 1).trim();
+            } else {
+                name = namevaluePair.trim();
+                value = null;
+            }
+
+            // assign attribute to cookie
+            assignAttribute(cookie, name, value);
+        }
+
+        return cookie;
+    }
+
+    /*
+     * assign cookie attribute value to attribute name;
+     * use a map to simulate method dispatch
+     */
+    static interface CookieAttributeAssignor {
+            public void assign(HttpCookie cookie,
+                               String attrName,
+                               String attrValue);
+    }
+    static final java.util.Map<String, CookieAttributeAssignor> assignors =
+            new java.util.HashMap<>();
+    static {
+        assignors.put("comment", new CookieAttributeAssignor() {
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    if (cookie.getComment() == null)
+                        cookie.setComment(attrValue);
+                }
+            });
+        assignors.put("commenturl", new CookieAttributeAssignor() {
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    if (cookie.getCommentURL() == null)
+                        cookie.setCommentURL(attrValue);
+                }
+            });
+        assignors.put("discard", new CookieAttributeAssignor() {
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    cookie.setDiscard(true);
+                }
+            });
+        assignors.put("domain", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    if (cookie.getDomain() == null)
+                        cookie.setDomain(attrValue);
+                }
+            });
+        assignors.put("max-age", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    try {
+                        long maxage = Long.parseLong(attrValue);
+                        if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED)
+                            cookie.setMaxAge(maxage);
+                    } catch (NumberFormatException ignored) {
+                        throw new IllegalArgumentException(
+                                "Illegal cookie max-age attribute");
+                    }
+                }
+            });
+        assignors.put("path", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    if (cookie.getPath() == null)
+                        cookie.setPath(attrValue);
+                }
+            });
+        assignors.put("port", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    if (cookie.getPortlist() == null)
+                        cookie.setPortlist(attrValue == null ? "" : attrValue);
+                }
+            });
+        assignors.put("secure", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    cookie.setSecure(true);
+                }
+            });
+        assignors.put("httponly", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    cookie.setHttpOnly(true);
+                }
+            });
+        assignors.put("version", new CookieAttributeAssignor(){
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    try {
+                        int version = Integer.parseInt(attrValue);
+                        cookie.setVersion(version);
+                    } catch (NumberFormatException ignored) {
+                        // Just ignore bogus version, it will default to 0 or 1
+                    }
+                }
+            });
+        assignors.put("expires", new CookieAttributeAssignor(){ // Netscape only
+                public void assign(HttpCookie cookie,
+                                   String attrName,
+                                   String attrValue) {
+                    if (cookie.getMaxAge() == MAX_AGE_UNSPECIFIED) {
+                        // BEGIN Android-changed: Use HttpDate for date parsing.
+                        // it accepts broader set of date formats.
+                        // cookie.setMaxAge(cookie.expiryDate2DeltaSeconds(attrValue));
+                        // Android-changed: Altered max age calculation to avoid setting
+                        // it to MAX_AGE_UNSPECIFIED (-1) if "expires" is one second in past.
+                        Date date = HttpDate.parse(attrValue);
+                        long maxAgeInSeconds = 0;
+                        if (date != null) {
+                            maxAgeInSeconds = (date.getTime() - cookie.whenCreated) / 1000;
+                            // Avoid MAX_AGE_UNSPECIFIED
+                            if (maxAgeInSeconds == MAX_AGE_UNSPECIFIED) {
+                                maxAgeInSeconds = 0;
+                            }
+                        }
+                        cookie.setMaxAge(maxAgeInSeconds);
+                        // END Android-changed: Use HttpDate for date parsing.
+                    }
+                }
+            });
+    }
+    private static void assignAttribute(HttpCookie cookie,
+                                        String attrName,
+                                        String attrValue)
+    {
+        // strip off the surrounding "-sign if there's any
+        attrValue = stripOffSurroundingQuote(attrValue);
+
+        CookieAttributeAssignor assignor = assignors.get(attrName.toLowerCase());
+        if (assignor != null) {
+            assignor.assign(cookie, attrName, attrValue);
+        } else {
+            // Ignore the attribute as per RFC 2965
+        }
+    }
+
+    // BEGIN Android-removed: Android doesn't use JavaNetHttpCookieAccess
+    /*
+    static {
+        sun.misc.SharedSecrets.setJavaNetHttpCookieAccess(
+            new sun.misc.JavaNetHttpCookieAccess() {
+                public List<HttpCookie> parse(String header) {
+                    return HttpCookie.parse(header, true);
+                }
+
+                public String header(HttpCookie cookie) {
+                    return cookie.header;
+                }
+            }
+        );
+    }
+    */
+    // END Android-removed: Android doesn't use JavaNetHttpCookieAccess
+
+    /*
+     * Returns the original header this cookie was consructed from, if it was
+     * constructed by parsing a header, otherwise null.
+     */
+    private String header() {
+        return header;
+    }
+
+    /*
+     * Constructs a string representation of this cookie. The string format is
+     * as Netscape spec, but without leading "Cookie:" token.
+     */
+    private String toNetscapeHeaderString() {
+        return getName() + "=" + getValue();
+    }
+
+    /*
+     * Constructs a string representation of this cookie. The string format is
+     * as RFC 2965/2109, but without leading "Cookie:" token.
+     */
+    private String toRFC2965HeaderString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append(getName()).append("=\"").append(getValue()).append('"');
+        if (getPath() != null)
+            sb.append(";$Path=\"").append(getPath()).append('"');
+        if (getDomain() != null)
+            sb.append(";$Domain=\"").append(getDomain()).append('"');
+        if (getPortlist() != null)
+            sb.append(";$Port=\"").append(getPortlist()).append('"');
+
+        return sb.toString();
+    }
+
+    static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+    // BEGIN Android-removed: not used.
+    /*
+     * @param  dateString
+     *         a date string in one of the formats defined in Netscape cookie spec
+     *
+     * @return  delta seconds between this cookie's creation time and the time
+     *          specified by dateString
+     *
+    private long expiryDate2DeltaSeconds(String dateString) {
+        Calendar cal = new GregorianCalendar(GMT);
+        for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
+            SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i],
+                                                       Locale.US);
+            cal.set(1970, 0, 1, 0, 0, 0);
+            df.setTimeZone(GMT);
+            df.setLenient(false);
+            df.set2DigitYearStart(cal.getTime());
+            try {
+                cal.setTime(df.parse(dateString));
+                if (!COOKIE_DATE_FORMATS[i].contains("yyyy")) {
+                    // 2-digit years following the standard set
+                    // out it rfc 6265
+                    int year = cal.get(Calendar.YEAR);
+                    year %= 100;
+                    if (year < 70) {
+                        year += 2000;
+                    } else {
+                        year += 1900;
+                    }
+                    cal.set(Calendar.YEAR, year);
+                }
+                return (cal.getTimeInMillis() - whenCreated) / 1000;
+            } catch (Exception e) {
+                // Ignore, try the next date format
+            }
+        }
+        return 0;
+    }
+    */
+    // END Android-removed: not used.
+
+    /*
+     * try to guess the cookie version through set-cookie header string
+     */
+    private static int guessCookieVersion(String header) {
+        int version = 0;
+
+        header = header.toLowerCase();
+        if (header.indexOf("expires=") != -1) {
+            // only netscape cookie using 'expires'
+            version = 0;
+        } else if (header.indexOf("version=") != -1) {
+            // version is mandatory for rfc 2965/2109 cookie
+            version = 1;
+        } else if (header.indexOf("max-age") != -1) {
+            // rfc 2965/2109 use 'max-age'
+            version = 1;
+        } else if (startsWithIgnoreCase(header, SET_COOKIE2)) {
+            // only rfc 2965 cookie starts with 'set-cookie2'
+            version = 1;
+        }
+
+        return version;
+    }
+
+    private static String stripOffSurroundingQuote(String str) {
+        if (str != null && str.length() > 2 &&
+            str.charAt(0) == '"' && str.charAt(str.length() - 1) == '"') {
+            return str.substring(1, str.length() - 1);
+        }
+        if (str != null && str.length() > 2 &&
+            str.charAt(0) == '\'' && str.charAt(str.length() - 1) == '\'') {
+            return str.substring(1, str.length() - 1);
+        }
+        return str;
+    }
+
+    private static boolean equalsIgnoreCase(String s, String t) {
+        if (s == t) return true;
+        if ((s != null) && (t != null)) {
+            return s.equalsIgnoreCase(t);
+        }
+        return false;
+    }
+
+    private static boolean startsWithIgnoreCase(String s, String start) {
+        if (s == null || start == null) return false;
+
+        if (s.length() >= start.length() &&
+                start.equalsIgnoreCase(s.substring(0, start.length()))) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /*
+     * Split cookie header string according to rfc 2965:
+     *   1) split where it is a comma;
+     *   2) but not the comma surrounding by double-quotes, which is the comma
+     *      inside port list or embeded URIs.
+     *
+     * @param  header
+     *         the cookie header string to split
+     *
+     * @return  list of strings; never null
+     */
+    private static List<String> splitMultiCookies(String header) {
+        List<String> cookies = new java.util.ArrayList<String>();
+        int quoteCount = 0;
+        int p, q;
+
+        for (p = 0, q = 0; p < header.length(); p++) {
+            char c = header.charAt(p);
+            if (c == '"') quoteCount++;
+            if (c == ',' && (quoteCount % 2 == 0)) {
+                // it is comma and not surrounding by double-quotes
+                cookies.add(header.substring(q, p));
+                q = p + 1;
+            }
+        }
+
+        cookies.add(header.substring(q));
+
+        return cookies;
+    }
+}
diff --git a/java/net/HttpRetryException.java b/java/net/HttpRetryException.java
new file mode 100644
index 0000000..d498a65
--- /dev/null
+++ b/java/net/HttpRetryException.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Thrown to indicate that a HTTP request needs to be retried
+ * but cannot be retried automatically, due to streaming mode
+ * being enabled.
+ *
+ * @author  Michael McMahon
+ * @since   1.5
+ */
+public
+class HttpRetryException extends IOException {
+    private static final long serialVersionUID = -9186022286469111381L;
+
+    private int responseCode;
+    private String location;
+
+    /**
+     * Constructs a new {@code HttpRetryException} from the
+     * specified response code and exception detail message
+     *
+     * @param   detail   the detail message.
+     * @param   code   the HTTP response code from server.
+     */
+    public HttpRetryException(String detail, int code) {
+        super(detail);
+        responseCode = code;
+    }
+
+    /**
+     * Constructs a new {@code HttpRetryException} with detail message
+     * responseCode and the contents of the Location response header field.
+     *
+     * @param   detail   the detail message.
+     * @param   code   the HTTP response code from server.
+     * @param   location   the URL to be redirected to
+     */
+    public HttpRetryException(String detail, int code, String location) {
+        super (detail);
+        responseCode = code;
+        this.location = location;
+    }
+
+    /**
+     * Returns the http response code
+     *
+     * @return  The http response code.
+     */
+    public int responseCode() {
+        return responseCode;
+    }
+
+    /**
+     * Returns a string explaining why the http request could
+     * not be retried.
+     *
+     * @return  The reason string
+     */
+    public String getReason() {
+        return super.getMessage();
+    }
+
+    /**
+     * Returns the value of the Location header field if the
+     * error resulted from redirection.
+     *
+     * @return The location string
+     */
+    public String getLocation() {
+        return location;
+    }
+}
diff --git a/java/net/HttpURLConnection.java b/java/net/HttpURLConnection.java
new file mode 100644
index 0000000..b72168b
--- /dev/null
+++ b/java/net/HttpURLConnection.java
@@ -0,0 +1,1023 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.security.Permission;
+import java.util.Date;
+
+// Android-changed: top-level documentation substantially changed/rewritten.
+/**
+ * A URLConnection with support for HTTP-specific features. See
+ * <A HREF="http://www.w3.org/pub/WWW/Protocols/"> the spec </A> for
+ * details.
+ * <p>
+ *
+ * <p>Uses of this class follow a pattern:
+ * <ol>
+ *   <li>Obtain a new {@code HttpURLConnection} by calling {@link
+ *       URL#openConnection() URL.openConnection()} and casting the result to
+ *       {@code HttpURLConnection}.
+ *   <li>Prepare the request. The primary property of a request is its URI.
+ *       Request headers may also include metadata such as credentials, preferred
+ *       content types, and session cookies.
+ *   <li>Optionally upload a request body. Instances must be configured with
+ *       {@link #setDoOutput(boolean) setDoOutput(true)} if they include a
+ *       request body. Transmit data by writing to the stream returned by {@link
+ *       #getOutputStream()}.
+ *   <li>Read the response. Response headers typically include metadata such as
+ *       the response body's content type and length, modified dates and session
+ *       cookies. The response body may be read from the stream returned by {@link
+ *       #getInputStream()}. If the response has no body, that method returns an
+ *       empty stream.
+ *   <li>Disconnect. Once the response body has been read, the {@code
+ *       HttpURLConnection} should be closed by calling {@link #disconnect()}.
+ *       Disconnecting releases the resources held by a connection so they may
+ *       be closed or reused.
+ * </ol>
+ *
+ * <p>For example, to retrieve the webpage at {@code http://www.android.com/}:
+ * <pre>   {@code
+ *   URL url = new URL("http://www.android.com/");
+ *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ *   try {
+ *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ *     readStream(in);
+ *   } finally {
+ *     urlConnection.disconnect();
+ *   }
+ * }</pre>
+ *
+ * <h3>Secure Communication with HTTPS</h3>
+ * Calling {@link URL#openConnection()} on a URL with the "https"
+ * scheme will return an {@code HttpsURLConnection}, which allows for
+ * overriding the default {@link javax.net.ssl.HostnameVerifier
+ * HostnameVerifier} and {@link javax.net.ssl.SSLSocketFactory
+ * SSLSocketFactory}. An application-supplied {@code SSLSocketFactory}
+ * created from an {@link javax.net.ssl.SSLContext SSLContext} can
+ * provide a custom {@link javax.net.ssl.X509TrustManager
+ * X509TrustManager} for verifying certificate chains and a custom
+ * {@link javax.net.ssl.X509KeyManager X509KeyManager} for supplying
+ * client certificates. See {@link javax.net.ssl.HttpsURLConnection
+ * HttpsURLConnection} for more details.
+ *
+ * <h3>Response Handling</h3>
+ * {@code HttpURLConnection} will follow up to five HTTP redirects. It will
+ * follow redirects from one origin server to another. This implementation
+ * doesn't follow redirects from HTTPS to HTTP or vice versa.
+ *
+ * <p>If the HTTP response indicates that an error occurred, {@link
+ * #getInputStream()} will throw an {@link IOException}. Use {@link
+ * #getErrorStream()} to read the error response. The headers can be read in
+ * the normal way using {@link #getHeaderFields()},
+ *
+ * <h3>Posting Content</h3>
+ * To upload data to a web server, configure the connection for output using
+ * {@link #setDoOutput(boolean) setDoOutput(true)}.
+ *
+ * <p>For best performance, you should call either {@link
+ * #setFixedLengthStreamingMode(int)} when the body length is known in advance,
+ * or {@link #setChunkedStreamingMode(int)} when it is not. Otherwise {@code
+ * HttpURLConnection} will be forced to buffer the complete request body in
+ * memory before it is transmitted, wasting (and possibly exhausting) heap and
+ * increasing latency.
+ *
+ * <p>For example, to perform an upload: <pre>   {@code
+ *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ *   try {
+ *     urlConnection.setDoOutput(true);
+ *     urlConnection.setChunkedStreamingMode(0);
+ *
+ *     OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
+ *     writeStream(out);
+ *
+ *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ *     readStream(in);
+ *   } finally {
+ *     urlConnection.disconnect();
+ *   }
+ * }</pre>
+ *
+ * <h3>Performance</h3>
+ * The input and output streams returned by this class are <strong>not
+ * buffered</strong>. Most callers should wrap the returned streams with {@link
+ * java.io.BufferedInputStream BufferedInputStream} or {@link
+ * java.io.BufferedOutputStream BufferedOutputStream}. Callers that do only bulk
+ * reads or writes may omit buffering.
+ *
+ * <p>When transferring large amounts of data to or from a server, use streams
+ * to limit how much data is in memory at once. Unless you need the entire
+ * body to be in memory at once, process it as a stream (rather than storing
+ * the complete body as a single byte array or string).
+ *
+ * <p>To reduce latency, this class may reuse the same underlying {@code Socket}
+ * for multiple request/response pairs. As a result, HTTP connections may be
+ * held open longer than necessary. Calls to {@link #disconnect()} may return
+ * the socket to a pool of connected sockets.
+ *
+ * <p>By default, this implementation of {@code HttpURLConnection} requests that
+ * servers use gzip compression and it automatically decompresses the data for
+ * callers of {@link #getInputStream()}. The Content-Encoding and Content-Length
+ * response headers are cleared in this case. Gzip compression can be disabled by
+ * setting the acceptable encodings in the request header: <pre>   {@code
+ *   urlConnection.setRequestProperty("Accept-Encoding", "identity");
+ * }</pre>
+ *
+ * <p>Setting the Accept-Encoding request header explicitly disables automatic
+ * decompression and leaves the response headers intact; callers must handle
+ * decompression as needed, according to the Content-Encoding header of the
+ * response.
+ *
+ * <p>{@link #getContentLength()} returns the number of bytes transmitted and
+ * cannot be used to predict how many bytes can be read from
+ * {@link #getInputStream()} for compressed streams. Instead, read that stream
+ * until it is exhausted, i.e. when {@link InputStream#read} returns -1.
+ *
+ * <h3>Handling Network Sign-On</h3>
+ * Some Wi-Fi networks block Internet access until the user clicks through a
+ * sign-on page. Such sign-on pages are typically presented by using HTTP
+ * redirects. You can use {@link #getURL()} to test if your connection has been
+ * unexpectedly redirected. This check is not valid until <strong>after</strong>
+ * the response headers have been received, which you can trigger by calling
+ * {@link #getHeaderFields()} or {@link #getInputStream()}. For example, to
+ * check that a response was not redirected to an unexpected host:
+ * <pre>   {@code
+ *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ *   try {
+ *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ *     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
+ *       // we were redirected! Kick the user out to the browser to sign on?
+ *     }
+ *     ...
+ *   } finally {
+ *     urlConnection.disconnect();
+ *   }
+ * }</pre>
+ *
+ * <h3>HTTP Authentication</h3>
+ * {@code HttpURLConnection} supports <a
+ * href="http://www.ietf.org/rfc/rfc2617">HTTP basic authentication</a>. Use
+ * {@link Authenticator} to set the VM-wide authentication handler:
+ * <pre>   {@code
+ *   Authenticator.setDefault(new Authenticator() {
+ *     protected PasswordAuthentication getPasswordAuthentication() {
+ *       return new PasswordAuthentication(username, password.toCharArray());
+ *     }
+ *   });
+ * }</pre>
+ * Unless paired with HTTPS, this is <strong>not</strong> a secure mechanism for
+ * user authentication. In particular, the username, password, request and
+ * response are all transmitted over the network without encryption.
+ *
+ * <h3>Sessions with Cookies</h3>
+ * To establish and maintain a potentially long-lived session between client
+ * and server, {@code HttpURLConnection} includes an extensible cookie manager.
+ * Enable VM-wide cookie management using {@link CookieHandler} and {@link
+ * CookieManager}: <pre>   {@code
+ *   CookieManager cookieManager = new CookieManager();
+ *   CookieHandler.setDefault(cookieManager);
+ * }</pre>
+ * By default, {@code CookieManager} accepts cookies from the <a
+ * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
+ * server</a> only. Two other policies are included: {@link
+ * CookiePolicy#ACCEPT_ALL} and {@link CookiePolicy#ACCEPT_NONE}. Implement
+ * {@link CookiePolicy} to define a custom policy.
+ *
+ * <p>The default {@code CookieManager} keeps all accepted cookies in memory. It
+ * will forget these cookies when the VM exits. Implement {@link CookieStore} to
+ * define a custom cookie store.
+ *
+ * <p>In addition to the cookies set by HTTP responses, you may set cookies
+ * programmatically. To be included in HTTP request headers, cookies must have
+ * the domain and path properties set.
+ *
+ * <p>By default, new instances of {@code HttpCookie} work only with servers
+ * that support <a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>
+ * cookies. Many web servers support only the older specification, <a
+ * href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a>. For compatibility
+ * with the most web servers, set the cookie version to 0.
+ *
+ * <p>For example, to receive {@code www.twitter.com} in French: <pre>   {@code
+ *   HttpCookie cookie = new HttpCookie("lang", "fr");
+ *   cookie.setDomain("twitter.com");
+ *   cookie.setPath("/");
+ *   cookie.setVersion(0);
+ *   cookieManager.getCookieStore().add(new URI("http://twitter.com/"), cookie);
+ * }</pre>
+ *
+ * <h3>HTTP Methods</h3>
+ * <p>{@code HttpURLConnection} uses the {@code GET} method by default. It will
+ * use {@code POST} if {@link #setDoOutput setDoOutput(true)} has been called.
+ * Other HTTP methods ({@code OPTIONS}, {@code HEAD}, {@code PUT}, {@code
+ * DELETE} and {@code TRACE}) can be used with {@link #setRequestMethod}.
+ *
+ * <h3>Proxies</h3>
+ * By default, this class will connect directly to the <a
+ * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
+ * server</a>. It can also connect via an {@link Proxy.Type#HTTP HTTP} or {@link
+ * Proxy.Type#SOCKS SOCKS} proxy. To use a proxy, use {@link
+ * URL#openConnection(Proxy) URL.openConnection(Proxy)} when creating the
+ * connection.
+ *
+ * <h3>IPv6 Support</h3>
+ * <p>This class includes transparent support for IPv6. For hosts with both IPv4
+ * and IPv6 addresses, it will attempt to connect to each of a host's addresses
+ * until a connection is established.
+ *
+ * <h3>Response Caching</h3>
+ * Android 4.0 (Ice Cream Sandwich, API level 15) includes a response cache. See
+ * {@code android.net.http.HttpResponseCache} for instructions on enabling HTTP
+ * caching in your application.
+ *
+ * <h3>Avoiding Bugs In Earlier Releases</h3>
+ * Prior to Android 2.2 (Froyo), this class had some frustrating bugs. In
+ * particular, calling {@code close()} on a readable {@code InputStream} could
+ * <a href="http://code.google.com/p/android/issues/detail?id=2939">poison the
+ * connection pool</a>. Work around this by disabling connection pooling:
+ * <pre>   {@code
+ * private void disableConnectionReuseIfNecessary() {
+ *   // Work around pre-Froyo bugs in HTTP connection reuse.
+ *   if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
+ *     System.setProperty("http.keepAlive", "false");
+ *   }
+ * }}</pre>
+ *
+ * <p>Each instance of {@code HttpURLConnection} may be used for one
+ * request/response pair. Instances of this class are not thread safe.
+ *
+ * @see     java.net.HttpURLConnection#disconnect()
+ * @since JDK1.1
+ */
+abstract public class HttpURLConnection extends URLConnection {
+    /* instance variables */
+
+    /**
+     * The HTTP method (GET,POST,PUT,etc.).
+     */
+    protected String method = "GET";
+
+    /**
+     * The chunk-length when using chunked encoding streaming mode for output.
+     * A value of {@code -1} means chunked encoding is disabled for output.
+     * @since 1.5
+     */
+    protected int chunkLength = -1;
+
+    /**
+     * The fixed content-length when using fixed-length streaming mode.
+     * A value of {@code -1} means fixed-length streaming mode is disabled
+     * for output.
+     *
+     * <P> <B>NOTE:</B> {@link #fixedContentLengthLong} is recommended instead
+     * of this field, as it allows larger content lengths to be set.
+     *
+     * @since 1.5
+     */
+    protected int fixedContentLength = -1;
+
+    /**
+     * The fixed content-length when using fixed-length streaming mode.
+     * A value of {@code -1} means fixed-length streaming mode is disabled
+     * for output.
+     *
+     * @since 1.7
+     */
+    protected long fixedContentLengthLong = -1;
+
+    /**
+     * Returns the key for the {@code n}<sup>th</sup> header field.
+     * Some implementations may treat the {@code 0}<sup>th</sup>
+     * header field as special, i.e. as the status line returned by the HTTP
+     * server. In this case, {@link #getHeaderField(int) getHeaderField(0)} returns the status
+     * line, but {@code getHeaderFieldKey(0)} returns null.
+     *
+     * @param   n   an index, where {@code n >=0}.
+     * @return  the key for the {@code n}<sup>th</sup> header field,
+     *          or {@code null} if the key does not exist.
+     */
+    public String getHeaderFieldKey (int n) {
+        return null;
+    }
+
+    /**
+     * This method is used to enable streaming of a HTTP request body
+     * without internal buffering, when the content length is known in
+     * advance.
+     * <p>
+     * An exception will be thrown if the application
+     * attempts to write more data than the indicated
+     * content-length, or if the application closes the OutputStream
+     * before writing the indicated amount.
+     * <p>
+     * When output streaming is enabled, authentication
+     * and redirection cannot be handled automatically.
+     * A HttpRetryException will be thrown when reading
+     * the response if authentication or redirection are required.
+     * This exception can be queried for the details of the error.
+     * <p>
+     * This method must be called before the URLConnection is connected.
+     * <p>
+     * <B>NOTE:</B> {@link #setFixedLengthStreamingMode(long)} is recommended
+     * instead of this method as it allows larger content lengths to be set.
+     *
+     * @param   contentLength The number of bytes which will be written
+     *          to the OutputStream.
+     *
+     * @throws  IllegalStateException if URLConnection is already connected
+     *          or if a different streaming mode is already enabled.
+     *
+     * @throws  IllegalArgumentException if a content length less than
+     *          zero is specified.
+     *
+     * @see     #setChunkedStreamingMode(int)
+     * @since 1.5
+     */
+    public void setFixedLengthStreamingMode (int contentLength) {
+        if (connected) {
+            throw new IllegalStateException ("Already connected");
+        }
+        if (chunkLength != -1) {
+            throw new IllegalStateException ("Chunked encoding streaming mode set");
+        }
+        if (contentLength < 0) {
+            throw new IllegalArgumentException ("invalid content length");
+        }
+        fixedContentLength = contentLength;
+    }
+
+    /**
+     * This method is used to enable streaming of a HTTP request body
+     * without internal buffering, when the content length is known in
+     * advance.
+     *
+     * <P> An exception will be thrown if the application attempts to write
+     * more data than the indicated content-length, or if the application
+     * closes the OutputStream before writing the indicated amount.
+     *
+     * <P> When output streaming is enabled, authentication and redirection
+     * cannot be handled automatically. A {@linkplain HttpRetryException} will
+     * be thrown when reading the response if authentication or redirection
+     * are required. This exception can be queried for the details of the
+     * error.
+     *
+     * <P> This method must be called before the URLConnection is connected.
+     *
+     * <P> The content length set by invoking this method takes precedence
+     * over any value set by {@link #setFixedLengthStreamingMode(int)}.
+     *
+     * @param  contentLength
+     *         The number of bytes which will be written to the OutputStream.
+     *
+     * @throws  IllegalStateException
+     *          if URLConnection is already connected or if a different
+     *          streaming mode is already enabled.
+     *
+     * @throws  IllegalArgumentException
+     *          if a content length less than zero is specified.
+     *
+     * @since 1.7
+     */
+    public void setFixedLengthStreamingMode(long contentLength) {
+        if (connected) {
+            throw new IllegalStateException("Already connected");
+        }
+        if (chunkLength != -1) {
+            throw new IllegalStateException(
+                "Chunked encoding streaming mode set");
+        }
+        if (contentLength < 0) {
+            throw new IllegalArgumentException("invalid content length");
+        }
+        fixedContentLengthLong = contentLength;
+    }
+
+    /* Default chunk size (including chunk header) if not specified;
+     * we want to keep this in sync with the one defined in
+     * sun.net.www.http.ChunkedOutputStream
+     */
+    private static final int DEFAULT_CHUNK_SIZE = 4096;
+
+    /**
+     * This method is used to enable streaming of a HTTP request body
+     * without internal buffering, when the content length is <b>not</b>
+     * known in advance. In this mode, chunked transfer encoding
+     * is used to send the request body. Note, not all HTTP servers
+     * support this mode.
+     * <p>
+     * When output streaming is enabled, authentication
+     * and redirection cannot be handled automatically.
+     * A HttpRetryException will be thrown when reading
+     * the response if authentication or redirection are required.
+     * This exception can be queried for the details of the error.
+     * <p>
+     * This method must be called before the URLConnection is connected.
+     *
+     * @param   chunklen The number of bytes to write in each chunk.
+     *          If chunklen is less than or equal to zero, a default
+     *          value will be used.
+     *
+     * @throws  IllegalStateException if URLConnection is already connected
+     *          or if a different streaming mode is already enabled.
+     *
+     * @see     #setFixedLengthStreamingMode(int)
+     * @since 1.5
+     */
+    public void setChunkedStreamingMode (int chunklen) {
+        if (connected) {
+            throw new IllegalStateException ("Can't set streaming mode: already connected");
+        }
+        if (fixedContentLength != -1 || fixedContentLengthLong != -1) {
+            throw new IllegalStateException ("Fixed length streaming mode set");
+        }
+        chunkLength = chunklen <=0? DEFAULT_CHUNK_SIZE : chunklen;
+    }
+
+    /**
+     * Returns the value for the {@code n}<sup>th</sup> header field.
+     * Some implementations may treat the {@code 0}<sup>th</sup>
+     * header field as special, i.e. as the status line returned by the HTTP
+     * server.
+     * <p>
+     * This method can be used in conjunction with the
+     * {@link #getHeaderFieldKey getHeaderFieldKey} method to iterate through all
+     * the headers in the message.
+     *
+     * @param   n   an index, where {@code n>=0}.
+     * @return  the value of the {@code n}<sup>th</sup> header field,
+     *          or {@code null} if the value does not exist.
+     * @see     java.net.HttpURLConnection#getHeaderFieldKey(int)
+     */
+    public String getHeaderField(int n) {
+        return null;
+    }
+
+    /**
+     * An {@code int} representing the three digit HTTP Status-Code.
+     * <ul>
+     * <li> 1xx: Informational
+     * <li> 2xx: Success
+     * <li> 3xx: Redirection
+     * <li> 4xx: Client Error
+     * <li> 5xx: Server Error
+     * </ul>
+     */
+    protected int responseCode = -1;
+
+    /**
+     * The HTTP response message.
+     */
+    protected String responseMessage = null;
+
+    /* static variables */
+
+    /* do we automatically follow redirects? The default is true. */
+    private static boolean followRedirects = true;
+
+    /**
+     * If {@code true}, the protocol will automatically follow redirects.
+     * If {@code false}, the protocol will not automatically follow
+     * redirects.
+     * <p>
+     * This field is set by the {@code setInstanceFollowRedirects}
+     * method. Its value is returned by the {@code getInstanceFollowRedirects}
+     * method.
+     * <p>
+     * Its default value is based on the value of the static followRedirects
+     * at HttpURLConnection construction time.
+     *
+     * @see     java.net.HttpURLConnection#setInstanceFollowRedirects(boolean)
+     * @see     java.net.HttpURLConnection#getInstanceFollowRedirects()
+     * @see     java.net.HttpURLConnection#setFollowRedirects(boolean)
+     */
+    protected boolean instanceFollowRedirects = followRedirects;
+
+    /* valid HTTP methods */
+    private static final String[] methods = {
+        "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
+    };
+
+    /**
+     * Constructor for the HttpURLConnection.
+     * @param u the URL
+     */
+    protected HttpURLConnection (URL u) {
+        super(u);
+    }
+
+    /**
+     * Sets whether HTTP redirects  (requests with response code 3xx) should
+     * be automatically followed by this class.  True by default.  Applets
+     * cannot change this variable.
+     * <p>
+     * If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param set a {@code boolean} indicating whether or not
+     * to follow HTTP redirects.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't
+     *             allow the operation.
+     * @see        SecurityManager#checkSetFactory
+     * @see #getFollowRedirects()
+     */
+    public static void setFollowRedirects(boolean set) {
+        SecurityManager sec = System.getSecurityManager();
+        if (sec != null) {
+            // seems to be the best check here...
+            sec.checkSetFactory();
+        }
+        followRedirects = set;
+    }
+
+    /**
+     * Returns a {@code boolean} indicating
+     * whether or not HTTP redirects (3xx) should
+     * be automatically followed.
+     *
+     * @return {@code true} if HTTP redirects should
+     * be automatically followed, {@code false} if not.
+     * @see #setFollowRedirects(boolean)
+     */
+    public static boolean getFollowRedirects() {
+        return followRedirects;
+    }
+
+    /**
+     * Sets whether HTTP redirects (requests with response code 3xx) should
+     * be automatically followed by this {@code HttpURLConnection}
+     * instance.
+     * <p>
+     * The default value comes from followRedirects, which defaults to
+     * true.
+     *
+     * @param followRedirects a {@code boolean} indicating
+     * whether or not to follow HTTP redirects.
+     *
+     * @see    java.net.HttpURLConnection#instanceFollowRedirects
+     * @see #getInstanceFollowRedirects
+     * @since 1.3
+     */
+     public void setInstanceFollowRedirects(boolean followRedirects) {
+        instanceFollowRedirects = followRedirects;
+     }
+
+     /**
+     * Returns the value of this {@code HttpURLConnection}'s
+     * {@code instanceFollowRedirects} field.
+     *
+     * @return  the value of this {@code HttpURLConnection}'s
+     *          {@code instanceFollowRedirects} field.
+     * @see     java.net.HttpURLConnection#instanceFollowRedirects
+     * @see #setInstanceFollowRedirects(boolean)
+     * @since 1.3
+     */
+     public boolean getInstanceFollowRedirects() {
+         return instanceFollowRedirects;
+     }
+
+    /**
+     * Set the method for the URL request, one of:
+     * <UL>
+     *  <LI>GET
+     *  <LI>POST
+     *  <LI>HEAD
+     *  <LI>OPTIONS
+     *  <LI>PUT
+     *  <LI>DELETE
+     *  <LI>TRACE
+     * </UL> are legal, subject to protocol restrictions.  The default
+     * method is GET.
+     *
+     * @param method the HTTP method
+     * @exception ProtocolException if the method cannot be reset or if
+     *              the requested method isn't valid for HTTP.
+     * @exception SecurityException if a security manager is set and the
+     *              method is "TRACE", but the "allowHttpTrace"
+     *              NetPermission is not granted.
+     * @see #getRequestMethod()
+     */
+    public void setRequestMethod(String method) throws ProtocolException {
+        if (connected) {
+            throw new ProtocolException("Can't reset method: already connected");
+        }
+        // This restriction will prevent people from using this class to
+        // experiment w/ new HTTP methods using java.  But it should
+        // be placed for security - the request String could be
+        // arbitrarily long.
+
+        for (int i = 0; i < methods.length; i++) {
+            if (methods[i].equals(method)) {
+                if (method.equals("TRACE")) {
+                    SecurityManager s = System.getSecurityManager();
+                    if (s != null) {
+                        s.checkPermission(new NetPermission("allowHttpTrace"));
+                    }
+                }
+                this.method = method;
+                return;
+            }
+        }
+        throw new ProtocolException("Invalid HTTP method: " + method);
+    }
+
+    /**
+     * Get the request method.
+     * @return the HTTP request method
+     * @see #setRequestMethod(java.lang.String)
+     */
+    public String getRequestMethod() {
+        return method;
+    }
+
+    /**
+     * Gets the status code from an HTTP response message.
+     * For example, in the case of the following status lines:
+     * <PRE>
+     * HTTP/1.0 200 OK
+     * HTTP/1.0 401 Unauthorized
+     * </PRE>
+     * It will return 200 and 401 respectively.
+     * Returns -1 if no code can be discerned
+     * from the response (i.e., the response is not valid HTTP).
+     * @throws IOException if an error occurred connecting to the server.
+     * @return the HTTP Status-Code, or -1
+     */
+    public int getResponseCode() throws IOException {
+        /*
+         * We're got the response code already
+         */
+        if (responseCode != -1) {
+            return responseCode;
+        }
+
+        /*
+         * Ensure that we have connected to the server. Record
+         * exception as we need to re-throw it if there isn't
+         * a status line.
+         */
+        Exception exc = null;
+        try {
+            getInputStream();
+        } catch (Exception e) {
+            exc = e;
+        }
+
+        /*
+         * If we can't a status-line then re-throw any exception
+         * that getInputStream threw.
+         */
+        String statusLine = getHeaderField(0);
+        if (statusLine == null) {
+            if (exc != null) {
+                if (exc instanceof RuntimeException)
+                    throw (RuntimeException)exc;
+                else
+                    throw (IOException)exc;
+            }
+            return -1;
+        }
+
+        /*
+         * Examine the status-line - should be formatted as per
+         * section 6.1 of RFC 2616 :-
+         *
+         * Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase
+         *
+         * If status line can't be parsed return -1.
+         */
+        if (statusLine.startsWith("HTTP/1.")) {
+            int codePos = statusLine.indexOf(' ');
+            if (codePos > 0) {
+
+                int phrasePos = statusLine.indexOf(' ', codePos+1);
+                if (phrasePos > 0 && phrasePos < statusLine.length()) {
+                    responseMessage = statusLine.substring(phrasePos+1);
+                }
+
+                // deviation from RFC 2616 - don't reject status line
+                // if SP Reason-Phrase is not included.
+                if (phrasePos < 0)
+                    phrasePos = statusLine.length();
+
+                try {
+                    responseCode = Integer.parseInt
+                            (statusLine.substring(codePos+1, phrasePos));
+                    return responseCode;
+                } catch (NumberFormatException e) { }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Gets the HTTP response message, if any, returned along with the
+     * response code from a server.  From responses like:
+     * <PRE>
+     * HTTP/1.0 200 OK
+     * HTTP/1.0 404 Not Found
+     * </PRE>
+     * Extracts the Strings "OK" and "Not Found" respectively.
+     * Returns null if none could be discerned from the responses
+     * (the result was not valid HTTP).
+     * @throws IOException if an error occurred connecting to the server.
+     * @return the HTTP response message, or {@code null}
+     */
+    public String getResponseMessage() throws IOException {
+        getResponseCode();
+        return responseMessage;
+    }
+
+    @SuppressWarnings("deprecation")
+    public long getHeaderFieldDate(String name, long Default) {
+        String dateString = getHeaderField(name);
+        try {
+            if (dateString.indexOf("GMT") == -1) {
+                dateString = dateString+" GMT";
+            }
+            return Date.parse(dateString);
+        } catch (Exception e) {
+        }
+        return Default;
+    }
+
+
+    /**
+     * Indicates that other requests to the server
+     * are unlikely in the near future. Calling disconnect()
+     * should not imply that this HttpURLConnection
+     * instance can be reused for other requests.
+     */
+    public abstract void disconnect();
+
+    /**
+     * Indicates if the connection is going through a proxy.
+     * @return a boolean indicating if the connection is
+     * using a proxy.
+     */
+    public abstract boolean usingProxy();
+
+    /**
+     * Returns a {@link SocketPermission} object representing the
+     * permission necessary to connect to the destination host and port.
+     *
+     * @exception IOException if an error occurs while computing
+     *            the permission.
+     *
+     * @return a {@code SocketPermission} object representing the
+     *         permission necessary to connect to the destination
+     *         host and port.
+     */
+    public Permission getPermission() throws IOException {
+        int port = url.getPort();
+        port = port < 0 ? 80 : port;
+        String host = url.getHost() + ":" + port;
+        Permission permission = new SocketPermission(host, "connect");
+        return permission;
+    }
+
+   /**
+    * Returns the error stream if the connection failed
+    * but the server sent useful data nonetheless. The
+    * typical example is when an HTTP server responds
+    * with a 404, which will cause a FileNotFoundException
+    * to be thrown in connect, but the server sent an HTML
+    * help page with suggestions as to what to do.
+    *
+    * <p>This method will not cause a connection to be initiated.  If
+    * the connection was not connected, or if the server did not have
+    * an error while connecting or if the server had an error but
+    * no error data was sent, this method will return null. This is
+    * the default.
+    *
+    * @return an error stream if any, null if there have been no
+    * errors, the connection is not connected or the server sent no
+    * useful data.
+    */
+    public InputStream getErrorStream() {
+        return null;
+    }
+
+    /**
+     * The response codes for HTTP, as of version 1.1.
+     */
+
+    // REMIND: do we want all these??
+    // Others not here that we do want??
+
+    /* 2XX: generally "OK" */
+
+    /**
+     * HTTP Status-Code 200: OK.
+     */
+    public static final int HTTP_OK = 200;
+
+    /**
+     * HTTP Status-Code 201: Created.
+     */
+    public static final int HTTP_CREATED = 201;
+
+    /**
+     * HTTP Status-Code 202: Accepted.
+     */
+    public static final int HTTP_ACCEPTED = 202;
+
+    /**
+     * HTTP Status-Code 203: Non-Authoritative Information.
+     */
+    public static final int HTTP_NOT_AUTHORITATIVE = 203;
+
+    /**
+     * HTTP Status-Code 204: No Content.
+     */
+    public static final int HTTP_NO_CONTENT = 204;
+
+    /**
+     * HTTP Status-Code 205: Reset Content.
+     */
+    public static final int HTTP_RESET = 205;
+
+    /**
+     * HTTP Status-Code 206: Partial Content.
+     */
+    public static final int HTTP_PARTIAL = 206;
+
+    /* 3XX: relocation/redirect */
+
+    /**
+     * HTTP Status-Code 300: Multiple Choices.
+     */
+    public static final int HTTP_MULT_CHOICE = 300;
+
+    /**
+     * HTTP Status-Code 301: Moved Permanently.
+     */
+    public static final int HTTP_MOVED_PERM = 301;
+
+    /**
+     * HTTP Status-Code 302: Temporary Redirect.
+     */
+    public static final int HTTP_MOVED_TEMP = 302;
+
+    /**
+     * HTTP Status-Code 303: See Other.
+     */
+    public static final int HTTP_SEE_OTHER = 303;
+
+    /**
+     * HTTP Status-Code 304: Not Modified.
+     */
+    public static final int HTTP_NOT_MODIFIED = 304;
+
+    /**
+     * HTTP Status-Code 305: Use Proxy.
+     */
+    public static final int HTTP_USE_PROXY = 305;
+
+    /* 4XX: client error */
+
+    /**
+     * HTTP Status-Code 400: Bad Request.
+     */
+    public static final int HTTP_BAD_REQUEST = 400;
+
+    /**
+     * HTTP Status-Code 401: Unauthorized.
+     */
+    public static final int HTTP_UNAUTHORIZED = 401;
+
+    /**
+     * HTTP Status-Code 402: Payment Required.
+     */
+    public static final int HTTP_PAYMENT_REQUIRED = 402;
+
+    /**
+     * HTTP Status-Code 403: Forbidden.
+     */
+    public static final int HTTP_FORBIDDEN = 403;
+
+    /**
+     * HTTP Status-Code 404: Not Found.
+     */
+    public static final int HTTP_NOT_FOUND = 404;
+
+    /**
+     * HTTP Status-Code 405: Method Not Allowed.
+     */
+    public static final int HTTP_BAD_METHOD = 405;
+
+    /**
+     * HTTP Status-Code 406: Not Acceptable.
+     */
+    public static final int HTTP_NOT_ACCEPTABLE = 406;
+
+    /**
+     * HTTP Status-Code 407: Proxy Authentication Required.
+     */
+    public static final int HTTP_PROXY_AUTH = 407;
+
+    /**
+     * HTTP Status-Code 408: Request Time-Out.
+     */
+    public static final int HTTP_CLIENT_TIMEOUT = 408;
+
+    /**
+     * HTTP Status-Code 409: Conflict.
+     */
+    public static final int HTTP_CONFLICT = 409;
+
+    /**
+     * HTTP Status-Code 410: Gone.
+     */
+    public static final int HTTP_GONE = 410;
+
+    /**
+     * HTTP Status-Code 411: Length Required.
+     */
+    public static final int HTTP_LENGTH_REQUIRED = 411;
+
+    /**
+     * HTTP Status-Code 412: Precondition Failed.
+     */
+    public static final int HTTP_PRECON_FAILED = 412;
+
+    /**
+     * HTTP Status-Code 413: Request Entity Too Large.
+     */
+    public static final int HTTP_ENTITY_TOO_LARGE = 413;
+
+    /**
+     * HTTP Status-Code 414: Request-URI Too Large.
+     */
+    public static final int HTTP_REQ_TOO_LONG = 414;
+
+    /**
+     * HTTP Status-Code 415: Unsupported Media Type.
+     */
+    public static final int HTTP_UNSUPPORTED_TYPE = 415;
+
+    /* 5XX: server error */
+
+    /**
+     * HTTP Status-Code 500: Internal Server Error.
+     * @deprecated   it is misplaced and shouldn't have existed.
+     */
+    @Deprecated
+    public static final int HTTP_SERVER_ERROR = 500;
+
+    /**
+     * HTTP Status-Code 500: Internal Server Error.
+     */
+    public static final int HTTP_INTERNAL_ERROR = 500;
+
+    /**
+     * HTTP Status-Code 501: Not Implemented.
+     */
+    public static final int HTTP_NOT_IMPLEMENTED = 501;
+
+    /**
+     * HTTP Status-Code 502: Bad Gateway.
+     */
+    public static final int HTTP_BAD_GATEWAY = 502;
+
+    /**
+     * HTTP Status-Code 503: Service Unavailable.
+     */
+    public static final int HTTP_UNAVAILABLE = 503;
+
+    /**
+     * HTTP Status-Code 504: Gateway Timeout.
+     */
+    public static final int HTTP_GATEWAY_TIMEOUT = 504;
+
+    /**
+     * HTTP Status-Code 505: HTTP Version Not Supported.
+     */
+    public static final int HTTP_VERSION = 505;
+
+}
diff --git a/java/net/IDN.java b/java/net/IDN.java
new file mode 100644
index 0000000..a18c3a8
--- /dev/null
+++ b/java/net/IDN.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+import android.icu.text.IDNA;
+
+/**
+ * Provides methods to convert internationalized domain names (IDNs) between
+ * a normal Unicode representation and an ASCII Compatible Encoding (ACE) representation.
+ * Internationalized domain names can use characters from the entire range of
+ * Unicode, while traditional domain names are restricted to ASCII characters.
+ * ACE is an encoding of Unicode strings that uses only ASCII characters and
+ * can be used with software (such as the Domain Name System) that only
+ * understands traditional domain names.
+ *
+ * <p>Internationalized domain names are defined in <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
+ * RFC 3490 defines two operations: ToASCII and ToUnicode. These 2 operations employ
+ * <a href="http://www.ietf.org/rfc/rfc3491.txt">Nameprep</a> algorithm, which is a
+ * profile of <a href="http://www.ietf.org/rfc/rfc3454.txt">Stringprep</a>, and
+ * <a href="http://www.ietf.org/rfc/rfc3492.txt">Punycode</a> algorithm to convert
+ * domain name string back and forth.
+ *
+ * <p>The behavior of aforementioned conversion process can be adjusted by various flags:
+ *   <ul>
+ *     <li>If the ALLOW_UNASSIGNED flag is used, the domain name string to be converted
+ *         can contain code points that are unassigned in Unicode 3.2, which is the
+ *         Unicode version on which IDN conversion is based. If the flag is not used,
+ *         the presence of such unassigned code points is treated as an error.
+ *     <li>If the USE_STD3_ASCII_RULES flag is used, ASCII strings are checked against <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC 1122</a> and <a href="http://www.ietf.org/rfc/rfc1123.txt">RFC 1123</a>.
+ *         It is an error if they don't meet the requirements.
+ *   </ul>
+ * These flags can be logically OR'ed together.
+ *
+ * <p>The security consideration is important with respect to internationalization
+ * domain name support. For example, English domain names may be <i>homographed</i>
+ * - maliciously misspelled by substitution of non-Latin letters.
+ * <a href="http://www.unicode.org/reports/tr36/">Unicode Technical Report #36</a>
+ * discusses security issues of IDN support as well as possible solutions.
+ * Applications are responsible for taking adequate security measures when using
+ * international domain names.
+ *
+ * @author Edward Wang
+ * @since 1.6
+ *
+ */
+public final class IDN {
+    /**
+     * Flag to allow processing of unassigned code points
+     */
+    public static final int ALLOW_UNASSIGNED = 0x01;
+
+    /**
+     * Flag to turn on the check against STD-3 ASCII rules
+     */
+    public static final int USE_STD3_ASCII_RULES = 0x02;
+
+
+    /**
+     * Translates a string from Unicode to ASCII Compatible Encoding (ACE),
+     * as defined by the ToASCII operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
+     *
+     * <p>ToASCII operation can fail. ToASCII fails if any step of it fails.
+     * If ToASCII operation fails, an IllegalArgumentException will be thrown.
+     * In this case, the input string should not be used in an internationalized domain name.
+     *
+     * <p> A label is an individual part of a domain name. The original ToASCII operation,
+     * as defined in RFC 3490, only operates on a single label. This method can handle
+     * both label and entire domain name, by assuming that labels in a domain name are
+     * always separated by dots. The following characters are recognized as dots:
+     * &#0092;u002E (full stop), &#0092;u3002 (ideographic full stop), &#0092;uFF0E (fullwidth full stop),
+     * and &#0092;uFF61 (halfwidth ideographic full stop). if dots are
+     * used as label separators, this method also changes all of them to &#0092;u002E (full stop)
+     * in output translated string.
+     *
+     * @param input     the string to be processed
+     * @param flag      process flag; can be 0 or any logical OR of possible flags
+     *
+     * @return          the translated {@code String}
+     *
+     * @throws IllegalArgumentException   if the input string doesn't conform to RFC 3490 specification
+     */
+    public static String toASCII(String input, int flag) {
+        // BEGIN Android-changed: Use ICU4J implementation
+        try {
+            return IDNA.convertIDNToASCII(input, flag).toString();
+        } catch (android.icu.text.StringPrepParseException e) {
+            // b/113787610: "." is a valid IDN but is rejected by ICU.
+            // Usage is relatively uncommon, so only check for it if ICU throws.
+            if (".".equals(input)) {
+                return input;
+            }
+            throw new IllegalArgumentException("Invalid input to toASCII: " + input, e);
+        }
+        // END Android-changed: Use ICU4J implementation
+    }
+
+
+    /**
+     * Translates a string from Unicode to ASCII Compatible Encoding (ACE),
+     * as defined by the ToASCII operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
+     *
+     * <p> This convenience method works as if by invoking the
+     * two-argument counterpart as follows:
+     * <blockquote>
+     * {@link #toASCII(String, int) toASCII}(input,&nbsp;0);
+     * </blockquote>
+     *
+     * @param input     the string to be processed
+     *
+     * @return          the translated {@code String}
+     *
+     * @throws IllegalArgumentException   if the input string doesn't conform to RFC 3490 specification
+     */
+    public static String toASCII(String input) {
+        return toASCII(input, 0);
+    }
+
+
+    /**
+     * Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
+     * as defined by the ToUnicode operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
+     *
+     * <p>ToUnicode never fails. In case of any error, the input string is returned unmodified.
+     *
+     * <p> A label is an individual part of a domain name. The original ToUnicode operation,
+     * as defined in RFC 3490, only operates on a single label. This method can handle
+     * both label and entire domain name, by assuming that labels in a domain name are
+     * always separated by dots. The following characters are recognized as dots:
+     * &#0092;u002E (full stop), &#0092;u3002 (ideographic full stop), &#0092;uFF0E (fullwidth full stop),
+     * and &#0092;uFF61 (halfwidth ideographic full stop).
+     *
+     * @param input     the string to be processed
+     * @param flag      process flag; can be 0 or any logical OR of possible flags
+     *
+     * @return          the translated {@code String}
+     */
+    public static String toUnicode(String input, int flag) {
+        // BEGIN Android-changed: Use ICU4J implementation
+        try {
+            // ICU only translates separators to ASCII for toASCII.
+            // Java expects the translation for toUnicode too.
+            return convertFullStop(IDNA.convertIDNToUnicode(input, flag)).toString();
+        } catch (android.icu.text.StringPrepParseException e) {
+            // The RI documentation explicitly states that if the conversion was unsuccessful
+            // the original string is returned.
+            return input;
+        }
+        // END Android-changed: Use ICU4J implementation
+    }
+
+    // BEGIN Android-added: Use ICU4J implementation
+    private static boolean isLabelSeperator(char c) {
+        return (c == '\u3002' || c == '\uff0e' || c == '\uff61');
+    }
+
+    private static StringBuffer convertFullStop(StringBuffer input) {
+        for (int i = 0; i < input.length(); i++) {
+            if (isLabelSeperator(input.charAt(i))) {
+                input.setCharAt(i, '.');
+            }
+        }
+        return input;
+    }
+    // END Android-added: Use ICU4J implementation
+
+    /**
+     * Translates a string from ASCII Compatible Encoding (ACE) to Unicode,
+     * as defined by the ToUnicode operation of <a href="http://www.ietf.org/rfc/rfc3490.txt">RFC 3490</a>.
+     *
+     * <p> This convenience method works as if by invoking the
+     * two-argument counterpart as follows:
+     * <blockquote>
+     * {@link #toUnicode(String, int) toUnicode}(input,&nbsp;0);
+     * </blockquote>
+     *
+     * @param input     the string to be processed
+     *
+     * @return          the translated {@code String}
+     */
+    public static String toUnicode(String input) {
+        return toUnicode(input, 0);
+    }
+
+
+    /* ---------------- Private members -------------- */
+
+    // Android-removed: Private helper methods, unused because we use ICU.
+    /*
+    // ACE Prefix is "xn--"
+    private static final String ACE_PREFIX = "xn--";
+    private static final int ACE_PREFIX_LENGTH = ACE_PREFIX.length();
+
+    private static final int MAX_LABEL_LENGTH   = 63;
+
+    // single instance of nameprep
+    private static StringPrep namePrep = null;
+
+    static {
+        InputStream stream = null;
+
+        try {
+            final String IDN_PROFILE = "uidna.spp";
+            if (System.getSecurityManager() != null) {
+                stream = AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
+                    public InputStream run() {
+                        return StringPrep.class.getResourceAsStream(IDN_PROFILE);
+                    }
+                });
+            } else {
+                stream = StringPrep.class.getResourceAsStream(IDN_PROFILE);
+            }
+
+            namePrep = new StringPrep(stream);
+            stream.close();
+        } catch (IOException e) {
+            // should never reach here
+            assert false;
+        }
+    }
+    */
+
+    /* ---------------- Private operations -------------- */
+
+
+    //
+    // to suppress the default zero-argument constructor
+    //
+    private IDN() {}
+
+    // Android-removed: Private helper methods, unused because we use ICU.
+    /*
+    //
+    // toASCII operation; should only apply to a single label
+    //
+    private static String toASCIIInternal(String label, int flag)
+    {
+        // step 1
+        // Check if the string contains code points outside the ASCII range 0..0x7c.
+        boolean isASCII  = isAllASCII(label);
+        StringBuffer dest;
+
+        // step 2
+        // perform the nameprep operation; flag ALLOW_UNASSIGNED is used here
+        if (!isASCII) {
+            UCharacterIterator iter = UCharacterIterator.getInstance(label);
+            try {
+                dest = namePrep.prepare(iter, flag);
+            } catch (java.text.ParseException e) {
+                throw new IllegalArgumentException(e);
+            }
+        } else {
+            dest = new StringBuffer(label);
+        }
+
+        // step 8, move forward to check the smallest number of the code points
+        // the length must be inside 1..63
+        if (dest.length() == 0) {
+            throw new IllegalArgumentException(
+                        "Empty label is not a legal name");
+        }
+
+        // step 3
+        // Verify the absence of non-LDH ASCII code points
+        //   0..0x2c, 0x2e..0x2f, 0x3a..0x40, 0x5b..0x60, 0x7b..0x7f
+        // Verify the absence of leading and trailing hyphen
+        boolean useSTD3ASCIIRules = ((flag & USE_STD3_ASCII_RULES) != 0);
+        if (useSTD3ASCIIRules) {
+            for (int i = 0; i < dest.length(); i++) {
+                int c = dest.charAt(i);
+                if (isNonLDHAsciiCodePoint(c)) {
+                    throw new IllegalArgumentException(
+                        "Contains non-LDH ASCII characters");
+                }
+            }
+
+            if (dest.charAt(0) == '-' ||
+                dest.charAt(dest.length() - 1) == '-') {
+
+                throw new IllegalArgumentException(
+                        "Has leading or trailing hyphen");
+            }
+        }
+
+        if (!isASCII) {
+            // step 4
+            // If all code points are inside 0..0x7f, skip to step 8
+            if (!isAllASCII(dest.toString())) {
+                // step 5
+                // verify the sequence does not begin with ACE prefix
+                if(!startsWithACEPrefix(dest)){
+
+                    // step 6
+                    // encode the sequence with punycode
+                    try {
+                        dest = Punycode.encode(dest, null);
+                    } catch (java.text.ParseException e) {
+                        throw new IllegalArgumentException(e);
+                    }
+
+                    dest = toASCIILower(dest);
+
+                    // step 7
+                    // prepend the ACE prefix
+                    dest.insert(0, ACE_PREFIX);
+                } else {
+                    throw new IllegalArgumentException("The input starts with the ACE Prefix");
+                }
+
+            }
+        }
+
+        // step 8
+        // the length must be inside 1..63
+        if (dest.length() > MAX_LABEL_LENGTH) {
+            throw new IllegalArgumentException("The label in the input is too long");
+        }
+
+        return dest.toString();
+    }
+
+    //
+    // toUnicode operation; should only apply to a single label
+    //
+    private static String toUnicodeInternal(String label, int flag) {
+        boolean[] caseFlags = null;
+        StringBuffer dest;
+
+        // step 1
+        // find out if all the codepoints in input are ASCII
+        boolean isASCII = isAllASCII(label);
+
+        if(!isASCII){
+            // step 2
+            // perform the nameprep operation; flag ALLOW_UNASSIGNED is used here
+            try {
+                UCharacterIterator iter = UCharacterIterator.getInstance(label);
+                dest = namePrep.prepare(iter, flag);
+            } catch (Exception e) {
+                // toUnicode never fails; if any step fails, return the input string
+                return label;
+            }
+        } else {
+            dest = new StringBuffer(label);
+        }
+
+        // step 3
+        // verify ACE Prefix
+        if(startsWithACEPrefix(dest)) {
+
+            // step 4
+            // Remove the ACE Prefix
+            String temp = dest.substring(ACE_PREFIX_LENGTH, dest.length());
+
+            try {
+                // step 5
+                // Decode using punycode
+                StringBuffer decodeOut = Punycode.decode(new StringBuffer(temp), null);
+
+                // step 6
+                // Apply toASCII
+                String toASCIIOut = toASCII(decodeOut.toString(), flag);
+
+                // step 7
+                // verify
+                if (toASCIIOut.equalsIgnoreCase(dest.toString())) {
+                    // step 8
+                    // return output of step 5
+                    return decodeOut.toString();
+                }
+            } catch (Exception ignored) {
+                // no-op
+            }
+        }
+
+        // just return the input
+        return label;
+    }
+
+
+    //
+    // LDH stands for "letter/digit/hyphen", with characters restricted to the
+    // 26-letter Latin alphabet <A-Z a-z>, the digits <0-9>, and the hyphen
+    // <->.
+    // Non LDH refers to characters in the ASCII range, but which are not
+    // letters, digits or the hypen.
+    //
+    // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F
+    //
+    private static boolean isNonLDHAsciiCodePoint(int ch){
+        return (0x0000 <= ch && ch <= 0x002C) ||
+               (0x002E <= ch && ch <= 0x002F) ||
+               (0x003A <= ch && ch <= 0x0040) ||
+               (0x005B <= ch && ch <= 0x0060) ||
+               (0x007B <= ch && ch <= 0x007F);
+    }
+
+    //
+    // search dots in a string and return the index of that character;
+    // or if there is no dots, return the length of input string
+    // dots might be: \u002E (full stop), \u3002 (ideographic full stop), \uFF0E (fullwidth full stop),
+    // and \uFF61 (halfwidth ideographic full stop).
+    //
+    private static int searchDots(String s, int start) {
+        int i;
+        for (i = start; i < s.length(); i++) {
+            if (isLabelSeparator(s.charAt(i))) {
+                break;
+            }
+        }
+
+        return i;
+    }
+
+    //
+    // to check if a string is a root label, ".".
+    //
+    private static boolean isRootLabel(String s) {
+        return (s.length() == 1 && isLabelSeparator(s.charAt(0)));
+    }
+
+    //
+    // to check if a character is a label separator, i.e. a dot character.
+    //
+    private static boolean isLabelSeparator(char c) {
+        return (c == '.' || c == '\u3002' || c == '\uFF0E' || c == '\uFF61');
+    }
+
+    //
+    // to check if a string only contains US-ASCII code point
+    //
+    private static boolean isAllASCII(String input) {
+        boolean isASCII = true;
+        for (int i = 0; i < input.length(); i++) {
+            int c = input.charAt(i);
+            if (c > 0x7F) {
+                isASCII = false;
+                break;
+            }
+        }
+        return isASCII;
+    }
+
+    //
+    // to check if a string starts with ACE-prefix
+    //
+    private static boolean startsWithACEPrefix(StringBuffer input){
+        boolean startsWithPrefix = true;
+
+        if(input.length() < ACE_PREFIX_LENGTH){
+            return false;
+        }
+        for(int i = 0; i < ACE_PREFIX_LENGTH; i++){
+            if(toASCIILower(input.charAt(i)) != ACE_PREFIX.charAt(i)){
+                startsWithPrefix = false;
+            }
+        }
+        return startsWithPrefix;
+    }
+
+    private static char toASCIILower(char ch){
+        if('A' <= ch && ch <= 'Z'){
+            return (char)(ch + 'a' - 'A');
+        }
+        return ch;
+    }
+
+    private static StringBuffer toASCIILower(StringBuffer input){
+        StringBuffer dest = new StringBuffer();
+        for(int i = 0; i < input.length();i++){
+            dest.append(toASCIILower(input.charAt(i)));
+        }
+        return dest;
+    }
+    */
+}
diff --git a/java/net/InMemoryCookieStore.java b/java/net/InMemoryCookieStore.java
new file mode 100644
index 0000000..5df66c0
--- /dev/null
+++ b/java/net/InMemoryCookieStore.java
@@ -0,0 +1,433 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import dalvik.system.VMRuntime;
+
+import java.util.List;
+import java.util.Map;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.concurrent.locks.ReentrantLock;
+
+// Android-changed: App compat changes and bug fixes
+// b/26456024 Add targetSdkVersion based compatibility for domain matching
+// b/33034917 Support clearing cookies by adding it with "max-age=0"
+// b/25897688 InMemoryCookieStore ignores scheme (http/https) port and path of the cookie
+// Remove cookieJar and domainIndex. Use urlIndex as single Cookie storage
+// Fix InMemoryCookieStore#remove to verify cookie URI before removal
+// Fix InMemoryCookieStore#removeAll to return false if it's empty.
+/**
+ * A simple in-memory java.net.CookieStore implementation
+ *
+ * @author Edward Wang
+ * @since 1.6
+ * @hide Visible for testing only.
+ */
+public class InMemoryCookieStore implements CookieStore {
+    // the in-memory representation of cookies
+    // BEGIN Android-removed: Remove cookieJar and domainIndex
+    /*
+    private List<HttpCookie> cookieJar = null;
+
+    // the cookies are indexed by its domain and associated uri (if present)
+    // CAUTION: when a cookie removed from main data structure (i.e. cookieJar),
+    //          it won't be cleared in domainIndex & uriIndex. Double-check the
+    //          presence of cookie when retrieve one form index store.
+    private Map<String, List<HttpCookie>> domainIndex = null;
+    */
+    // END Android-removed: Remove cookieJar and domainIndex
+    private Map<URI, List<HttpCookie>> uriIndex = null;
+
+    // use ReentrantLock instead of syncronized for scalability
+    private ReentrantLock lock = null;
+
+    // BEGIN Android-changed: Add targetSdkVersion and remove cookieJar and domainIndex
+    private final boolean applyMCompatibility;
+
+    /**
+     * The default ctor
+     */
+    public InMemoryCookieStore() {
+        this(VMRuntime.getRuntime().getTargetSdkVersion());
+    }
+
+    public InMemoryCookieStore(int targetSdkVersion) {
+        uriIndex = new HashMap<>();
+        lock = new ReentrantLock(false);
+        applyMCompatibility = (targetSdkVersion <= 23);
+    }
+    // END Android-changed: Add targetSdkVersion and remove cookieJar and domainIndex
+
+    /**
+     * Add one cookie into cookie store.
+     */
+    public void add(URI uri, HttpCookie cookie) {
+        // pre-condition : argument can't be null
+        if (cookie == null) {
+            throw new NullPointerException("cookie is null");
+        }
+
+        lock.lock();
+        try {
+            // Android-changed: http://b/33034917, android supports clearing cookies
+            // by adding the cookie with max-age: 0.
+            //if (cookie.getMaxAge() != 0) {
+            addIndex(uriIndex, getEffectiveURI(uri), cookie);
+            //}
+        } finally {
+            lock.unlock();
+        }
+    }
+
+
+    /**
+     * Get all cookies, which:
+     *  1) given uri domain-matches with, or, associated with
+     *     given uri when added to the cookie store.
+     *  3) not expired.
+     * See RFC 2965 sec. 3.3.4 for more detail.
+     */
+    public List<HttpCookie> get(URI uri) {
+        // argument can't be null
+        if (uri == null) {
+            throw new NullPointerException("uri is null");
+        }
+
+        List<HttpCookie> cookies = new ArrayList<HttpCookie>();
+        // BEGIN Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        lock.lock();
+        try {
+            // check domainIndex first
+            getInternal1(cookies, uriIndex, uri.getHost());
+            // check uriIndex then
+            getInternal2(cookies, uriIndex, getEffectiveURI(uri));
+        } finally {
+            lock.unlock();
+        }
+        // END Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        return cookies;
+    }
+
+    /**
+     * Get all cookies in cookie store, except those have expired
+     */
+    public List<HttpCookie> getCookies() {
+        // BEGIN Android-changed: Remove cookieJar and domainIndex
+        List<HttpCookie> rt = new ArrayList<HttpCookie>();
+
+        lock.lock();
+        try {
+            for (List<HttpCookie> list : uriIndex.values()) {
+                Iterator<HttpCookie> it = list.iterator();
+                while (it.hasNext()) {
+                    HttpCookie cookie = it.next();
+                    if (cookie.hasExpired()) {
+                        it.remove();
+                    } else if (!rt.contains(cookie)) {
+                        rt.add(cookie);
+                    }
+                }
+            }
+        } finally {
+            rt = Collections.unmodifiableList(rt);
+            lock.unlock();
+        }
+        // END Android-changed: Remove cookieJar and domainIndex
+
+        return rt;
+    }
+
+    /**
+     * Get all URIs, which are associated with at least one cookie
+     * of this cookie store.
+     */
+    public List<URI> getURIs() {
+        // BEGIN Android-changed: App compat. Return URI with no cookies. http://b/65538736
+        /*
+        List<URI> uris = new ArrayList<URI>();
+
+        lock.lock();
+        try {
+            Iterator<URI> it = uriIndex.keySet().iterator();
+            while (it.hasNext()) {
+                URI uri = it.next();
+                List<HttpCookie> cookies = uriIndex.get(uri);
+                if (cookies == null || cookies.size() == 0) {
+                    // no cookies list or an empty list associated with
+                    // this uri entry, delete it
+                    it.remove();
+                }
+            }
+        } finally {
+            uris.addAll(uriIndex.keySet());
+            lock.unlock();
+        }
+
+        return uris;
+         */
+        lock.lock();
+        try {
+            List<URI> result = new ArrayList<URI>(uriIndex.keySet());
+            result.remove(null);
+            return Collections.unmodifiableList(result);
+        } finally {
+            lock.unlock();
+        }
+        // END Android-changed: App compat. Return URI with no cookies. http://b/65538736
+    }
+
+
+    /**
+     * Remove a cookie from store
+     */
+    public boolean remove(URI uri, HttpCookie ck) {
+        // argument can't be null
+        if (ck == null) {
+            throw new NullPointerException("cookie is null");
+        }
+
+        // BEGIN Android-changed: Fix uri not being removed from uriIndex
+        lock.lock();
+        try {
+            uri = getEffectiveURI(uri);
+            if (uriIndex.get(uri) == null) {
+                return false;
+            } else {
+                List<HttpCookie> cookies = uriIndex.get(uri);
+                if (cookies != null) {
+                    return cookies.remove(ck);
+                } else {
+                    return false;
+                }
+            }
+        } finally {
+            lock.unlock();
+        }
+        // END Android-changed: Fix uri not being removed from uriIndex
+    }
+
+
+    /**
+     * Remove all cookies in this cookie store.
+     */
+    public boolean removeAll() {
+        lock.lock();
+        // BEGIN Android-changed: Let removeAll() return false when there are no cookies.
+        boolean result = false;
+
+        try {
+            result = !uriIndex.isEmpty();
+            uriIndex.clear();
+        } finally {
+            lock.unlock();
+        }
+
+        return result;
+        // END Android-changed: Let removeAll() return false when there are no cookies.
+    }
+
+
+    /* ---------------- Private operations -------------- */
+
+
+    /*
+     * This is almost the same as HttpCookie.domainMatches except for
+     * one difference: It won't reject cookies when the 'H' part of the
+     * domain contains a dot ('.').
+     * I.E.: RFC 2965 section 3.3.2 says that if host is x.y.domain.com
+     * and the cookie domain is .domain.com, then it should be rejected.
+     * However that's not how the real world works. Browsers don't reject and
+     * some sites, like yahoo.com do actually expect these cookies to be
+     * passed along.
+     * And should be used for 'old' style cookies (aka Netscape type of cookies)
+     */
+    private boolean netscapeDomainMatches(String domain, String host)
+    {
+        if (domain == null || host == null) {
+            return false;
+        }
+
+        // if there's no embedded dot in domain and domain is not .local
+        boolean isLocalDomain = ".local".equalsIgnoreCase(domain);
+        int embeddedDotInDomain = domain.indexOf('.');
+        if (embeddedDotInDomain == 0) {
+            embeddedDotInDomain = domain.indexOf('.', 1);
+        }
+        if (!isLocalDomain && (embeddedDotInDomain == -1 || embeddedDotInDomain == domain.length() - 1)) {
+            return false;
+        }
+
+        // if the host name contains no dot and the domain name is .local
+        int firstDotInHost = host.indexOf('.');
+        if (firstDotInHost == -1 && isLocalDomain) {
+            return true;
+        }
+
+        int domainLength = domain.length();
+        int lengthDiff = host.length() - domainLength;
+        if (lengthDiff == 0) {
+            // if the host name and the domain name are just string-compare euqal
+            return host.equalsIgnoreCase(domain);
+        } else if (lengthDiff > 0) {
+            // need to check H & D component
+            String D = host.substring(lengthDiff);
+
+            // Android-changed: b/26456024 targetSdkVersion based compatibility for domain matching
+            // Android M and earlier: Cookies with domain "foo.com" would not match "bar.foo.com".
+            // The RFC dictates that the user agent must treat those domains as if they had a
+            // leading period and must therefore match "bar.foo.com".
+            if (applyMCompatibility && !domain.startsWith(".")) {
+                return false;
+            }
+
+            return (D.equalsIgnoreCase(domain));
+        } else if (lengthDiff == -1) {
+            // if domain is actually .host
+            return (domain.charAt(0) == '.' &&
+                    host.equalsIgnoreCase(domain.substring(1)));
+        }
+
+        return false;
+    }
+
+    private void getInternal1(List<HttpCookie> cookies, Map<URI, List<HttpCookie>> cookieIndex,
+            String host) {
+        // BEGIN Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // Use a separate list to handle cookies that need to be removed so
+        // that there is no conflict with iterators.
+        ArrayList<HttpCookie> toRemove = new ArrayList<HttpCookie>();
+        for (Map.Entry<URI, List<HttpCookie>> entry : cookieIndex.entrySet()) {
+            List<HttpCookie> lst = entry.getValue();
+            for (HttpCookie c : lst) {
+                String domain = c.getDomain();
+                if ((c.getVersion() == 0 && netscapeDomainMatches(domain, host)) ||
+                        (c.getVersion() == 1 && HttpCookie.domainMatches(domain, host))) {
+
+                    // the cookie still in main cookie store
+                    if (!c.hasExpired()) {
+                        // don't add twice
+                        if (!cookies.contains(c)) {
+                            cookies.add(c);
+                        }
+                    } else {
+                        toRemove.add(c);
+                    }
+                }
+            }
+            // Clear up the cookies that need to be removed
+            for (HttpCookie c : toRemove) {
+                lst.remove(c);
+
+            }
+            toRemove.clear();
+        }
+        // END Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+    }
+
+    // @param cookies           [OUT] contains the found cookies
+    // @param cookieIndex       the index
+    // @param comparator        the prediction to decide whether or not
+    //                          a cookie in index should be returned
+    private <T extends Comparable<T>>
+        void getInternal2(List<HttpCookie> cookies, Map<T, List<HttpCookie>> cookieIndex,
+                          T comparator)
+    {
+        // BEGIN Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+        // Removed cookieJar
+        for (T index : cookieIndex.keySet()) {
+            if ((index == comparator) || (index != null && comparator.compareTo(index) == 0)) {
+                List<HttpCookie> indexedCookies = cookieIndex.get(index);
+                // check the list of cookies associated with this domain
+                if (indexedCookies != null) {
+                    Iterator<HttpCookie> it = indexedCookies.iterator();
+                    while (it.hasNext()) {
+                        HttpCookie ck = it.next();
+                        // the cookie still in main cookie store
+                        if (!ck.hasExpired()) {
+                            // don't add twice
+                            if (!cookies.contains(ck))
+                                cookies.add(ck);
+                        } else {
+                            it.remove();
+                        }
+                    }
+                } // end of indexedCookies != null
+            } // end of comparator.compareTo(index) == 0
+        } // end of cookieIndex iteration
+        // END Android-changed: b/25897688 InMemoryCookieStore ignores scheme (http/https)
+    }
+
+    // add 'cookie' indexed by 'index' into 'indexStore'
+    private <T> void addIndex(Map<T, List<HttpCookie>> indexStore,
+                              T index,
+                              HttpCookie cookie)
+    {
+        // Android-changed: "index" can be null. We only use the URI based
+        // index on Android and we want to support null URIs. The underlying
+        // store is a HashMap which will support null keys anyway.
+        // if (index != null) {
+        List<HttpCookie> cookies = indexStore.get(index);
+        if (cookies != null) {
+            // there may already have the same cookie, so remove it first
+            cookies.remove(cookie);
+
+            cookies.add(cookie);
+        } else {
+            cookies = new ArrayList<HttpCookie>();
+            cookies.add(cookie);
+            indexStore.put(index, cookies);
+        }
+    }
+
+
+    //
+    // for cookie purpose, the effective uri should only be http://host
+    // the path will be taken into account when path-match algorithm applied
+    //
+    private URI getEffectiveURI(URI uri) {
+        URI effectiveURI = null;
+        // Android-added: Fix NullPointerException
+        if (uri == null) {
+            return null;
+        }
+        try {
+            effectiveURI = new URI("http",
+                                   uri.getHost(),
+                                   null,  // path component
+                                   null,  // query component
+                                   null   // fragment component
+                                  );
+        } catch (URISyntaxException ignored) {
+            effectiveURI = uri;
+        }
+
+        return effectiveURI;
+    }
+}
diff --git a/java/net/Inet4Address.annotated.java b/java/net/Inet4Address.annotated.java
new file mode 100644
index 0000000..e10debf
--- /dev/null
+++ b/java/net/Inet4Address.annotated.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+import java.io.ObjectStreamException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Inet4Address extends java.net.InetAddress {
+
+Inet4Address() { throw new RuntimeException("Stub!"); }
+
+public boolean isMulticastAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnyLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLinkLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isSiteLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCGlobal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCNodeLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCLinkLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCSiteLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCOrgLocal() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostAddress() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress ALL;
+static { ALL = null; }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress ANY;
+static { ANY = null; }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress LOOPBACK;
+static { LOOPBACK = null; }
+}
+
diff --git a/java/net/Inet4Address.java b/java/net/Inet4Address.java
new file mode 100644
index 0000000..1fb7b92
--- /dev/null
+++ b/java/net/Inet4Address.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.ObjectStreamException;
+import static android.system.OsConstants.*;
+
+/**
+ * This class represents an Internet Protocol version 4 (IPv4) address.
+ * Defined by <a href="http://www.ietf.org/rfc/rfc790.txt">
+ * <i>RFC&nbsp;790: Assigned Numbers</i></a>,
+ * <a href="http://www.ietf.org/rfc/rfc1918.txt">
+ * <i>RFC&nbsp;1918: Address Allocation for Private Internets</i></a>,
+ * and <a href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC&nbsp;2365:
+ * Administratively Scoped IP Multicast</i></a>
+ *
+ * <h3> <A NAME="format">Textual representation of IP addresses</a> </h3>
+ *
+ * Textual representation of IPv4 address used as input to methods
+ * takes one of the following forms:
+ *
+ * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ * <tr><td>{@code d.d.d.d}</td></tr>
+ * <tr><td>{@code d.d.d}</td></tr>
+ * <tr><td>{@code d.d}</td></tr>
+ * <tr><td>{@code d}</td></tr>
+ * </table></blockquote>
+ *
+ * <p> When four parts are specified, each is interpreted as a byte of
+ * data and assigned, from left to right, to the four bytes of an IPv4
+ * address.
+
+ * <p> When a three part address is specified, the last part is
+ * interpreted as a 16-bit quantity and placed in the right most two
+ * bytes of the network address. This makes the three part address
+ * format convenient for specifying Class B net- work addresses as
+ * 128.net.host.
+ *
+ * <p> When a two part address is supplied, the last part is
+ * interpreted as a 24-bit quantity and placed in the right most three
+ * bytes of the network address. This makes the two part address
+ * format convenient for specifying Class A network addresses as
+ * net.host.
+ *
+ * <p> When only one part is given, the value is stored directly in
+ * the network address without any byte rearrangement.
+ *
+ * <p> For methods that return a textual representation as output
+ * value, the first form, i.e. a dotted-quad string, is used.
+ *
+ * <h4> The Scope of a Multicast Address </h4>
+ *
+ * Historically the IPv4 TTL field in the IP header has doubled as a
+ * multicast scope field: a TTL of 0 means node-local, 1 means
+ * link-local, up through 32 means site-local, up through 64 means
+ * region-local, up through 128 means continent-local, and up through
+ * 255 are global. However, the administrative scoping is preferred.
+ * Please refer to <a href="http://www.ietf.org/rfc/rfc2365.txt">
+ * <i>RFC&nbsp;2365: Administratively Scoped IP Multicast</i></a>
+ * @since 1.4
+ */
+
+public final
+class Inet4Address extends InetAddress {
+    final static int INADDRSZ = 4;
+
+    /** use serialVersionUID from InetAddress, but Inet4Address instance
+     *  is always replaced by an InetAddress instance before being
+     *  serialized */
+    private static final long serialVersionUID = 3286316764910316507L;
+
+    // BEGIN Android-added: Define special-purpose IPv4 address
+    /** @hide */
+    public static final InetAddress ANY = new Inet4Address(null, new byte[] { 0, 0, 0, 0 });
+
+    /** @hide */
+    public static final InetAddress ALL =
+            new Inet4Address(null, new byte[] { (byte) 255, (byte) 255,
+                  (byte) 255, (byte) 255 });
+    /** @hide */
+    public static final InetAddress LOOPBACK =
+            new Inet4Address("localhost", new byte[] { 127, 0, 0, 1 });
+    // END Android-added: Define special-purpose IPv4 address
+
+
+    // BEGIN Android-removed: Android doesn't need to call native init
+    /*
+     * Perform initializations.
+     *
+    static {
+        init();
+    }
+    */
+    // END Android-removed: Android doesn't need to call native init
+    Inet4Address() {
+        super();
+        holder().hostName = null;
+        holder().address = 0;
+        holder().family = AF_INET;
+    }
+
+    Inet4Address(String hostName, byte addr[]) {
+        holder().hostName = hostName;
+        holder().family = AF_INET;
+        if (addr != null) {
+            if (addr.length == INADDRSZ) {
+                int address  = addr[3] & 0xFF;
+                address |= ((addr[2] << 8) & 0xFF00);
+                address |= ((addr[1] << 16) & 0xFF0000);
+                address |= ((addr[0] << 24) & 0xFF000000);
+                holder().address = address;
+            }
+        }
+        holder().originalHostName = hostName;
+    }
+    Inet4Address(String hostName, int address) {
+        holder().hostName = hostName;
+        holder().family = AF_INET;
+        holder().address = address;
+        holder().originalHostName = hostName;
+    }
+
+    /**
+     * Replaces the object to be serialized with an InetAddress object.
+     *
+     * @return the alternate object to be serialized.
+     *
+     * @throws ObjectStreamException if a new object replacing this
+     * object could not be created
+     */
+    private Object writeReplace() throws ObjectStreamException {
+        // will replace the to be serialized 'this' object
+        InetAddress inet = new InetAddress();
+        inet.holder().hostName = holder().getHostName();
+        inet.holder().address = holder().getAddress();
+
+        /**
+         * Prior to 1.4 an InetAddress was created with a family
+         * based on the platform AF_INET value (usually 2).
+         * For compatibility reasons we must therefore write the
+         * the InetAddress with this family.
+         */
+        inet.holder().family = 2;
+
+        return inet;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an
+     * IP multicast address. IP multicast address is a Class D
+     * address i.e first four bits of the address are 1110.
+     * @return a {@code boolean} indicating if the InetAddress is
+     * an IP multicast address
+     * @since   JDK1.1
+     */
+    public boolean isMulticastAddress() {
+        return ((holder().getAddress() & 0xf0000000) == 0xe0000000);
+    }
+
+    /**
+     * Utility routine to check if the InetAddress in a wildcard address.
+     * @return a {@code boolean} indicating if the Inetaddress is
+     *         a wildcard address.
+     * @since 1.4
+     */
+    public boolean isAnyLocalAddress() {
+        return holder().getAddress() == 0;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is a loopback address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is
+     * a loopback address; or false otherwise.
+     * @since 1.4
+     */
+    public boolean isLoopbackAddress() {
+        /* 127.x.x.x */
+        byte[] byteAddr = getAddress();
+        return byteAddr[0] == 127;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an link local address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is
+     * a link local address; or false if address is not a link local unicast address.
+     * @since 1.4
+     */
+    public boolean isLinkLocalAddress() {
+        // link-local unicast in IPv4 (169.254.0.0/16)
+        // defined in "Documenting Special Use IPv4 Address Blocks
+        // that have been Registered with IANA" by Bill Manning
+        // draft-manning-dsua-06.txt
+        int address = holder().getAddress();
+        return (((address >>> 24) & 0xFF) == 169)
+            && (((address >>> 16) & 0xFF) == 254);
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is a site local address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is
+     * a site local address; or false if address is not a site local unicast address.
+     * @since 1.4
+     */
+    public boolean isSiteLocalAddress() {
+        // refer to RFC 1918
+        // 10/8 prefix
+        // 172.16/12 prefix
+        // 192.168/16 prefix
+        int address = holder().getAddress();
+        return (((address >>> 24) & 0xFF) == 10)
+            || ((((address >>> 24) & 0xFF) == 172)
+                && (((address >>> 16) & 0xF0) == 16))
+            || ((((address >>> 24) & 0xFF) == 192)
+                && (((address >>> 16) & 0xFF) == 168));
+    }
+
+    /**
+     * Utility routine to check if the multicast address has global scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of global scope, false if it is not
+     *         of global scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCGlobal() {
+        // 224.0.1.0 to 238.255.255.255
+        byte[] byteAddr = getAddress();
+        return ((byteAddr[0] & 0xff) >= 224 && (byteAddr[0] & 0xff) <= 238 ) &&
+            !((byteAddr[0] & 0xff) == 224 && byteAddr[1] == 0 &&
+              byteAddr[2] == 0);
+    }
+
+    /**
+     * Utility routine to check if the multicast address has node scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of node-local scope, false if it is not
+     *         of node-local scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCNodeLocal() {
+        // unless ttl == 0
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the multicast address has link scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of link-local scope, false if it is not
+     *         of link-local scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCLinkLocal() {
+        // 224.0.0/24 prefix and ttl == 1
+        int address = holder().getAddress();
+        return (((address >>> 24) & 0xFF) == 224)
+            && (((address >>> 16) & 0xFF) == 0)
+            && (((address >>> 8) & 0xFF) == 0);
+    }
+
+    /**
+     * Utility routine to check if the multicast address has site scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of site-local scope, false if it is not
+     *         of site-local scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCSiteLocal() {
+        // 239.255/16 prefix or ttl < 32
+        int address = holder().getAddress();
+        return (((address >>> 24) & 0xFF) == 239)
+            && (((address >>> 16) & 0xFF) == 255);
+    }
+
+    /**
+     * Utility routine to check if the multicast address has organization scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of organization-local scope,
+     *         false if it is not of organization-local scope
+     *         or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCOrgLocal() {
+        // 239.192 - 239.195
+        int address = holder().getAddress();
+        return (((address >>> 24) & 0xFF) == 239)
+            && (((address >>> 16) & 0xFF) >= 192)
+            && (((address >>> 16) & 0xFF) <= 195);
+    }
+
+    /**
+     * Returns the raw IP address of this {@code InetAddress}
+     * object. The result is in network byte order: the highest order
+     * byte of the address is in {@code getAddress()[0]}.
+     *
+     * @return  the raw IP address of this object.
+     */
+    public byte[] getAddress() {
+        int address = holder().getAddress();
+        byte[] addr = new byte[INADDRSZ];
+
+        addr[0] = (byte) ((address >>> 24) & 0xFF);
+        addr[1] = (byte) ((address >>> 16) & 0xFF);
+        addr[2] = (byte) ((address >>> 8) & 0xFF);
+        addr[3] = (byte) (address & 0xFF);
+        return addr;
+    }
+
+    /**
+     * Returns the IP address string in textual presentation form.
+     *
+     * @return  the raw IP address in a string format.
+     * @since   JDK1.0.2
+     */
+    public String getHostAddress() {
+        return numericToTextFormat(getAddress());
+    }
+
+    /**
+     * Returns a hashcode for this IP address.
+     *
+     * @return  a hash code value for this IP address.
+     */
+    public int hashCode() {
+        return holder().getAddress();
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is
+     * not {@code null} and it represents the same IP address as
+     * this object.
+     * <p>
+     * Two instances of {@code InetAddress} represent the same IP
+     * address if the length of the byte arrays returned by
+     * {@code getAddress} is the same for both, and each of the
+     * array components is the same for the byte arrays.
+     *
+     * @param   obj   the object to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see     java.net.InetAddress#getAddress()
+     */
+    public boolean equals(Object obj) {
+        return (obj != null) && (obj instanceof Inet4Address) &&
+            (((InetAddress)obj).holder().getAddress() == holder().getAddress());
+    }
+
+    // Utilities
+    /*
+     * Converts IPv4 binary address into a string suitable for presentation.
+     *
+     * @param src a byte array representing an IPv4 numeric address
+     * @return a String representing the IPv4 address in
+     *         textual representation format
+     * @since 1.4
+     */
+
+    static String numericToTextFormat(byte[] src)
+    {
+        return (src[0] & 0xff) + "." + (src[1] & 0xff) + "." + (src[2] & 0xff) + "." + (src[3] & 0xff);
+    }
+
+    // BEGIN Android-removed: Android doesn't need to call native init
+    /*
+     * Perform class load-time initializations.
+     *
+    private static native void init();
+    */
+    // END Android-removed: Android doesn't need to call native init
+}
diff --git a/java/net/Inet6Address.annotated.java b/java/net/Inet6Address.annotated.java
new file mode 100644
index 0000000..7888710
--- /dev/null
+++ b/java/net/Inet6Address.annotated.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+
+@libcore.api.CorePlatformApi
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public final class Inet6Address extends java.net.InetAddress {
+
+Inet6Address() { throw new RuntimeException("Stub!"); }
+
+public static java.net.Inet6Address getByAddress(java.lang.String host, byte[] addr, java.net.NetworkInterface nif) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.Inet6Address getByAddress(java.lang.String host, byte[] addr, int scope_id) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public boolean isMulticastAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnyLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLinkLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isSiteLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCGlobal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCNodeLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCLinkLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCSiteLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCOrgLocal() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public int getScopeId() { throw new RuntimeException("Stub!"); }
+
+public java.net.NetworkInterface getScopedInterface() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostAddress() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public boolean isIPv4CompatibleAddress() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress ANY;
+static { ANY = null; }
+
+@libcore.api.CorePlatformApi
+public static final java.net.InetAddress LOOPBACK;
+static { LOOPBACK = null; }
+}
diff --git a/java/net/Inet6Address.java b/java/net/Inet6Address.java
new file mode 100644
index 0000000..c0aadb3
--- /dev/null
+++ b/java/net/Inet6Address.java
@@ -0,0 +1,981 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamField;
+import java.util.Enumeration;
+import java.util.Arrays;
+import libcore.io.Libcore;
+import static android.system.OsConstants.*;
+
+/**
+ * This class represents an Internet Protocol version 6 (IPv6) address.
+ * Defined by <a href="http://www.ietf.org/rfc/rfc2373.txt">
+ * <i>RFC&nbsp;2373: IP Version 6 Addressing Architecture</i></a>.
+ *
+ * <h3> <A NAME="format">Textual representation of IP addresses</a> </h3>
+ *
+ * Textual representation of IPv6 address used as input to methods
+ * takes one of the following forms:
+ *
+ * <ol>
+ *   <li><p> <A NAME="lform">The preferred form</a> is x:x:x:x:x:x:x:x,
+ *   where the 'x's are
+ *   the hexadecimal values of the eight 16-bit pieces of the
+ *   address. This is the full form.  For example,
+ *
+ *   <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ *   <tr><td>{@code 1080:0:0:0:8:800:200C:417A}<td></tr>
+ *   </table></blockquote>
+ *
+ *   <p> Note that it is not necessary to write the leading zeros in
+ *   an individual field. However, there must be at least one numeral
+ *   in every field, except as described below.</li>
+ *
+ *   <li><p> Due to some methods of allocating certain styles of IPv6
+ *   addresses, it will be common for addresses to contain long
+ *   strings of zero bits. In order to make writing addresses
+ *   containing zero bits easier, a special syntax is available to
+ *   compress the zeros. The use of "::" indicates multiple groups
+ *   of 16-bits of zeros. The "::" can only appear once in an address.
+ *   The "::" can also be used to compress the leading and/or trailing
+ *   zeros in an address. For example,
+ *
+ *   <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ *   <tr><td>{@code 1080::8:800:200C:417A}<td></tr>
+ *   </table></blockquote>
+ *
+ *   <li><p> An alternative form that is sometimes more convenient
+ *   when dealing with a mixed environment of IPv4 and IPv6 nodes is
+ *   x:x:x:x:x:x:d.d.d.d, where the 'x's are the hexadecimal values
+ *   of the six high-order 16-bit pieces of the address, and the 'd's
+ *   are the decimal values of the four low-order 8-bit pieces of the
+ *   standard IPv4 representation address, for example,
+ *
+ *   <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ *   <tr><td>{@code ::FFFF:129.144.52.38}<td></tr>
+ *   <tr><td>{@code ::129.144.52.38}<td></tr>
+ *   </table></blockquote>
+ *
+ *   <p> where "::FFFF:d.d.d.d" and "::d.d.d.d" are, respectively, the
+ *   general forms of an IPv4-mapped IPv6 address and an
+ *   IPv4-compatible IPv6 address. Note that the IPv4 portion must be
+ *   in the "d.d.d.d" form. The following forms are invalid:
+ *
+ *   <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ *   <tr><td>{@code ::FFFF:d.d.d}<td></tr>
+ *   <tr><td>{@code ::FFFF:d.d}<td></tr>
+ *   <tr><td>{@code ::d.d.d}<td></tr>
+ *   <tr><td>{@code ::d.d}<td></tr>
+ *   </table></blockquote>
+ *
+ *   <p> The following form:
+ *
+ *   <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ *   <tr><td>{@code ::FFFF:d}<td></tr>
+ *   </table></blockquote>
+ *
+ *   <p> is valid, however it is an unconventional representation of
+ *   the IPv4-compatible IPv6 address,
+ *
+ *   <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ *   <tr><td>{@code ::255.255.0.d}<td></tr>
+ *   </table></blockquote>
+ *
+ *   <p> while "::d" corresponds to the general IPv6 address
+ *   "0:0:0:0:0:0:0:d".</li>
+ * </ol>
+ *
+ * <p> For methods that return a textual representation as output
+ * value, the full form is used. Inet6Address will return the full
+ * form because it is unambiguous when used in combination with other
+ * textual data.
+ *
+ * <h4> Special IPv6 address </h4>
+ *
+ * <blockquote>
+ * <table cellspacing=2 summary="Description of IPv4-mapped address">
+ * <tr><th valign=top><i>IPv4-mapped address</i></th>
+ *         <td>Of the form::ffff:w.x.y.z, this IPv6 address is used to
+ *         represent an IPv4 address. It allows the native program to
+ *         use the same address data structure and also the same
+ *         socket when communicating with both IPv4 and IPv6 nodes.
+ *
+ *         <p>In InetAddress and Inet6Address, it is used for internal
+ *         representation; it has no functional role. Java will never
+ *         return an IPv4-mapped address.  These classes can take an
+ *         IPv4-mapped address as input, both in byte array and text
+ *         representation. However, it will be converted into an IPv4
+ *         address.</td></tr>
+ * </table></blockquote>
+ *
+ * <h4><A NAME="scoped">Textual representation of IPv6 scoped addresses</a></h4>
+ *
+ * <p> The textual representation of IPv6 addresses as described above can be
+ * extended to specify IPv6 scoped addresses. This extension to the basic
+ * addressing architecture is described in [draft-ietf-ipngwg-scoping-arch-04.txt].
+ *
+ * <p> Because link-local and site-local addresses are non-global, it is possible
+ * that different hosts may have the same destination address and may be
+ * reachable through different interfaces on the same originating system. In
+ * this case, the originating system is said to be connected to multiple zones
+ * of the same scope. In order to disambiguate which is the intended destination
+ * zone, it is possible to append a zone identifier (or <i>scope_id</i>) to an
+ * IPv6 address.
+ *
+ * <p> The general format for specifying the <i>scope_id</i> is the following:
+ *
+ * <blockquote><i>IPv6-address</i>%<i>scope_id</i></blockquote>
+ * <p> The IPv6-address is a literal IPv6 address as described above.
+ * The <i>scope_id</i> refers to an interface on the local system, and it can be
+ * specified in two ways.
+ * <ol><li><i>As a numeric identifier.</i> This must be a positive integer
+ * that identifies the particular interface and scope as understood by the
+ * system. Usually, the numeric values can be determined through administration
+ * tools on the system. Each interface may have multiple values, one for each
+ * scope. If the scope is unspecified, then the default value used is zero.</li>
+ * <li><i>As a string.</i> This must be the exact string that is returned by
+ * {@link java.net.NetworkInterface#getName()} for the particular interface in
+ * question. When an Inet6Address is created in this way, the numeric scope-id
+ * is determined at the time the object is created by querying the relevant
+ * NetworkInterface.</li></ol>
+ *
+ * <p> Note also, that the numeric <i>scope_id</i> can be retrieved from
+ * Inet6Address instances returned from the NetworkInterface class. This can be
+ * used to find out the current scope ids configured on the system.
+ * @since 1.4
+ */
+
+public final
+class Inet6Address extends InetAddress {
+    final static int INADDRSZ = 16;
+
+    // BEGIN Android-removed: Remove special handling for link-local addresses
+    /*
+    * cached scope_id - for link-local address use only.
+    *
+    private transient int cached_scope_id;  // 0
+    */
+    // END Android-removed: Remove special handling for link-local addresses
+
+    // BEGIN Android-added: Define special-purpose IPv6 address
+    /** @hide */
+    public static final InetAddress ANY =
+            new Inet6Address("::", new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0);
+
+    /** @hide */
+    public static final InetAddress LOOPBACK = new Inet6Address("ip6-localhost",
+            new byte[] {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 0);
+    // END Android-added: Define special-purpose IPv6 address
+
+    private class Inet6AddressHolder {
+
+        private Inet6AddressHolder() {
+            ipaddress = new byte[INADDRSZ];
+        }
+
+        private Inet6AddressHolder(
+            byte[] ipaddress, int scope_id, boolean scope_id_set,
+            NetworkInterface ifname, boolean scope_ifname_set)
+        {
+            this.ipaddress = ipaddress;
+            this.scope_id = scope_id;
+            this.scope_id_set = scope_id_set;
+            this.scope_ifname_set = scope_ifname_set;
+            this.scope_ifname = ifname;
+        }
+
+        /**
+         * Holds a 128-bit (16 bytes) IPv6 address.
+         */
+        byte[] ipaddress;
+
+        /**
+         * scope_id. The scope specified when the object is created. If the object
+         * is created with an interface name, then the scope_id is not determined
+         * until the time it is needed.
+         */
+        int scope_id;  // 0
+
+        /**
+         * This will be set to true when the scope_id field contains a valid
+         * integer scope_id.
+         */
+        boolean scope_id_set;  // false
+
+        /**
+         * scoped interface. scope_id is derived from this as the scope_id of the first
+         * address whose scope is the same as this address for the named interface.
+         */
+        NetworkInterface scope_ifname;  // null
+
+        /**
+         * set if the object is constructed with a scoped
+         * interface instead of a numeric scope id.
+         */
+        boolean scope_ifname_set; // false;
+
+        void setAddr(byte addr[]) {
+            if (addr.length == INADDRSZ) { // normal IPv6 address
+                System.arraycopy(addr, 0, ipaddress, 0, INADDRSZ);
+            }
+        }
+
+        void init(byte addr[], int scope_id) {
+            setAddr(addr);
+
+            // Android-changed: was >= 0
+            if (scope_id > 0) {
+                this.scope_id = scope_id;
+                this.scope_id_set = true;
+            }
+        }
+
+        void init(byte addr[], NetworkInterface nif)
+            throws UnknownHostException
+        {
+            setAddr(addr);
+
+            if (nif != null) {
+                this.scope_id = deriveNumericScope(ipaddress, nif);
+                this.scope_id_set = true;
+                this.scope_ifname = nif;
+                this.scope_ifname_set = true;
+            }
+        }
+
+        // Android-removed: getnameinfo returns smarter representations than getHostAddress()
+        /*
+        String getHostAddress() {
+            String s = numericToTextFormat(ipaddress);
+            if (scope_ifname != null) { // must check this first
+                s = s + "%" + scope_ifname.getName();
+            } else if (scope_id_set) {
+                s = s + "%" + scope_id;
+            }
+            return s;
+        }
+        */
+
+        public boolean equals(Object o) {
+            if (! (o instanceof Inet6AddressHolder)) {
+                return false;
+            }
+            Inet6AddressHolder that = (Inet6AddressHolder)o;
+
+            return Arrays.equals(this.ipaddress, that.ipaddress);
+        }
+
+        public int hashCode() {
+            if (ipaddress != null) {
+
+                int hash = 0;
+                int i=0;
+                while (i<INADDRSZ) {
+                    int j=0;
+                    int component=0;
+                    while (j<4 && i<INADDRSZ) {
+                        component = (component << 8) + ipaddress[i];
+                        j++;
+                        i++;
+                    }
+                    hash += component;
+                }
+                return hash;
+
+            } else {
+                return 0;
+            }
+        }
+
+        boolean isIPv4CompatibleAddress() {
+            if ((ipaddress[0] == 0x00) && (ipaddress[1] == 0x00) &&
+                (ipaddress[2] == 0x00) && (ipaddress[3] == 0x00) &&
+                (ipaddress[4] == 0x00) && (ipaddress[5] == 0x00) &&
+                (ipaddress[6] == 0x00) && (ipaddress[7] == 0x00) &&
+                (ipaddress[8] == 0x00) && (ipaddress[9] == 0x00) &&
+                (ipaddress[10] == 0x00) && (ipaddress[11] == 0x00))  {
+                return true;
+            }
+            return false;
+        }
+
+        boolean isMulticastAddress() {
+            return ((ipaddress[0] & 0xff) == 0xff);
+        }
+
+        boolean isAnyLocalAddress() {
+            byte test = 0x00;
+            for (int i = 0; i < INADDRSZ; i++) {
+                test |= ipaddress[i];
+            }
+            return (test == 0x00);
+        }
+
+        boolean isLoopbackAddress() {
+            byte test = 0x00;
+            for (int i = 0; i < 15; i++) {
+                test |= ipaddress[i];
+            }
+            return (test == 0x00) && (ipaddress[15] == 0x01);
+        }
+
+        boolean isLinkLocalAddress() {
+            return ((ipaddress[0] & 0xff) == 0xfe
+                    && (ipaddress[1] & 0xc0) == 0x80);
+        }
+
+
+        boolean isSiteLocalAddress() {
+            return ((ipaddress[0] & 0xff) == 0xfe
+                    && (ipaddress[1] & 0xc0) == 0xc0);
+        }
+
+        boolean isMCGlobal() {
+            return ((ipaddress[0] & 0xff) == 0xff
+                    && (ipaddress[1] & 0x0f) == 0x0e);
+        }
+
+        boolean isMCNodeLocal() {
+            return ((ipaddress[0] & 0xff) == 0xff
+                    && (ipaddress[1] & 0x0f) == 0x01);
+        }
+
+        boolean isMCLinkLocal() {
+            return ((ipaddress[0] & 0xff) == 0xff
+                    && (ipaddress[1] & 0x0f) == 0x02);
+        }
+
+        boolean isMCSiteLocal() {
+            return ((ipaddress[0] & 0xff) == 0xff
+                    && (ipaddress[1] & 0x0f) == 0x05);
+        }
+
+        boolean isMCOrgLocal() {
+            return ((ipaddress[0] & 0xff) == 0xff
+                    && (ipaddress[1] & 0x0f) == 0x08);
+        }
+    }
+
+    private final transient Inet6AddressHolder holder6;
+
+    private static final long serialVersionUID = 6880410070516793377L;
+
+    // BEGIN Android-removed: Android doesn't need to call native init
+    /*
+    // Perform native initialization
+    static { init(); }
+    // END Android-removed: Android doesn't need to call native init
+    */
+
+    Inet6Address() {
+        super();
+        holder.init(null, AF_INET6);
+        holder6 = new Inet6AddressHolder();
+    }
+
+    /* checking of value for scope_id should be done by caller
+     * scope_id must be >= 0, or -1 to indicate not being set
+     */
+    Inet6Address(String hostName, byte addr[], int scope_id) {
+        holder.init(hostName, AF_INET6);
+        holder6 = new Inet6AddressHolder();
+        holder6.init(addr, scope_id);
+    }
+
+    Inet6Address(String hostName, byte addr[]) {
+        holder6 = new Inet6AddressHolder();
+        try {
+            initif (hostName, addr, null);
+        } catch (UnknownHostException e) {} /* cant happen if ifname is null */
+    }
+
+    Inet6Address (String hostName, byte addr[], NetworkInterface nif)
+        throws UnknownHostException
+    {
+        holder6 = new Inet6AddressHolder();
+        initif (hostName, addr, nif);
+    }
+
+    Inet6Address (String hostName, byte addr[], String ifname)
+        throws UnknownHostException
+    {
+        holder6 = new Inet6AddressHolder();
+        initstr (hostName, addr, ifname);
+    }
+
+    /**
+     * Create an Inet6Address in the exact manner of {@link
+     * InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is
+     * set to the value corresponding to the given interface for the address
+     * type specified in {@code addr}. The call will fail with an
+     * UnknownHostException if the given interface does not have a numeric
+     * scope_id assigned for the given address type (eg. link-local or site-local).
+     * See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
+     * scoped addresses.
+     *
+     * @param host the specified host
+     * @param addr the raw IP address in network byte order
+     * @param nif an interface this address must be associated with.
+     * @return  an Inet6Address object created from the raw IP address.
+     * @throws  UnknownHostException
+     *          if IP address is of illegal length, or if the interface does not
+     *          have a numeric scope_id assigned for the given address type.
+     *
+     * @since 1.5
+     */
+    public static Inet6Address getByAddress(String host, byte[] addr,
+                                            NetworkInterface nif)
+        throws UnknownHostException
+    {
+        if (host != null && host.length() > 0 && host.charAt(0) == '[') {
+            if (host.charAt(host.length()-1) == ']') {
+                host = host.substring(1, host.length() -1);
+            }
+        }
+        if (addr != null) {
+            if (addr.length == Inet6Address.INADDRSZ) {
+                return new Inet6Address(host, addr, nif);
+            }
+        }
+        throw new UnknownHostException("addr is of illegal length");
+    }
+
+    /**
+     * Create an Inet6Address in the exact manner of {@link
+     * InetAddress#getByAddress(String,byte[])} except that the IPv6 scope_id is
+     * set to the given numeric value. The scope_id is not checked to determine
+     * if it corresponds to any interface on the system.
+     * See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
+     * scoped addresses.
+     *
+     * @param host the specified host
+     * @param addr the raw IP address in network byte order
+     * @param scope_id the numeric scope_id for the address.
+     * @return  an Inet6Address object created from the raw IP address.
+     * @throws  UnknownHostException  if IP address is of illegal length.
+     *
+     * @since 1.5
+     */
+    public static Inet6Address getByAddress(String host, byte[] addr,
+                                            int scope_id)
+        throws UnknownHostException
+    {
+        if (host != null && host.length() > 0 && host.charAt(0) == '[') {
+            if (host.charAt(host.length()-1) == ']') {
+                host = host.substring(1, host.length() -1);
+            }
+        }
+        if (addr != null) {
+            if (addr.length == Inet6Address.INADDRSZ) {
+                return new Inet6Address(host, addr, scope_id);
+            }
+        }
+        throw new UnknownHostException("addr is of illegal length");
+    }
+
+    private void initstr(String hostName, byte addr[], String ifname)
+        throws UnknownHostException
+    {
+        try {
+            NetworkInterface nif = NetworkInterface.getByName (ifname);
+            if (nif == null) {
+                throw new UnknownHostException ("no such interface " + ifname);
+            }
+            initif (hostName, addr, nif);
+        } catch (SocketException e) {
+            throw new UnknownHostException ("SocketException thrown" + ifname);
+        }
+    }
+
+    private void initif(String hostName, byte addr[], NetworkInterface nif)
+        throws UnknownHostException
+    {
+        int family = -1;
+        holder6.init(addr, nif);
+
+        if (addr.length == INADDRSZ) { // normal IPv6 address
+            family = AF_INET6;
+        }
+        holder.init(hostName, family);
+    }
+
+    /* check the two Ipv6 addresses and return false if they are both
+     * non global address types, but not the same.
+     * (ie. one is sitelocal and the other linklocal)
+     * return true otherwise.
+     */
+
+    private static boolean isDifferentLocalAddressType(
+        byte[] thisAddr, byte[] otherAddr) {
+
+        if (Inet6Address.isLinkLocalAddress(thisAddr) &&
+                !Inet6Address.isLinkLocalAddress(otherAddr)) {
+            return false;
+        }
+        if (Inet6Address.isSiteLocalAddress(thisAddr) &&
+                !Inet6Address.isSiteLocalAddress(otherAddr)) {
+            return false;
+        }
+        return true;
+    }
+
+    private static int deriveNumericScope (byte[] thisAddr, NetworkInterface ifc) throws UnknownHostException {
+        Enumeration<InetAddress> addresses = ifc.getInetAddresses();
+        while (addresses.hasMoreElements()) {
+            InetAddress addr = addresses.nextElement();
+            if (!(addr instanceof Inet6Address)) {
+                continue;
+            }
+            Inet6Address ia6_addr = (Inet6Address)addr;
+            /* check if site or link local prefixes match */
+            if (!isDifferentLocalAddressType(thisAddr, ia6_addr.getAddress())){
+                /* type not the same, so carry on searching */
+                continue;
+            }
+            /* found a matching address - return its scope_id */
+            return ia6_addr.getScopeId();
+        }
+        throw new UnknownHostException ("no scope_id found");
+    }
+
+    private int deriveNumericScope (String ifname) throws UnknownHostException {
+        Enumeration<NetworkInterface> en;
+        try {
+            en = NetworkInterface.getNetworkInterfaces();
+        } catch (SocketException e) {
+            throw new UnknownHostException ("could not enumerate local network interfaces");
+        }
+        while (en.hasMoreElements()) {
+            NetworkInterface ifc = en.nextElement();
+            if (ifc.getName().equals (ifname)) {
+                return deriveNumericScope(holder6.ipaddress, ifc);
+            }
+        }
+        throw new UnknownHostException ("No matching address found for interface : " +ifname);
+    }
+
+    /**
+     * @serialField ipaddress byte[]
+     * @serialField scope_id int
+     * @serialField scope_id_set boolean
+     * @serialField scope_ifname_set boolean
+     * @serialField ifname String
+     */
+
+    private static final ObjectStreamField[] serialPersistentFields = {
+         new ObjectStreamField("ipaddress", byte[].class),
+         new ObjectStreamField("scope_id", int.class),
+         new ObjectStreamField("scope_id_set", boolean.class),
+         new ObjectStreamField("scope_ifname_set", boolean.class),
+         new ObjectStreamField("ifname", String.class)
+    };
+
+    private static final long FIELDS_OFFSET;
+    private static final sun.misc.Unsafe UNSAFE;
+
+    static {
+        try {
+            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            FIELDS_OFFSET = unsafe.objectFieldOffset(
+                    Inet6Address.class.getDeclaredField("holder6"));
+            UNSAFE = unsafe;
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
+    /**
+     * restore the state of this object from stream
+     * including the scope information, only if the
+     * scoped interface name is valid on this system
+     */
+    private void readObject(ObjectInputStream s)
+        throws IOException, ClassNotFoundException {
+        NetworkInterface scope_ifname = null;
+
+        // Android-changed: was getClass().getClassLoader() != null
+        if (getClass().getClassLoader() != Class.class.getClassLoader()) {
+            throw new SecurityException ("invalid address type");
+        }
+
+        ObjectInputStream.GetField gf = s.readFields();
+        byte[] ipaddress = (byte[])gf.get("ipaddress", null);
+        int scope_id = (int)gf.get("scope_id", -1);
+        boolean scope_id_set = (boolean)gf.get("scope_id_set", false);
+        boolean scope_ifname_set = (boolean)gf.get("scope_ifname_set", false);
+        String ifname = (String)gf.get("ifname", null);
+
+        if (ifname != null && !"".equals (ifname)) {
+            try {
+                scope_ifname = NetworkInterface.getByName(ifname);
+                if (scope_ifname == null) {
+                    /* the interface does not exist on this system, so we clear
+                     * the scope information completely */
+                    scope_id_set = false;
+                    scope_ifname_set = false;
+                    scope_id = 0;
+                } else {
+                    scope_ifname_set = true;
+                    try {
+                        scope_id = deriveNumericScope (ipaddress, scope_ifname);
+                    } catch (UnknownHostException e) {
+                        // typically should not happen, but it may be that
+                        // the machine being used for deserialization has
+                        // the same interface name but without IPv6 configured.
+                    }
+                }
+            } catch (SocketException e) {}
+        }
+
+        /* if ifname was not supplied, then the numeric info is used */
+
+        ipaddress = ipaddress.clone();
+
+        // Check that our invariants are satisfied
+        if (ipaddress.length != INADDRSZ) {
+            throw new InvalidObjectException("invalid address length: "+
+                                             ipaddress.length);
+        }
+
+        if (holder().getFamily() != AF_INET6) {
+            throw new InvalidObjectException("invalid address family type");
+        }
+
+        Inet6AddressHolder h = new Inet6AddressHolder(
+            ipaddress, scope_id, scope_id_set, scope_ifname, scope_ifname_set
+        );
+
+        UNSAFE.putObject(this, FIELDS_OFFSET, h);
+    }
+
+    /**
+     * default behavior is overridden in order to write the
+     * scope_ifname field as a String, rather than a NetworkInterface
+     * which is not serializable
+     */
+    private synchronized void writeObject(ObjectOutputStream s)
+        throws IOException
+    {
+            String ifname = null;
+
+        if (holder6.scope_ifname != null) {
+            ifname = holder6.scope_ifname.getName();
+            holder6.scope_ifname_set = true;
+        }
+        ObjectOutputStream.PutField pfields = s.putFields();
+        pfields.put("ipaddress", holder6.ipaddress);
+        pfields.put("scope_id", holder6.scope_id);
+        pfields.put("scope_id_set", holder6.scope_id_set);
+        pfields.put("scope_ifname_set", holder6.scope_ifname_set);
+        pfields.put("ifname", ifname);
+        s.writeFields();
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an IP multicast
+     * address. 11111111 at the start of the address identifies the
+     * address as being a multicast address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is an IP
+     *         multicast address
+     *
+     * @since JDK1.1
+     */
+    @Override
+    public boolean isMulticastAddress() {
+        return holder6.isMulticastAddress();
+    }
+
+    /**
+     * Utility routine to check if the InetAddress in a wildcard address.
+     *
+     * @return a {@code boolean} indicating if the Inetaddress is
+     *         a wildcard address.
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isAnyLocalAddress() {
+        return holder6.isAnyLocalAddress();
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is a loopback address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is a loopback
+     *         address; or false otherwise.
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isLoopbackAddress() {
+        return holder6.isLoopbackAddress();
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an link local address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is a link local
+     *         address; or false if address is not a link local unicast address.
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isLinkLocalAddress() {
+        return holder6.isLinkLocalAddress();
+    }
+
+    /* static version of above */
+    static boolean isLinkLocalAddress(byte[] ipaddress) {
+        return ((ipaddress[0] & 0xff) == 0xfe
+                && (ipaddress[1] & 0xc0) == 0x80);
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is a site local address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is a site local
+     *         address; or false if address is not a site local unicast address.
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isSiteLocalAddress() {
+        return holder6.isSiteLocalAddress();
+    }
+
+    /* static version of above */
+    static boolean isSiteLocalAddress(byte[] ipaddress) {
+        return ((ipaddress[0] & 0xff) == 0xfe
+                && (ipaddress[1] & 0xc0) == 0xc0);
+    }
+
+    /**
+     * Utility routine to check if the multicast address has global scope.
+     *
+     * @return a {@code boolean} indicating if the address has is a multicast
+     *         address of global scope, false if it is not of global scope or
+     *         it is not a multicast address
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isMCGlobal() {
+        return holder6.isMCGlobal();
+    }
+
+    /**
+     * Utility routine to check if the multicast address has node scope.
+     *
+     * @return a {@code boolean} indicating if the address has is a multicast
+     *         address of node-local scope, false if it is not of node-local
+     *         scope or it is not a multicast address
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isMCNodeLocal() {
+        return holder6.isMCNodeLocal();
+    }
+
+    /**
+     * Utility routine to check if the multicast address has link scope.
+     *
+     * @return a {@code boolean} indicating if the address has is a multicast
+     *         address of link-local scope, false if it is not of link-local
+     *         scope or it is not a multicast address
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isMCLinkLocal() {
+        return holder6.isMCLinkLocal();
+    }
+
+    /**
+     * Utility routine to check if the multicast address has site scope.
+     *
+     * @return a {@code boolean} indicating if the address has is a multicast
+     *         address of site-local scope, false if it is not  of site-local
+     *         scope or it is not a multicast address
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isMCSiteLocal() {
+        return holder6.isMCSiteLocal();
+    }
+
+    /**
+     * Utility routine to check if the multicast address has organization scope.
+     *
+     * @return a {@code boolean} indicating if the address has is a multicast
+     *         address of organization-local scope, false if it is not of
+     *         organization-local scope or it is not a multicast address
+     *
+     * @since 1.4
+     */
+    @Override
+    public boolean isMCOrgLocal() {
+        return holder6.isMCOrgLocal();
+    }
+    /**
+     * Returns the raw IP address of this {@code InetAddress} object. The result
+     * is in network byte order: the highest order byte of the address is in
+     * {@code getAddress()[0]}.
+     *
+     * @return  the raw IP address of this object.
+     */
+    @Override
+    public byte[] getAddress() {
+        return holder6.ipaddress.clone();
+    }
+
+    /**
+     * Returns the numeric scopeId, if this instance is associated with
+     * an interface. If no scoped_id is set, the returned value is zero.
+     *
+     * @return the scopeId, or zero if not set.
+     *
+     * @since 1.5
+     */
+     public int getScopeId() {
+        return holder6.scope_id;
+     }
+
+    /**
+     * Returns the scoped interface, if this instance was created with
+     * with a scoped interface.
+     *
+     * @return the scoped interface, or null if not set.
+     * @since 1.5
+     */
+     public NetworkInterface getScopedInterface() {
+        return holder6.scope_ifname;
+     }
+
+    /**
+     * Returns the IP address string in textual presentation. If the instance
+     * was created specifying a scope identifier then the scope id is appended
+     * to the IP address preceded by a "%" (per-cent) character. This can be
+     * either a numeric value or a string, depending on which was used to create
+     * the instance.
+     *
+     * @return  the raw IP address in a string format.
+     */
+    @Override
+    public String getHostAddress() {
+        // Android-changed: getnameinfo returns smarter representations than getHostAddress()
+        // return holder6.getHostAddress();
+        return Libcore.os.getnameinfo(this, NI_NUMERICHOST); // Can't throw.
+    }
+
+    /**
+     * Returns a hashcode for this IP address.
+     *
+     * @return  a hash code value for this IP address.
+     */
+    @Override
+    public int hashCode() {
+        return holder6.hashCode();
+    }
+
+    /**
+     * Compares this object against the specified object. The result is {@code
+     * true} if and only if the argument is not {@code null} and it represents
+     * the same IP address as this object.
+     *
+     * <p> Two instances of {@code InetAddress} represent the same IP address
+     * if the length of the byte arrays returned by {@code getAddress} is the
+     * same for both, and each of the array components is the same for the byte
+     * arrays.
+     *
+     * @param   obj   the object to compare against.
+     *
+     * @return  {@code true} if the objects are the same; {@code false} otherwise.
+     *
+     * @see     java.net.InetAddress#getAddress()
+     */
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof Inet6Address))
+            return false;
+
+        Inet6Address inetAddr = (Inet6Address)obj;
+
+        return holder6.equals(inetAddr.holder6);
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an
+     * IPv4 compatible IPv6 address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is an IPv4
+     *         compatible IPv6 address; or false if address is IPv4 address.
+     *
+     * @since 1.4
+     */
+    public boolean isIPv4CompatibleAddress() {
+        return holder6.isIPv4CompatibleAddress();
+    }
+
+    // Utilities
+    private final static int INT16SZ = 2;
+
+    /*
+     * Convert IPv6 binary address into presentation (printable) format.
+     *
+     * @param src a byte array representing the IPv6 numeric address
+     * @return a String representing an IPv6 address in
+     *         textual representation format
+     * @since 1.4
+     */
+    static String numericToTextFormat(byte[] src) {
+        StringBuilder sb = new StringBuilder(39);
+        for (int i = 0; i < (INADDRSZ / INT16SZ); i++) {
+            sb.append(Integer.toHexString(((src[i<<1]<<8) & 0xff00)
+                                          | (src[(i<<1)+1] & 0xff)));
+            if (i < (INADDRSZ / INT16SZ) -1 ) {
+               sb.append(":");
+            }
+        }
+        return sb.toString();
+    }
+
+    // BEGIN Android-removed: Android doesn't need to call native init
+    /*
+     * Perform class load-time initializations.
+     *
+    private static native void init();
+    */
+    // END Android-removed: Android doesn't need to call native init
+}
diff --git a/java/net/Inet6AddressImpl.java b/java/net/Inet6AddressImpl.java
new file mode 100644
index 0000000..84bcf17
--- /dev/null
+++ b/java/net/Inet6AddressImpl.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+import android.system.ErrnoException;
+import android.system.GaiException;
+import android.system.StructAddrinfo;
+import android.system.IcmpHeaders;
+
+import dalvik.system.BlockGuard;
+
+import libcore.io.IoBridge;
+import libcore.io.Libcore;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import libcore.net.InetAddressUtils;
+
+import static android.system.OsConstants.AF_INET;
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNSPEC;
+import static android.system.OsConstants.AI_ADDRCONFIG;
+import static android.system.OsConstants.EACCES;
+import static android.system.OsConstants.ECONNREFUSED;
+import static android.system.OsConstants.EPERM;
+import static android.system.OsConstants.NI_NAMEREQD;
+import static android.system.OsConstants.ICMP6_ECHO_REPLY;
+import static android.system.OsConstants.ICMP_ECHOREPLY;
+import static android.system.OsConstants.IPPROTO_ICMP;
+import static android.system.OsConstants.IPPROTO_ICMPV6;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+
+// Android-note: Android-specific behavior and Linux-based implementation
+// http://b/36933260 Implement root-less ICMP for isReachable()
+// http://b/28609551 Rewrite getHostByAddr0 using POSIX library Libcore.os.
+// http://b/25861497 Add BlockGuard checks.
+// http://b/26700324 Fix odd dependency chains of the static InetAddress.
+// anyLocalAddress() Let anyLocalAddress() always return an IPv6 address.
+// Let loopbackAddresses() return both Inet4 and Inet6 loopbacks.
+// Rewrote hostname lookup methods on top of Libcore.os. Merge implementation from InetAddress
+//   and remove native methods in this class
+/*
+ * Package private implementation of InetAddressImpl for dual
+ * IPv4/IPv6 stack. {@code #anyLocalAddress()} will always return an IPv6 address.
+ *
+ * @since 1.4
+ */
+
+class Inet6AddressImpl implements InetAddressImpl {
+
+    // @GuardedBy(Inet6AddressImpl.class)
+    private static InetAddress anyLocalAddress;
+    // @GuardedBy(Inet6AddressImpl.class)
+    private static InetAddress[] loopbackAddresses;
+
+    private static final AddressCache addressCache = new AddressCache();
+
+    // BEGIN Android-changed: Rewrote hostname lookup methods on top of Libcore.os.
+    /*
+    public native String getLocalHostName() throws UnknownHostException;
+    public native InetAddress[]
+        lookupAllHostAddr(String hostname) throws UnknownHostException;
+    public native String getHostByAddr(byte[] addr) throws UnknownHostException;
+    private native boolean isReachable0(byte[] addr, int scope, int timeout, byte[] inf, int ttl, int if_scope) throws IOException;
+    */
+    @Override
+    public InetAddress[] lookupAllHostAddr(String host, int netId) throws UnknownHostException {
+        if (host == null || host.isEmpty()) {
+            // Android-changed: Return both the Inet4 and Inet6 loopback addresses
+            // when host == null or empty.
+            return loopbackAddresses();
+        }
+
+        // Is it a numeric address?
+        InetAddress result = InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(host);
+        if (result != null) {
+            return new InetAddress[] { result };
+        }
+
+        return lookupHostByName(host, netId);
+    }
+
+    /**
+     * Resolves a hostname to its IP addresses using a cache.
+     *
+     * @param host the hostname to resolve.
+     * @param netId the network to perform resolution upon.
+     * @return the IP addresses of the host.
+     */
+    private static InetAddress[] lookupHostByName(String host, int netId)
+            throws UnknownHostException {
+        BlockGuard.getThreadPolicy().onNetwork();
+        // Do we have a result cached?
+        Object cachedResult = addressCache.get(host, netId);
+        if (cachedResult != null) {
+            if (cachedResult instanceof InetAddress[]) {
+                // A cached positive result.
+                return (InetAddress[]) cachedResult;
+            } else {
+                // A cached negative result.
+                throw new UnknownHostException((String) cachedResult);
+            }
+        }
+        try {
+            StructAddrinfo hints = new StructAddrinfo();
+            hints.ai_flags = AI_ADDRCONFIG;
+            hints.ai_family = AF_UNSPEC;
+            // If we don't specify a socket type, every address will appear twice, once
+            // for SOCK_STREAM and one for SOCK_DGRAM. Since we do not return the family
+            // anyway, just pick one.
+            hints.ai_socktype = SOCK_STREAM;
+            InetAddress[] addresses = Libcore.os.android_getaddrinfo(host, hints, netId);
+            // TODO: should getaddrinfo set the hostname of the InetAddresses it returns?
+            for (InetAddress address : addresses) {
+                address.holder().hostName = host;
+                address.holder().originalHostName = host;
+            }
+            addressCache.put(host, netId, addresses);
+            return addresses;
+        } catch (GaiException gaiException) {
+            // If the failure appears to have been a lack of INTERNET permission, throw a clear
+            // SecurityException to aid in debugging this common mistake.
+            // http://code.google.com/p/android/issues/detail?id=15722
+            if (gaiException.getCause() instanceof ErrnoException) {
+                int errno = ((ErrnoException) gaiException.getCause()).errno;
+                if (errno == EACCES || errno == EPERM) {
+                    throw new SecurityException("Permission denied (missing INTERNET permission?)", gaiException);
+                }
+            }
+            // Otherwise, throw an UnknownHostException.
+            String detailMessage = "Unable to resolve host \"" + host + "\": " + Libcore.os.gai_strerror(gaiException.error);
+            addressCache.putUnknownHost(host, netId, detailMessage);
+            throw gaiException.rethrowAsUnknownHostException(detailMessage);
+        }
+    }
+
+    @Override
+    public String getHostByAddr(byte[] addr) throws UnknownHostException {
+        BlockGuard.getThreadPolicy().onNetwork();
+
+        return getHostByAddr0(addr);
+    }
+
+    @Override
+    public void clearAddressCache() {
+        addressCache.clear();
+    }
+    // END Android-changed: Rewrote hostname lookup methods on top of Libcore.os.
+
+    @Override
+    public boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif, int ttl) throws IOException {
+        // Android-changed: rewritten on the top of IoBridge and Libcore.os.
+        InetAddress sourceAddr = null;
+        if (netif != null) {
+            /*
+             * Let's make sure we bind to an address of the proper family.
+             * Which means same family as addr because at this point it could
+             * be either an IPv6 address or an IPv4 address (case of a dual
+             * stack system).
+             */
+            java.util.Enumeration<InetAddress> it = netif.getInetAddresses();
+            InetAddress inetaddr = null;
+            while (it.hasMoreElements()) {
+                inetaddr = it.nextElement();
+                if (inetaddr.getClass().isInstance(addr)) {
+                    sourceAddr = inetaddr;
+                    break;
+                }
+            }
+
+            if (sourceAddr == null) {
+                // Interface doesn't support the address family of
+                // the destination
+                return false;
+            }
+        }
+
+        // Android-changed: http://b/36933260 Implement root-less ICMP for isReachable().
+        /*
+        if (addr instanceof Inet6Address)
+            scope = ((Inet6Address) addr).getScopeId();
+        return isReachable0(addr.getAddress(), scope, timeout, ifaddr, ttl, netif_scope);
+        */
+        // Try ICMP first
+        if (icmpEcho(addr, timeout, sourceAddr, ttl)) {
+            return true;
+        }
+
+        // No good, let's fall back to TCP
+        return tcpEcho(addr, timeout, sourceAddr, ttl);
+    }
+
+    // BEGIN Android-added: http://b/36933260 Implement root-less ICMP for isReachable().
+    private boolean tcpEcho(InetAddress addr, int timeout, InetAddress sourceAddr, int ttl)
+            throws IOException {
+        FileDescriptor fd = null;
+        try {
+            fd = IoBridge.socket(AF_INET6, SOCK_STREAM, 0);
+            if (ttl > 0) {
+                IoBridge.setSocketOption(fd, IoBridge.JAVA_IP_TTL, ttl);
+            }
+            if (sourceAddr != null) {
+                IoBridge.bind(fd, sourceAddr, 0);
+            }
+            IoBridge.connect(fd, addr, 7 /* Echo-protocol port */, timeout);
+            return true;
+        } catch (IOException e) {
+            // Connection refused by remote (ECONNREFUSED) implies reachable. Otherwise silently
+            // ignore the exception and return false.
+            Throwable cause = e.getCause();
+            return cause instanceof ErrnoException
+                    && ((ErrnoException) cause).errno == ECONNREFUSED;
+        } finally {
+            IoBridge.closeAndSignalBlockedThreads(fd);
+        }
+    }
+
+    protected boolean icmpEcho(InetAddress addr, int timeout, InetAddress sourceAddr, int ttl)
+            throws IOException {
+
+        FileDescriptor fd = null;
+        try {
+            boolean isIPv4 = addr instanceof Inet4Address;
+            int domain = isIPv4 ? AF_INET : AF_INET6;
+            int icmpProto = isIPv4 ? IPPROTO_ICMP : IPPROTO_ICMPV6;
+            fd = IoBridge.socket(domain, SOCK_DGRAM, icmpProto);
+
+            if (ttl > 0) {
+                IoBridge.setSocketOption(fd, IoBridge.JAVA_IP_TTL, ttl);
+            }
+            if (sourceAddr != null) {
+                IoBridge.bind(fd, sourceAddr, 0);
+            }
+
+            byte[] packet;
+
+            // ICMP is unreliable, try sending requests every second until timeout.
+            for (int to = timeout, seq = 1; to > 0; ++seq) {
+                int sockTo = to >= 1000 ? 1000 : to;
+
+                IoBridge.setSocketOption(fd, SocketOptions.SO_TIMEOUT, sockTo);
+
+                packet = IcmpHeaders.createIcmpEchoHdr(isIPv4, seq);
+                IoBridge.sendto(fd, packet, 0, packet.length, 0, addr, 0);
+                final int icmpId = IoBridge.getLocalInetSocketAddress(fd).getPort();
+
+                byte[] received = new byte[packet.length];
+                DatagramPacket receivedPacket = new DatagramPacket(received, packet.length);
+                int size = IoBridge
+                        .recvfrom(true, fd, received, 0, received.length, 0, receivedPacket, false);
+                if (size == packet.length) {
+                    byte expectedType = isIPv4 ? (byte) ICMP_ECHOREPLY
+                            : (byte) ICMP6_ECHO_REPLY;
+                    if (receivedPacket.getAddress().equals(addr)
+                            && received[0] == expectedType
+                            && received[4] == (byte) (icmpId >> 8)
+                            && received[5] == (byte) icmpId) {
+                        int receivedSequence = ((received[6] & 0xff) << 8) + (received[7] & 0xff);
+                        if (receivedSequence <= seq) {
+                            return true;
+                        }
+                    }
+                }
+                to -= sockTo;
+            }
+        } catch (IOException e) {
+            // Silently ignore and fall back.
+        } finally {
+            if (fd != null) {
+                try {
+                    Libcore.os.close(fd);
+                } catch (ErrnoException e) { }
+            }
+        }
+
+        return false;
+    }
+    // END Android-added: http://b/36933260 Implement root-less ICMP for isReachable().
+
+    // BEGIN Android-changed: Let anyLocalAddress() always return an IPv6 address.
+    @Override
+    public InetAddress anyLocalAddress() {
+        synchronized (Inet6AddressImpl.class) {
+            // We avoid initializing anyLocalAddress during <clinit> to avoid issues
+            // caused by the dependency chains of these classes. InetAddress depends on
+            // InetAddressImpl, but Inet6Address & Inet4Address are its subclasses.
+            // Also see {@code loopbackAddresses). http://b/26700324
+            if (anyLocalAddress == null) {
+                Inet6Address anyAddress = new Inet6Address();
+                anyAddress.holder().hostName = "::";
+                anyLocalAddress = anyAddress;
+            }
+
+            return anyLocalAddress;
+        }
+    }
+    // END Android-changed: Let anyLocalAddress() always return an IPv6 address.
+
+    // BEGIN Android-changed: Let loopbackAddresses() return both Inet4 and Inet6 loopbacks.
+    @Override
+    public InetAddress[] loopbackAddresses() {
+        synchronized (Inet6AddressImpl.class) {
+            // We avoid initializing anyLocalAddress during <clinit> to avoid issues
+            // caused by the dependency chains of these classes. InetAddress depends on
+            // InetAddressImpl, but Inet6Address & Inet4Address are its subclasses.
+            // Also see {@code anyLocalAddress).
+            if (loopbackAddresses == null) {
+                loopbackAddresses = new InetAddress[]{Inet6Address.LOOPBACK, Inet4Address.LOOPBACK};
+            }
+
+            return loopbackAddresses;
+        }
+    }
+    // END Android-changed: Let loopbackAddresses() return both Inet4 and Inet6 loopbacks.
+
+    // BEGIN Android-changed: b/28609551 Rewrite getHostByAddr0 using POSIX library Libcore.os.
+    private String getHostByAddr0(byte[] addr) throws UnknownHostException {
+        // Android-changed: Rewritten on the top of Libcore.os
+        InetAddress hostaddr = InetAddress.getByAddress(addr);
+        try {
+            return Libcore.os.getnameinfo(hostaddr, NI_NAMEREQD);
+        } catch (GaiException e) {
+            UnknownHostException uhe = new UnknownHostException(hostaddr.toString());
+            uhe.initCause(e);
+            throw uhe;
+        }
+    }
+    // END Android-changed: b/28609551 Rewrite getHostByAddr0 using POSIX library Libcore.os.
+}
diff --git a/java/net/InetAddress.annotated.java b/java/net/InetAddress.annotated.java
new file mode 100644
index 0000000..6f4492d
--- /dev/null
+++ b/java/net/InetAddress.annotated.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+import java.io.ObjectStreamException;
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InetAddress implements java.io.Serializable {
+
+InetAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMulticastAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isAnyLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isLinkLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isSiteLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCGlobal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCNodeLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCLinkLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCSiteLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isMCOrgLocal() { throw new RuntimeException("Stub!"); }
+
+public boolean isReachable(int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public boolean isReachable(java.net.NetworkInterface netif, int ttl, int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public boolean isReachableByICMP(int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostName() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getCanonicalHostName() { throw new RuntimeException("Stub!"); }
+
+public byte[] getAddress() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String getHostAddress() { throw new RuntimeException("Stub!"); }
+
+public int hashCode() { throw new RuntimeException("Stub!"); }
+
+public boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getByAddress(java.lang.String host, byte[] addr) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getByName(java.lang.String host) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress[] getAllByName(java.lang.String host) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getLoopbackAddress() { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getByAddress(byte[] addr) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetAddress getLocalHost() throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static boolean isNumeric(java.lang.String address) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.net.InetAddress parseNumericAddress(java.lang.String numericAddress) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static void clearDnsCache() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.net.InetAddress getByNameOnNet(java.lang.String host, int netId) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public static java.net.InetAddress[] getAllByNameOnNet(java.lang.String host, int netId) throws java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/net/InetAddress.java b/java/net/InetAddress.java
new file mode 100644
index 0000000..e4f8660
--- /dev/null
+++ b/java/net/InetAddress.java
@@ -0,0 +1,1702 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectOutputStream;
+import java.io.ObjectOutputStream.PutField;
+import libcore.net.InetAddressUtils;
+import sun.net.util.IPAddressUtil;
+import sun.net.spi.nameservice.*;
+import libcore.io.Libcore;
+
+/**
+ * This class represents an Internet Protocol (IP) address.
+ *
+ * <p> An IP address is either a 32-bit or 128-bit unsigned number
+ * used by IP, a lower-level protocol on which protocols like UDP and
+ * TCP are built. The IP address architecture is defined by <a
+ * href="http://www.ietf.org/rfc/rfc790.txt"><i>RFC&nbsp;790:
+ * Assigned Numbers</i></a>, <a
+ * href="http://www.ietf.org/rfc/rfc1918.txt"> <i>RFC&nbsp;1918:
+ * Address Allocation for Private Internets</i></a>, <a
+ * href="http://www.ietf.org/rfc/rfc2365.txt"><i>RFC&nbsp;2365:
+ * Administratively Scoped IP Multicast</i></a>, and <a
+ * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IP
+ * Version 6 Addressing Architecture</i></a>. An instance of an
+ * InetAddress consists of an IP address and possibly its
+ * corresponding host name (depending on whether it is constructed
+ * with a host name or whether it has already done reverse host name
+ * resolution).
+ *
+ * <h3> Address types </h3>
+ *
+ * <blockquote><table cellspacing=2 summary="Description of unicast and multicast address types">
+ *   <tr><th valign=top><i>unicast</i></th>
+ *       <td>An identifier for a single interface. A packet sent to
+ *         a unicast address is delivered to the interface identified by
+ *         that address.
+ *
+ *         <p> The Unspecified Address -- Also called anylocal or wildcard
+ *         address. It must never be assigned to any node. It indicates the
+ *         absence of an address. One example of its use is as the target of
+ *         bind, which allows a server to accept a client connection on any
+ *         interface, in case the server host has multiple interfaces.
+ *
+ *         <p> The <i>unspecified</i> address must not be used as
+ *         the destination address of an IP packet.
+ *
+ *         <p> The <i>Loopback</i> Addresses -- This is the address
+ *         assigned to the loopback interface. Anything sent to this
+ *         IP address loops around and becomes IP input on the local
+ *         host. This address is often used when testing a
+ *         client.</td></tr>
+ *   <tr><th valign=top><i>multicast</i></th>
+ *       <td>An identifier for a set of interfaces (typically belonging
+ *         to different nodes). A packet sent to a multicast address is
+ *         delivered to all interfaces identified by that address.</td></tr>
+ * </table></blockquote>
+ *
+ * <h4> IP address scope </h4>
+ *
+ * <p> <i>Link-local</i> addresses are designed to be used for addressing
+ * on a single link for purposes such as auto-address configuration,
+ * neighbor discovery, or when no routers are present.
+ *
+ * <p> <i>Site-local</i> addresses are designed to be used for addressing
+ * inside of a site without the need for a global prefix.
+ *
+ * <p> <i>Global</i> addresses are unique across the internet.
+ *
+ * <h4> Textual representation of IP addresses </h4>
+ *
+ * The textual representation of an IP address is address family specific.
+ *
+ * <p>
+ *
+ * For IPv4 address format, please refer to <A
+ * HREF="Inet4Address.html#format">Inet4Address#format</A>; For IPv6
+ * address format, please refer to <A
+ * HREF="Inet6Address.html#format">Inet6Address#format</A>.
+ *
+ * <P>There is a <a href="doc-files/net-properties.html#Ipv4IPv6">couple of
+ * System Properties</a> affecting how IPv4 and IPv6 addresses are used.</P>
+ *
+ * <h4> Host Name Resolution </h4>
+ *
+ * Host name-to-IP address <i>resolution</i> is accomplished through
+ * the use of a combination of local machine configuration information
+ * and network naming services such as the Domain Name System (DNS)
+ * and Network Information Service(NIS). The particular naming
+ * services(s) being used is by default the local machine configured
+ * one. For any host name, its corresponding IP address is returned.
+ *
+ * <p> <i>Reverse name resolution</i> means that for any IP address,
+ * the host associated with the IP address is returned.
+ *
+ * <p> The InetAddress class provides methods to resolve host names to
+ * their IP addresses and vice versa.
+ *
+ * <h4> InetAddress Caching </h4>
+ *
+ * The InetAddress class has a cache to store successful as well as
+ * unsuccessful host name resolutions.
+ *
+ * <p> By default, when a security manager is installed, in order to
+ * protect against DNS spoofing attacks,
+ * the result of positive host name resolutions are
+ * cached forever. When a security manager is not installed, the default
+ * behavior is to cache entries for a finite (implementation dependent)
+ * period of time. The result of unsuccessful host
+ * name resolution is cached for a very short period of time (10
+ * seconds) to improve performance.
+ *
+ * <p> If the default behavior is not desired, then a Java security property
+ * can be set to a different Time-to-live (TTL) value for positive
+ * caching. Likewise, a system admin can configure a different
+ * negative caching TTL value when needed.
+ *
+ * <p> Two Java security properties control the TTL values used for
+ *  positive and negative host name resolution caching:
+ *
+ * <blockquote>
+ * <dl>
+ * <dt><b>networkaddress.cache.ttl</b></dt>
+ * <dd>Indicates the caching policy for successful name lookups from
+ * the name service. The value is specified as as integer to indicate
+ * the number of seconds to cache the successful lookup. The default
+ * setting is to cache for an implementation specific period of time.
+ * <p>
+ * A value of -1 indicates "cache forever".
+ * </dd>
+ * <dt><b>networkaddress.cache.negative.ttl</b> (default: 10)</dt>
+ * <dd>Indicates the caching policy for un-successful name lookups
+ * from the name service. The value is specified as as integer to
+ * indicate the number of seconds to cache the failure for
+ * un-successful lookups.
+ * <p>
+ * A value of 0 indicates "never cache".
+ * A value of -1 indicates "cache forever".
+ * </dd>
+ * </dl>
+ * </blockquote>
+ *
+ * @author  Chris Warth
+ * @see     java.net.InetAddress#getByAddress(byte[])
+ * @see     java.net.InetAddress#getByAddress(java.lang.String, byte[])
+ * @see     java.net.InetAddress#getAllByName(java.lang.String)
+ * @see     java.net.InetAddress#getByName(java.lang.String)
+ * @see     java.net.InetAddress#getLocalHost()
+ * @since JDK1.0
+ */
+public
+class InetAddress implements java.io.Serializable {
+    // BEGIN Android-removed: Android uses linux-based OsConstants.
+    /*
+     * Specify the address family: Internet Protocol, Version 4
+     * @since 1.4
+     *
+    static final int IPv4 = 1;
+
+    /**
+     * Specify the address family: Internet Protocol, Version 6
+     * @since 1.4
+     *
+    static final int IPv6 = 2;
+    */
+    // END Android-removed: Android uses linux-based OsConstants.
+
+    // Android-removed: Android doesn't support the preference.
+    // /* Specify address family preference */
+    //static transient boolean preferIPv6Address = false;
+
+    static class InetAddressHolder {
+        /**
+         * Reserve the original application specified hostname.
+         *
+         * The original hostname is useful for domain-based endpoint
+         * identification (see RFC 2818 and RFC 6125).  If an address
+         * was created with a raw IP address, a reverse name lookup
+         * may introduce endpoint identification security issue via
+         * DNS forging.
+         *
+         * Oracle JSSE provider is using this original hostname, via
+         * sun.misc.JavaNetAccess, for SSL/TLS endpoint identification.
+         *
+         * Note: May define a new public method in the future if necessary.
+         */
+        String originalHostName;
+
+        InetAddressHolder() {}
+
+        InetAddressHolder(String hostName, int address, int family) {
+            this.originalHostName = hostName;
+            this.hostName = hostName;
+            this.address = address;
+            this.family = family;
+        }
+
+        void init(String hostName, int family) {
+            this.originalHostName = hostName;
+            this.hostName = hostName;
+            if (family != -1) {
+                this.family = family;
+            }
+        }
+
+        String hostName;
+
+        String getHostName() {
+            return hostName;
+        }
+
+        String getOriginalHostName() {
+            return originalHostName;
+        }
+
+        /**
+         * Holds a 32-bit IPv4 address.
+         */
+        int address;
+
+        int getAddress() {
+            return address;
+        }
+
+        // Android-changed: Documentation: use Linux-based OsConstants.
+        /**
+         * Specifies the address family type, for instance, AF_INET for IPv4
+         * addresses, and AF_INET6 for IPv6 addresses.
+         */
+        int family;
+
+        int getFamily() {
+            return family;
+        }
+    }
+
+    transient InetAddressHolder holder;
+
+    InetAddressHolder holder() {
+        return holder;
+    }
+
+    /* The implementation is always dual stack IPv6/IPv4 on android */
+    static final InetAddressImpl impl = new Inet6AddressImpl();
+
+    /* Used to store the name service provider */
+    // Android-changed: Android has only one name service.
+    // Android doesn't allow user to provide custom name services.
+    // private static List<NameService> nameServices = null;
+    private static final NameService nameService = new NameService() {
+        public InetAddress[] lookupAllHostAddr(String host, int netId)
+                throws UnknownHostException {
+            return impl.lookupAllHostAddr(host, netId);
+        }
+        public String getHostByAddr(byte[] addr)
+                throws UnknownHostException {
+            return impl.getHostByAddr(addr);
+        }
+    };
+
+    /* Used to store the best available hostname */
+    private transient String canonicalHostName = null;
+
+    /** use serialVersionUID from JDK 1.0.2 for interoperability */
+    private static final long serialVersionUID = 3286316764910316507L;
+
+
+    // BEGIN Android-removed: Android doesn't need to load native library.
+    /*
+     * Load net library into runtime, and perform initializations.
+     *
+    static {
+        preferIPv6Address = java.security.AccessController.doPrivileged(
+            new GetBooleanAction("java.net.preferIPv6Addresses")).booleanValue();
+        AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("net");
+                    return null;
+                }
+            });
+        init();
+    }
+    */
+    // END Android-removed: Android doesn't need to load native library.
+
+    /**
+     * Constructor for the Socket.accept() method.
+     * This creates an empty InetAddress, which is filled in by
+     * the accept() method.  This InetAddress, however, is not
+     * put in the address cache, since it is not created by name.
+     */
+    InetAddress() {
+        holder = new InetAddressHolder();
+    }
+
+    /**
+     * Replaces the de-serialized object with an Inet4Address object.
+     *
+     * @return the alternate object to the de-serialized object.
+     *
+     * @throws ObjectStreamException if a new object replacing this
+     * object could not be created
+     */
+    private Object readResolve() throws ObjectStreamException {
+        // will replace the deserialized 'this' object
+        return new Inet4Address(holder().getHostName(), holder().getAddress());
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an
+     * IP multicast address.
+     * @return a {@code boolean} indicating if the InetAddress is
+     * an IP multicast address
+     * @since   JDK1.1
+     */
+    public boolean isMulticastAddress() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress in a wildcard address.
+     * @return a {@code boolean} indicating if the Inetaddress is
+     *         a wildcard address.
+     * @since 1.4
+     */
+    public boolean isAnyLocalAddress() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is a loopback address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is
+     * a loopback address; or false otherwise.
+     * @since 1.4
+     */
+    public boolean isLoopbackAddress() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is an link local address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is
+     * a link local address; or false if address is not a link local unicast address.
+     * @since 1.4
+     */
+    public boolean isLinkLocalAddress() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the InetAddress is a site local address.
+     *
+     * @return a {@code boolean} indicating if the InetAddress is
+     * a site local address; or false if address is not a site local unicast address.
+     * @since 1.4
+     */
+    public boolean isSiteLocalAddress() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the multicast address has global scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of global scope, false if it is not
+     *         of global scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCGlobal() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the multicast address has node scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of node-local scope, false if it is not
+     *         of node-local scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCNodeLocal() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the multicast address has link scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of link-local scope, false if it is not
+     *         of link-local scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCLinkLocal() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the multicast address has site scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of site-local scope, false if it is not
+     *         of site-local scope or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCSiteLocal() {
+        return false;
+    }
+
+    /**
+     * Utility routine to check if the multicast address has organization scope.
+     *
+     * @return a {@code boolean} indicating if the address has
+     *         is a multicast address of organization-local scope,
+     *         false if it is not of organization-local scope
+     *         or it is not a multicast address
+     * @since 1.4
+     */
+    public boolean isMCOrgLocal() {
+        return false;
+    }
+
+
+    // Android-changed: Document that impl tries ICMP ECHO REQUESTs first.
+    // The sole implementation, Inet6AddressImpl.isReachable(), tries ICMP ECHO REQUESTs before
+    // TCP ECHO REQUESTs on Android. On Android, these are both possible without root access.
+    /**
+     * Test whether that address is reachable. Best effort is made by the
+     * implementation to try to reach the host, but firewalls and server
+     * configuration may block requests resulting in a unreachable status
+     * while some specific ports may be accessible.
+     * <p>
+     * Android implementation attempts ICMP ECHO REQUESTs first, on failure it
+     * will fall back to TCP ECHO REQUESTs. Success on either protocol will
+     * return true.
+     * <p>
+     * The timeout value, in milliseconds, indicates the maximum amount of time
+     * the try should take. If the operation times out before getting an
+     * answer, the host is deemed unreachable. A negative value will result
+     * in an IllegalArgumentException being thrown.
+     *
+     * @param   timeout the time, in milliseconds, before the call aborts
+     * @return a {@code boolean} indicating if the address is reachable.
+     * @throws IOException if a network error occurs
+     * @throws  IllegalArgumentException if {@code timeout} is negative.
+     * @since 1.5
+     */
+    public boolean isReachable(int timeout) throws IOException {
+        return isReachable(null, 0 , timeout);
+    }
+
+    // Android-changed: Document that impl tries ICMP ECHO REQUESTs first.
+    // The sole implementation, Inet6AddressImpl.isReachable(), tries ICMP ECHO REQUESTs before
+    // TCP ECHO REQUESTs on Android. On Android, these are both possible without root access.
+    /**
+     * Test whether that address is reachable. Best effort is made by the
+     * implementation to try to reach the host, but firewalls and server
+     * configuration may block requests resulting in a unreachable status
+     * while some specific ports may be accessible.
+     * <p>
+     * Android implementation attempts ICMP ECHO REQUESTs first, on failure it
+     * will fall back to TCP ECHO REQUESTs. Success on either protocol will
+     * return true.
+     * <p>
+     * The {@code network interface} and {@code ttl} parameters
+     * let the caller specify which network interface the test will go through
+     * and the maximum number of hops the packets should go through.
+     * A negative value for the {@code ttl} will result in an
+     * IllegalArgumentException being thrown.
+     * <p>
+     * The timeout value, in milliseconds, indicates the maximum amount of time
+     * the try should take. If the operation times out before getting an
+     * answer, the host is deemed unreachable. A negative value will result
+     * in an IllegalArgumentException being thrown.
+     *
+     * @param   netif   the NetworkInterface through which the
+     *                    test will be done, or null for any interface
+     * @param   ttl     the maximum numbers of hops to try or 0 for the
+     *                  default
+     * @param   timeout the time, in milliseconds, before the call aborts
+     * @throws  IllegalArgumentException if either {@code timeout}
+     *                          or {@code ttl} are negative.
+     * @return a {@code boolean}indicating if the address is reachable.
+     * @throws IOException if a network error occurs
+     * @since 1.5
+     */
+    public boolean isReachable(NetworkInterface netif, int ttl,
+                               int timeout) throws IOException {
+        if (ttl < 0)
+            throw new IllegalArgumentException("ttl can't be negative");
+        if (timeout < 0)
+            throw new IllegalArgumentException("timeout can't be negative");
+
+        return impl.isReachable(this, timeout, netif, ttl);
+    }
+
+    // BEGIN Android-added: isReachableByICMP(timeout).
+    /**
+     * @hide For testing only
+     */
+    public boolean isReachableByICMP(int timeout) throws IOException {
+        return ((Inet6AddressImpl) impl).icmpEcho(this, timeout, null, 0);
+    }
+    // END Android-added: isReachableByICMP(timeout).
+
+    /**
+     * Gets the host name for this IP address.
+     *
+     * <p>If this InetAddress was created with a host name,
+     * this host name will be remembered and returned;
+     * otherwise, a reverse name lookup will be performed
+     * and the result will be returned based on the system
+     * configured name lookup service. If a lookup of the name service
+     * is required, call
+     * {@link #getCanonicalHostName() getCanonicalHostName}.
+     *
+     * <p>If there is a security manager, its
+     * {@code checkConnect} method is first called
+     * with the hostname and {@code -1}
+     * as its arguments to see if the operation is allowed.
+     * If the operation is not allowed, it will return
+     * the textual representation of the IP address.
+     *
+     * @return  the host name for this IP address, or if the operation
+     *    is not allowed by the security check, the textual
+     *    representation of the IP address.
+     *
+     * @see InetAddress#getCanonicalHostName
+     * @see SecurityManager#checkConnect
+     */
+    public String getHostName() {
+        // Android-changed: Remove SecurityManager check.
+        if (holder().getHostName() == null) {
+            holder().hostName = InetAddress.getHostFromNameService(this);
+        }
+        return holder().getHostName();
+    }
+
+    // BEGIN Android-removed: Android doesn't support SecurityManager.
+    /*
+     * Returns the hostname for this address.
+     * If the host is equal to null, then this address refers to any
+     * of the local machine's available network addresses.
+     * this is package private so SocketPermission can make calls into
+     * here without a security check.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkConnect} method
+     * with the hostname and {@code -1}
+     * as its arguments to see if the calling code is allowed to know
+     * the hostname for this IP address, i.e., to connect to the host.
+     * If the operation is not allowed, it will return
+     * the textual representation of the IP address.
+     *
+     * @return  the host name for this IP address, or if the operation
+     *    is not allowed by the security check, the textual
+     *    representation of the IP address.
+     *
+     * @param check make security check if true
+     *
+     * @see SecurityManager#checkConnect
+     *
+    String getHostName(boolean check) {
+        if (holder().getHostName() == null) {
+            holder().hostName = InetAddress.getHostFromNameService(this, check);
+        }
+        return holder().getHostName();
+    }
+    */
+    // END Android-removed: Android doesn't support SecurityManager.
+
+    /**
+     * Gets the fully qualified domain name for this IP address.
+     * Best effort method, meaning we may not be able to return
+     * the FQDN depending on the underlying system configuration.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkConnect} method
+     * with the hostname and {@code -1}
+     * as its arguments to see if the calling code is allowed to know
+     * the hostname for this IP address, i.e., to connect to the host.
+     * If the operation is not allowed, it will return
+     * the textual representation of the IP address.
+     *
+     * @return  the fully qualified domain name for this IP address,
+     *    or if the operation is not allowed by the security check,
+     *    the textual representation of the IP address.
+     *
+     * @see SecurityManager#checkConnect
+     *
+     * @since 1.4
+     */
+    public String getCanonicalHostName() {
+        // Android-changed: Remove SecurityManager check.
+        if (canonicalHostName == null) {
+            canonicalHostName = InetAddress.getHostFromNameService(this);
+        }
+        return canonicalHostName;
+    }
+
+    // Android-changed: Remove SecurityManager check.
+    // * @param check make security check if true
+    /**
+     * Returns the hostname for this address.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkConnect} method
+     * with the hostname and {@code -1}
+     * as its arguments to see if the calling code is allowed to know
+     * the hostname for this IP address, i.e., to connect to the host.
+     * If the operation is not allowed, it will return
+     * the textual representation of the IP address.
+     *
+     * @return  the host name for this IP address, or if the operation
+     *    is not allowed by the security check, the textual
+     *    representation of the IP address.
+     *
+     * @see SecurityManager#checkConnect
+     */
+    private static String getHostFromNameService(InetAddress addr) {
+        String host = null;
+        try {
+            // first lookup the hostname
+            // Android-changed: Android has only one name service.
+            host = nameService.getHostByAddr(addr.getAddress());
+
+                /* now get all the IP addresses for this hostname,
+                 * and make sure one of them matches the original IP
+                 * address. We do this to try and prevent spoofing.
+                 */
+            InetAddress[] arr = nameService.lookupAllHostAddr(host, NETID_UNSET);
+            boolean ok = false;
+
+            if (arr != null) {
+                for(int i = 0; !ok && i < arr.length; i++) {
+                    ok = addr.equals(arr[i]);
+                }
+            }
+
+            //XXX: if it looks a spoof just return the address?
+            if (!ok) {
+                host = addr.getHostAddress();
+                return host;
+            }
+        } catch (UnknownHostException e) {
+            host = addr.getHostAddress();
+        }
+
+        return host;
+    }
+
+    /**
+     * Returns the raw IP address of this {@code InetAddress}
+     * object. The result is in network byte order: the highest order
+     * byte of the address is in {@code getAddress()[0]}.
+     *
+     * @return  the raw IP address of this object.
+     */
+    public byte[] getAddress() {
+        return null;
+    }
+
+    /**
+     * Returns the IP address string in textual presentation.
+     *
+     * @return  the raw IP address in a string format.
+     * @since   JDK1.0.2
+     */
+    public String getHostAddress() {
+        return null;
+     }
+
+    /**
+     * Returns a hashcode for this IP address.
+     *
+     * @return  a hash code value for this IP address.
+     */
+    public int hashCode() {
+        return -1;
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is
+     * not {@code null} and it represents the same IP address as
+     * this object.
+     * <p>
+     * Two instances of {@code InetAddress} represent the same IP
+     * address if the length of the byte arrays returned by
+     * {@code getAddress} is the same for both, and each of the
+     * array components is the same for the byte arrays.
+     *
+     * @param   obj   the object to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see     java.net.InetAddress#getAddress()
+     */
+    public boolean equals(Object obj) {
+        return false;
+    }
+
+    /**
+     * Converts this IP address to a {@code String}. The
+     * string returned is of the form: hostname / literal IP
+     * address.
+     *
+     * If the host name is unresolved, no reverse name service lookup
+     * is performed. The hostname part will be represented by an empty string.
+     *
+     * @return  a string representation of this IP address.
+     */
+    public String toString() {
+        String hostName = holder().getHostName();
+        return ((hostName != null) ? hostName : "")
+            + "/" + getHostAddress();
+    }
+
+    // BEGIN Android-removed: Resolves a hostname using Libcore.os.
+    /*
+     * Cached addresses - our own litle nis, not!
+     *
+    private static Cache addressCache = new Cache(Cache.Type.Positive);
+
+    private static Cache negativeCache = new Cache(Cache.Type.Negative);
+
+    private static boolean addressCacheInit = false;
+
+    static InetAddress[]    unknown_array; // put THIS in cache
+
+    static InetAddressImpl  impl;
+
+    private static final HashMap<String, Void> lookupTable = new HashMap<>();
+
+    /**
+     * Represents a cache entry
+     *
+    static final class CacheEntry {
+
+        CacheEntry(InetAddress[] addresses, long expiration) {
+            this.addresses = addresses;
+            this.expiration = expiration;
+        }
+
+        InetAddress[] addresses;
+        long expiration;
+    }
+
+    /**
+     * A cache that manages entries based on a policy specified
+     * at creation time.
+     *
+    static final class Cache {
+        private LinkedHashMap<String, CacheEntry> cache;
+        private Type type;
+
+        enum Type {Positive, Negative};
+
+        /**
+         * Create cache
+         *
+        public Cache(Type type) {
+            this.type = type;
+            cache = new LinkedHashMap<String, CacheEntry>();
+        }
+
+        private int getPolicy() {
+            if (type == Type.Positive) {
+                return InetAddressCachePolicy.get();
+            } else {
+                return InetAddressCachePolicy.getNegative();
+            }
+        }
+
+        /**
+         * Add an entry to the cache. If there's already an
+         * entry then for this host then the entry will be
+         * replaced.
+         *
+        public Cache put(String host, InetAddress[] addresses) {
+            int policy = getPolicy();
+            if (policy == InetAddressCachePolicy.NEVER) {
+                return this;
+            }
+
+            // purge any expired entries
+
+            if (policy != InetAddressCachePolicy.FOREVER) {
+
+                // As we iterate in insertion order we can
+                // terminate when a non-expired entry is found.
+                LinkedList<String> expired = new LinkedList<>();
+                long now = System.currentTimeMillis();
+                for (String key : cache.keySet()) {
+                    CacheEntry entry = cache.get(key);
+
+                    if (entry.expiration >= 0 && entry.expiration < now) {
+                        expired.add(key);
+                    } else {
+                        break;
+                    }
+                }
+
+                for (String key : expired) {
+                    cache.remove(key);
+                }
+            }
+
+            // create new entry and add it to the cache
+            // -- as a HashMap replaces existing entries we
+            //    don't need to explicitly check if there is
+            //    already an entry for this host.
+            long expiration;
+            if (policy == InetAddressCachePolicy.FOREVER) {
+                expiration = -1;
+            } else {
+                expiration = System.currentTimeMillis() + (policy * 1000);
+            }
+            CacheEntry entry = new CacheEntry(addresses, expiration);
+            cache.put(host, entry);
+            return this;
+        }
+
+        /**
+         * Query the cache for the specific host. If found then
+         * return its CacheEntry, or null if not found.
+         *
+        public CacheEntry get(String host) {
+            int policy = getPolicy();
+            if (policy == InetAddressCachePolicy.NEVER) {
+                return null;
+            }
+            CacheEntry entry = cache.get(host);
+
+            // check if entry has expired
+            if (entry != null && policy != InetAddressCachePolicy.FOREVER) {
+                if (entry.expiration >= 0 &&
+                        entry.expiration < System.currentTimeMillis()) {
+                    cache.remove(host);
+                    entry = null;
+                }
+            }
+
+            return entry;
+        }
+    }
+
+    /*
+     * Initialize cache and insert anyLocalAddress into the
+     * unknown array with no expiry.
+     *
+    private static void cacheInitIfNeeded() {
+        assert Thread.holdsLock(addressCache);
+        if (addressCacheInit) {
+            return;
+        }
+        unknown_array = new InetAddress[1];
+        unknown_array[0] = impl.anyLocalAddress();
+
+        addressCache.put(impl.anyLocalAddress().getHostName(),
+                         unknown_array);
+
+        addressCacheInit = true;
+    }
+
+    /*
+     * Cache the given hostname and addresses.
+     *
+    private static void cacheAddresses(String hostname,
+                                       InetAddress[] addresses,
+                                       boolean success) {
+        hostname = hostname.toLowerCase();
+        synchronized (addressCache) {
+            cacheInitIfNeeded();
+            if (success) {
+                addressCache.put(hostname, addresses);
+            } else {
+                negativeCache.put(hostname, addresses);
+            }
+        }
+    }
+
+    /*
+     * Lookup hostname in cache (positive & negative cache). If
+     * found return addresses, null if not found.
+     *
+    private static InetAddress[] getCachedAddresses(String hostname) {
+        hostname = hostname.toLowerCase();
+
+        // search both positive & negative caches
+
+        synchronized (addressCache) {
+            cacheInitIfNeeded();
+
+            CacheEntry entry = addressCache.get(hostname);
+            if (entry == null) {
+                entry = negativeCache.get(hostname);
+            }
+
+            if (entry != null) {
+                return entry.addresses;
+            }
+        }
+
+        // not found
+        return null;
+    }
+
+    private static NameService createNSProvider(String provider) {
+        if (provider == null)
+            return null;
+
+        NameService nameService = null;
+        if (provider.equals("default")) {
+            // initialize the default name service
+            nameService = new NameService() {
+                public InetAddress[] lookupAllHostAddr(String host)
+                    throws UnknownHostException {
+                    return impl.lookupAllHostAddr(host);
+                }
+                public String getHostByAddr(byte[] addr)
+                    throws UnknownHostException {
+                    return impl.getHostByAddr(addr);
+                }
+            };
+        } else {
+            final String providerName = provider;
+            try {
+                nameService = java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedExceptionAction<NameService>() {
+                        public NameService run() {
+                            Iterator<NameServiceDescriptor> itr =
+                                ServiceLoader.load(NameServiceDescriptor.class)
+                                    .iterator();
+                            while (itr.hasNext()) {
+                                NameServiceDescriptor nsd = itr.next();
+                                if (providerName.
+                                    equalsIgnoreCase(nsd.getType()+","
+                                        +nsd.getProviderName())) {
+                                    try {
+                                        return nsd.createNameService();
+                                    } catch (Exception e) {
+                                        e.printStackTrace();
+                                        System.err.println(
+                                            "Cannot create name service:"
+                                             +providerName+": " + e);
+                                    }
+                                }
+                            }
+
+                            return null;
+                        }
+                    }
+                );
+            } catch (java.security.PrivilegedActionException e) {
+            }
+        }
+
+        return nameService;
+    }
+
+    static {
+        // create the impl
+        impl = InetAddressImplFactory.create();
+
+        // get name service if provided and requested
+        String provider = null;;
+        String propPrefix = "sun.net.spi.nameservice.provider.";
+        int n = 1;
+        nameServices = new ArrayList<NameService>();
+        provider = AccessController.doPrivileged(
+                new GetPropertyAction(propPrefix + n));
+        while (provider != null) {
+            NameService ns = createNSProvider(provider);
+            if (ns != null)
+                nameServices.add(ns);
+
+            n++;
+            provider = AccessController.doPrivileged(
+                    new GetPropertyAction(propPrefix + n));
+        }
+
+        // if not designate any name services provider,
+        // create a default one
+        if (nameServices.size() == 0) {
+            NameService ns = createNSProvider("default");
+            nameServices.add(ns);
+        }
+    }
+    */
+    // END Android-removed: Resolves a hostname using Libcore.os.
+
+    /**
+     * Creates an InetAddress based on the provided host name and IP address.
+     * No name service is checked for the validity of the address.
+     *
+     * <p> The host name can either be a machine name, such as
+     * "{@code java.sun.com}", or a textual representation of its IP
+     * address.
+     * <p> No validity checking is done on the host name either.
+     *
+     * <p> If addr specifies an IPv4 address an instance of Inet4Address
+     * will be returned; otherwise, an instance of Inet6Address
+     * will be returned.
+     *
+     * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
+     * must be 16 bytes long
+     *
+     * @param host the specified host
+     * @param addr the raw IP address in network byte order
+     * @return  an InetAddress object created from the raw IP address.
+     * @exception  UnknownHostException  if IP address is of illegal length
+     * @since 1.4
+     */
+    public static InetAddress getByAddress(String host, byte[] addr) throws UnknownHostException {
+        return getByAddress(host, addr, -1 /* scopeId */);
+    }
+
+    // Android-added: Called by native code in Libcore.io.
+    // Do not delete. Called from native code.
+    private static InetAddress getByAddress(String host, byte[] addr, int scopeId)
+        throws UnknownHostException {
+        if (host != null && host.length() > 0 && host.charAt(0) == '[') {
+            if (host.charAt(host.length()-1) == ']') {
+                host = host.substring(1, host.length() -1);
+            }
+        }
+        if (addr != null) {
+            if (addr.length == Inet4Address.INADDRSZ) {
+                return new Inet4Address(host, addr);
+            } else if (addr.length == Inet6Address.INADDRSZ) {
+                byte[] newAddr
+                    = IPAddressUtil.convertFromIPv4MappedAddress(addr);
+                if (newAddr != null) {
+                    return new Inet4Address(host, newAddr);
+                } else {
+                    return new Inet6Address(host, addr, scopeId);
+                }
+            }
+        }
+        throw new UnknownHostException("addr is of illegal length");
+    }
+
+
+    /**
+     * Determines the IP address of a host, given the host's name.
+     *
+     * <p> The host name can either be a machine name, such as
+     * "{@code java.sun.com}", or a textual representation of its
+     * IP address. If a literal IP address is supplied, only the
+     * validity of the address format is checked.
+     *
+     * <p> For {@code host} specified in literal IPv6 address,
+     * either the form defined in RFC 2732 or the literal IPv6 address
+     * format defined in RFC 2373 is accepted. IPv6 scoped addresses are also
+     * supported. See <a href="Inet6Address.html#scoped">here</a> for a description of IPv6
+     * scoped addresses.
+     *
+     * <p> If the host is {@code null} then an {@code InetAddress}
+     * representing an address of the loopback interface is returned.
+     * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
+     * section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
+     * section&nbsp;2.5.3. </p>
+     *
+     * @param      host   the specified host, or {@code null}.
+     * @return     an IP address for the given host name.
+     * @exception  UnknownHostException  if no IP address for the
+     *               {@code host} could be found, or if a scope_id was specified
+     *               for a global IPv6 address.
+     * @exception  SecurityException if a security manager exists
+     *             and its checkConnect method doesn't allow the operation
+     */
+    public static InetAddress getByName(String host)
+        throws UnknownHostException {
+        // Android-changed: Rewritten on the top of Libcore.os.
+        return impl.lookupAllHostAddr(host, NETID_UNSET)[0];
+    }
+
+    /**
+     * Given the name of a host, returns an array of its IP addresses,
+     * based on the configured name service on the system.
+     *
+     * <p> The host name can either be a machine name, such as
+     * "{@code java.sun.com}", or a textual representation of its IP
+     * address. If a literal IP address is supplied, only the
+     * validity of the address format is checked.
+     *
+     * <p> For {@code host} specified in <i>literal IPv6 address</i>,
+     * either the form defined in RFC 2732 or the literal IPv6 address
+     * format defined in RFC 2373 is accepted. A literal IPv6 address may
+     * also be qualified by appending a scoped zone identifier or scope_id.
+     * The syntax and usage of scope_ids is described
+     * <a href="Inet6Address.html#scoped">here</a>.
+     * <p> If the host is {@code null} then an {@code InetAddress}
+     * representing an address of the loopback interface is returned.
+     * See <a href="http://www.ietf.org/rfc/rfc3330.txt">RFC&nbsp;3330</a>
+     * section&nbsp;2 and <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>
+     * section&nbsp;2.5.3. </p>
+     *
+     * <p> If there is a security manager and {@code host} is not
+     * null and {@code host.length() } is not equal to zero, the
+     * security manager's
+     * {@code checkConnect} method is called
+     * with the hostname and {@code -1}
+     * as its arguments to see if the operation is allowed.
+     *
+     * @param      host   the name of the host, or {@code null}.
+     * @return     an array of all the IP addresses for a given host name.
+     *
+     * @exception  UnknownHostException  if no IP address for the
+     *               {@code host} could be found, or if a scope_id was specified
+     *               for a global IPv6 address.
+     * @exception  SecurityException  if a security manager exists and its
+     *               {@code checkConnect} method doesn't allow the operation.
+     *
+     * @see SecurityManager#checkConnect
+     */
+    public static InetAddress[] getAllByName(String host)
+        throws UnknownHostException {
+        // Android-changed: Resolves a hostname using Libcore.os.
+        // Also, returns both the Inet4 and Inet6 loopback for null/empty host
+        return impl.lookupAllHostAddr(host, NETID_UNSET).clone();
+    }
+
+    /**
+     * Returns the loopback address.
+     * <p>
+     * The InetAddress returned will represent the IPv4
+     * loopback address, 127.0.0.1, or the IPv6 loopback
+     * address, ::1. The IPv4 loopback address returned
+     * is only one of many in the form 127.*.*.*
+     *
+     * @return  the InetAddress loopback instance.
+     * @since 1.7
+     */
+    public static InetAddress getLoopbackAddress() {
+        // Android-changed: Always returns IPv6 loopback address in Android.
+        return impl.loopbackAddresses()[0];
+    }
+
+    // BEGIN Android-removed: Resolves a hostname using Libcore.os.
+    /*
+     * check if the literal address string has %nn appended
+     * returns -1 if not, or the numeric value otherwise.
+     *
+     * %nn may also be a string that represents the displayName of
+     * a currently available NetworkInterface.
+     *
+    private static int checkNumericZone (String s) throws UnknownHostException {
+        int percent = s.indexOf ('%');
+        int slen = s.length();
+        int digit, zone=0;
+        if (percent == -1) {
+            return -1;
+        }
+        for (int i=percent+1; i<slen; i++) {
+            char c = s.charAt(i);
+            if (c == ']') {
+                if (i == percent+1) {
+                    /* empty per-cent field *
+                    return -1;
+                }
+                break;
+            }
+            if ((digit = Character.digit (c, 10)) < 0) {
+                return -1;
+            }
+            zone = (zone * 10) + digit;
+        }
+        return zone;
+    }
+
+    private static InetAddress[] getAllByName0 (String host)
+        throws UnknownHostException
+    {
+        return getAllByName0(host, true);
+    }
+
+    /**
+     * package private so SocketPermission can call it
+     *
+    static InetAddress[] getAllByName0 (String host, boolean check)
+        throws UnknownHostException  {
+        return getAllByName0 (host, null, check);
+    }
+
+    private static InetAddress[] getAllByName0 (String host, InetAddress reqAddr, boolean check)
+        throws UnknownHostException  {
+
+        /* If it gets here it is presumed to be a hostname */
+        /* Cache.get can return: null, unknownAddress, or InetAddress[] */
+
+        /* make sure the connection to the host is allowed, before we
+         * give out a hostname
+         *
+        if (check) {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkConnect(host, -1);
+            }
+        }
+
+        InetAddress[] addresses = getCachedAddresses(host);
+
+        /* If no entry in cache, then do the host lookup *
+        if (addresses == null) {
+            addresses = getAddressesFromNameService(host, reqAddr);
+        }
+
+        if (addresses == unknown_array)
+            throw new UnknownHostException(host);
+
+        return addresses.clone();
+    }
+
+    private static InetAddress[] getAddressesFromNameService(String host, InetAddress reqAddr)
+        throws UnknownHostException
+    {
+        InetAddress[] addresses = null;
+        boolean success = false;
+        UnknownHostException ex = null;
+
+        // Check whether the host is in the lookupTable.
+        // 1) If the host isn't in the lookupTable when
+        //    checkLookupTable() is called, checkLookupTable()
+        //    would add the host in the lookupTable and
+        //    return null. So we will do the lookup.
+        // 2) If the host is in the lookupTable when
+        //    checkLookupTable() is called, the current thread
+        //    would be blocked until the host is removed
+        //    from the lookupTable. Then this thread
+        //    should try to look up the addressCache.
+        //     i) if it found the addresses in the
+        //        addressCache, checkLookupTable()  would
+        //        return the addresses.
+        //     ii) if it didn't find the addresses in the
+        //         addressCache for any reason,
+        //         it should add the host in the
+        //         lookupTable and return null so the
+        //         following code would do  a lookup itself.
+        if ((addresses = checkLookupTable(host)) == null) {
+            try {
+                // This is the first thread which looks up the addresses
+                // this host or the cache entry for this host has been
+                // expired so this thread should do the lookup.
+                for (NameService nameService : nameServices) {
+                    try {
+                        /*
+                         * Do not put the call to lookup() inside the
+                         * constructor.  if you do you will still be
+                         * allocating space when the lookup fails.
+                         *
+
+                        addresses = nameService.lookupAllHostAddr(host);
+                        success = true;
+                        break;
+                    } catch (UnknownHostException uhe) {
+                        if (host.equalsIgnoreCase("localhost")) {
+                            InetAddress[] local = new InetAddress[] { impl.loopbackAddress() };
+                            addresses = local;
+                            success = true;
+                            break;
+                        }
+                        else {
+                            addresses = unknown_array;
+                            success = false;
+                            ex = uhe;
+                        }
+                    }
+                }
+
+                // More to do?
+                if (reqAddr != null && addresses.length > 1 && !addresses[0].equals(reqAddr)) {
+                    // Find it?
+                    int i = 1;
+                    for (; i < addresses.length; i++) {
+                        if (addresses[i].equals(reqAddr)) {
+                            break;
+                        }
+                    }
+                    // Rotate
+                    if (i < addresses.length) {
+                        InetAddress tmp, tmp2 = reqAddr;
+                        for (int j = 0; j < i; j++) {
+                            tmp = addresses[j];
+                            addresses[j] = tmp2;
+                            tmp2 = tmp;
+                        }
+                        addresses[i] = tmp2;
+                    }
+                }
+                // Cache the address.
+                cacheAddresses(host, addresses, success);
+
+                if (!success && ex != null)
+                    throw ex;
+
+            } finally {
+                // Delete host from the lookupTable and notify
+                // all threads waiting on the lookupTable monitor.
+                updateLookupTable(host);
+            }
+        }
+
+        return addresses;
+    }
+
+
+    private static InetAddress[] checkLookupTable(String host) {
+        synchronized (lookupTable) {
+            // If the host isn't in the lookupTable, add it in the
+            // lookuptable and return null. The caller should do
+            // the lookup.
+            if (lookupTable.containsKey(host) == false) {
+                lookupTable.put(host, null);
+                return null;
+            }
+
+            // If the host is in the lookupTable, it means that another
+            // thread is trying to look up the addresses of this host.
+            // This thread should wait.
+            while (lookupTable.containsKey(host)) {
+                try {
+                    lookupTable.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+        }
+
+        // The other thread has finished looking up the addresses of
+        // the host. This thread should retry to get the addresses
+        // from the addressCache. If it doesn't get the addresses from
+        // the cache, it will try to look up the addresses itself.
+        InetAddress[] addresses = getCachedAddresses(host);
+        if (addresses == null) {
+            synchronized (lookupTable) {
+                lookupTable.put(host, null);
+                return null;
+            }
+        }
+
+        return addresses;
+    }
+
+    private static void updateLookupTable(String host) {
+        synchronized (lookupTable) {
+            lookupTable.remove(host);
+            lookupTable.notifyAll();
+        }
+    }
+    */
+    // END Android-removed: Resolves a hostname using Libcore.os.
+
+    /**
+     * Returns an {@code InetAddress} object given the raw IP address .
+     * The argument is in network byte order: the highest order
+     * byte of the address is in {@code getAddress()[0]}.
+     *
+     * <p> This method doesn't block, i.e. no reverse name service lookup
+     * is performed.
+     *
+     * <p> IPv4 address byte array must be 4 bytes long and IPv6 byte array
+     * must be 16 bytes long
+     *
+     * @param addr the raw IP address in network byte order
+     * @return  an InetAddress object created from the raw IP address.
+     * @exception  UnknownHostException  if IP address is of illegal length
+     * @since 1.4
+     */
+    public static InetAddress getByAddress(byte[] addr)
+        throws UnknownHostException {
+        return getByAddress(null, addr);
+    }
+
+    // BEGIN Android-removed: Resolves a hostname using Libcore.os.
+    /*
+    private static InetAddress cachedLocalHost = null;
+    private static long cacheTime = 0;
+    private static final long maxCacheTime = 5000L;
+    private static final Object cacheLock = new Object();
+    */
+    // END Android-removed: Resolves a hostname using Libcore.os.
+
+    /**
+     * Returns the address of the local host. This is achieved by retrieving
+     * the name of the host from the system, then resolving that name into
+     * an {@code InetAddress}.
+     *
+     * <P>Note: The resolved address may be cached for a short period of time.
+     * </P>
+     *
+     * <p>If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with the local host name and {@code -1}
+     * as its arguments to see if the operation is allowed.
+     * If the operation is not allowed, an InetAddress representing
+     * the loopback address is returned.
+     *
+     * @return     the address of the local host.
+     *
+     * @exception  UnknownHostException  if the local host name could not
+     *             be resolved into an address.
+     *
+     * @see SecurityManager#checkConnect
+     * @see java.net.InetAddress#getByName(java.lang.String)
+     */
+    public static InetAddress getLocalHost() throws UnknownHostException {
+        // BEGIN Android-changed: Resolves a hostname using Libcore.os.
+        /*
+        SecurityManager security = System.getSecurityManager();
+        try {
+            String local = impl.getLocalHostName();
+
+            if (security != null) {
+                security.checkConnect(local, -1);
+            }
+
+            if (local.equals("localhost")) {
+                return impl.loopbackAddress();
+            }
+
+            InetAddress ret = null;
+            synchronized (cacheLock) {
+                long now = System.currentTimeMillis();
+                if (cachedLocalHost != null) {
+                    if ((now - cacheTime) < maxCacheTime) // Less than 5s old?
+                        ret = cachedLocalHost;
+                    else
+                        cachedLocalHost = null;
+                }
+
+                // we are calling getAddressesFromNameService directly
+                // to avoid getting localHost from cache
+                if (ret == null) {
+                    InetAddress[] localAddrs;
+                    try {
+                        localAddrs =
+                            InetAddress.getAddressesFromNameService(local, null);
+                    } catch (UnknownHostException uhe) {
+                        // Rethrow with a more informative error message.
+                        UnknownHostException uhe2 =
+                            new UnknownHostException(local + ": " +
+                                                     uhe.getMessage());
+                        uhe2.initCause(uhe);
+                        throw uhe2;
+                    }
+                    cachedLocalHost = localAddrs[0];
+                    cacheTime = now;
+                    ret = localAddrs[0];
+                }
+            }
+            return ret;
+        } catch (java.lang.SecurityException e) {
+            return impl.loopbackAddress();
+        }
+        */
+        String local = Libcore.os.uname().nodename;
+        return impl.lookupAllHostAddr(local, NETID_UNSET)[0];
+        // END Android-changed: Resolves a hostname using Libcore.os.
+    }
+
+    // BEGIN Android-removed: Android doesn't need to call native init.
+    /**
+     * Perform class load-time initializations.
+     *
+    private static native void init();
+    */
+    // END Android-removed: Android doesn't need to call native init.
+
+    /*
+     * Returns the InetAddress representing anyLocalAddress
+     * (typically 0.0.0.0 or ::0)
+     */
+    static InetAddress anyLocalAddress() {
+        return impl.anyLocalAddress();
+    }
+
+    // BEGIN Android-removed: Android doesn't load user-provided implementation.
+    /*
+     * Load and instantiate an underlying impl class
+     *
+    static InetAddressImpl loadImpl(String implName) {
+        Object impl = null;
+
+        /*
+         * Property "impl.prefix" will be prepended to the classname
+         * of the implementation object we instantiate, to which we
+         * delegate the real work (like native methods).  This
+         * property can vary across implementations of the java.
+         * classes.  The default is an empty String "".
+         *
+        String prefix = AccessController.doPrivileged(
+                      new GetPropertyAction("impl.prefix", ""));
+        try {
+            impl = Class.forName("java.net." + prefix + implName).newInstance();
+        } catch (ClassNotFoundException e) {
+            System.err.println("Class not found: java.net." + prefix +
+                               implName + ":\ncheck impl.prefix property " +
+                               "in your properties file.");
+        } catch (InstantiationException e) {
+            System.err.println("Could not instantiate: java.net." + prefix +
+                               implName + ":\ncheck impl.prefix property " +
+                               "in your properties file.");
+        } catch (IllegalAccessException e) {
+            System.err.println("Cannot access class: java.net." + prefix +
+                               implName + ":\ncheck impl.prefix property " +
+                               "in your properties file.");
+        }
+
+        if (impl == null) {
+            try {
+                impl = Class.forName(implName).newInstance();
+            } catch (Exception e) {
+                throw new Error("System property impl.prefix incorrect");
+            }
+        }
+
+        return (InetAddressImpl) impl;
+    }
+    */
+    // END Android-removed: Android doesn't load user-provided implementation.
+
+    private void readObjectNoData (ObjectInputStream s) throws
+                         IOException, ClassNotFoundException {
+        // Android-changed: Don't use null to mean the boot classloader.
+        if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
+            throw new SecurityException ("invalid address type");
+        }
+    }
+
+    // Android-changed: Don't use null to mean the boot classloader.
+    private static final ClassLoader BOOT_CLASSLOADER = Object.class.getClassLoader();
+
+    private void readObject (ObjectInputStream s) throws
+                         IOException, ClassNotFoundException {
+        // Android-changed: Don't use null to mean the boot classloader.
+        if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
+            throw new SecurityException ("invalid address type");
+        }
+        GetField gf = s.readFields();
+        String host = (String)gf.get("hostName", null);
+        int address= gf.get("address", 0);
+        int family= gf.get("family", 0);
+        holder = new InetAddressHolder(host, address, family);
+    }
+
+    /* needed because the serializable fields no longer exist */
+
+    /**
+     * @serialField hostName String
+     * @serialField address int
+     * @serialField family int
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("hostName", String.class),
+        new ObjectStreamField("address", int.class),
+        new ObjectStreamField("family", int.class),
+    };
+
+    private void writeObject (ObjectOutputStream s) throws
+                        IOException {
+        // Android-changed: Don't use null to mean the boot classloader.
+        if (getClass().getClassLoader() != BOOT_CLASSLOADER) {
+            throw new SecurityException ("invalid address type");
+        }
+        PutField pf = s.putFields();
+        pf.put("hostName", holder().hostName);
+        pf.put("address", holder().address);
+        pf.put("family", holder().family);
+        s.writeFields();
+        s.flush();
+    }
+
+    static final int NETID_UNSET = 0;
+
+    // BEGIN Android-added: Add methods required by frameworks/base.
+    // Particularly those required to deal with scope ids.
+    /**
+     * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
+     *
+     * <p>This copes with all forms of address that Java supports, detailed in the
+     * {@link InetAddress} class documentation. An empty string is not treated as numeric.
+     *
+     * @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup.
+     * @deprecated Use {@link InetAddressUtils#isNumericAddress(String)} instead, if possible.
+     * @throws NullPointerException if the {@code address} is {@code null}.
+     */
+    @Deprecated
+    public static boolean isNumeric(String address) {
+        return InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(address) != null;
+    }
+
+    /**
+     * Returns an InetAddress corresponding to the given numeric address (such
+     * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
+     *
+     * <p>This method will never do a DNS lookup. Non-numeric addresses are errors. Passing either
+     * an empty string or a {@code null} as the {@code numericAddress} will return the
+     * {@link Inet6Address#LOOPBACK} address.
+     *
+     * @hide used by frameworks/base's NetworkUtils.numericToInetAddress
+     * @throws IllegalArgumentException if {@code numericAddress} is not a numeric address
+     * @deprecated Use {@link InetAddressUtils#parseNumericAddress(String)} instead, if possible.
+     */
+    @Deprecated
+    public static InetAddress parseNumericAddress(String numericAddress) {
+        if (numericAddress == null || numericAddress.isEmpty()) {
+            return Inet6Address.LOOPBACK;
+        }
+        InetAddress result = InetAddressUtils
+                .parseNumericAddressNoThrowStripOptionalBrackets(numericAddress);
+        if (result == null) {
+            throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
+        }
+        return result;
+    }
+
+    /**
+     * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS
+     * cache, nor any caching DNS servers between you and the canonical server.
+     * @hide
+     */
+    public static void clearDnsCache() {
+        impl.clearAddressCache();
+    }
+    // END Android-added: Add methods required by frameworks/base.
+    // BEGIN Android-added: Support for network (netId)-specific DNS resolution.
+    /**
+     * Operates identically to {@code getByName} except host resolution is
+     * performed on the network designated by {@code netId}.
+     *
+     * @param host
+     *            the hostName to be resolved to an address or {@code null}.
+     * @param netId the network to use for host resolution.
+     * @return the {@code InetAddress} instance representing the host.
+     * @throws UnknownHostException if the address lookup fails.
+     * @hide internal use only
+     */
+    public static InetAddress getByNameOnNet(String host, int netId) throws UnknownHostException {
+        return impl.lookupAllHostAddr(host, netId)[0];
+    }
+
+    /**
+     * Operates identically to {@code getAllByName} except host resolution is
+     * performed on the network designated by {@code netId}.
+     *
+     * @param host the hostname or literal IP string to be resolved.
+     * @param netId the network to use for host resolution.
+     * @return the array of addresses associated with the specified host.
+     * @throws UnknownHostException if the address lookup fails.
+     * @hide internal use only
+     */
+    public static InetAddress[] getAllByNameOnNet(String host, int netId) throws UnknownHostException {
+        return impl.lookupAllHostAddr(host, netId).clone();
+    }
+    // END Android-added: Support for network (netId)-specific DNS resolution.
+}
+// BEGIN Android-removed: Android doesn't load user-provided implementation.
+/*
+ * Simple factory to create the impl
+ *
+class InetAddressImplFactory {
+
+    static InetAddressImpl create() {
+        return InetAddress.loadImpl(isIPv6Supported() ?
+                                    "Inet6AddressImpl" : "Inet4AddressImpl");
+    }
+
+    static native boolean isIPv6Supported();
+}
+*/
+// END Android-removed: Android doesn't load user-provided implementation.
diff --git a/java/net/InetAddressContainer.java b/java/net/InetAddressContainer.java
new file mode 100644
index 0000000..28b6402
--- /dev/null
+++ b/java/net/InetAddressContainer.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+class InetAddressContainer {
+    InetAddress addr;
+}
diff --git a/java/net/InetAddressImpl.java b/java/net/InetAddressImpl.java
new file mode 100644
index 0000000..a636c1e
--- /dev/null
+++ b/java/net/InetAddressImpl.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+import java.io.IOException;
+/*
+ * Package private interface to "implementation" used by
+ * {@link InetAddress}.
+ * <p>
+ * See {@link java.net.Inet4AddressImp} and
+ * {@link java.net.Inet6AddressImp}.
+ *
+ * @since 1.4
+ */
+interface InetAddressImpl {
+
+    // BEGIN Android-changed: Rewrote hostname lookup methods on top of Libcore.os.
+    /*
+    String getLocalHostName() throws UnknownHostException;
+    InetAddress[]
+        lookupAllHostAddr(String hostname) throws UnknownHostException;
+     */
+    /**
+     * Lookup all addresses for {@code hostname} on the given {@code netId}.
+     */
+    InetAddress[] lookupAllHostAddr(String hostname, int netId) throws UnknownHostException;
+
+    /**
+     * Reverse-lookup the host name for a given {@code addr}.
+     */
+    String getHostByAddr(byte[] addr) throws UnknownHostException;
+
+    /**
+     * Clear address caches (if any).
+     */
+    public void clearAddressCache();
+    // END Android-changed: Rewrote hostname lookup methods on top of Libcore.os.
+
+    /**
+     * Return the "any" local address.
+     */
+    InetAddress anyLocalAddress();
+
+    // Android-changed: Let loopbackAddresses() return both Inet4 and Inet6 loopbacks.
+    // InetAddress loopbackAddress();
+    /**
+     * Return a list of loop back adresses for this implementation.
+     */
+    InetAddress[] loopbackAddresses();
+
+    /**
+     * Whether {@code addr} is reachable over {@code netif}.
+     */
+    boolean isReachable(InetAddress addr, int timeout, NetworkInterface netif,
+                        int ttl) throws IOException;
+}
diff --git a/java/net/InetSocketAddress.annotated.java b/java/net/InetSocketAddress.annotated.java
new file mode 100644
index 0000000..554b8e3
--- /dev/null
+++ b/java/net/InetSocketAddress.annotated.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class InetSocketAddress extends java.net.SocketAddress {
+
+@libcore.api.CorePlatformApi
+public InetSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public InetSocketAddress(int port) { throw new RuntimeException("Stub!"); }
+
+public InetSocketAddress(java.net.InetAddress addr, int port) { throw new RuntimeException("Stub!"); }
+
+public InetSocketAddress(java.lang.String hostname, int port) { throw new RuntimeException("Stub!"); }
+
+public static java.net.InetSocketAddress createUnresolved(java.lang.String host, int port) { throw new RuntimeException("Stub!"); }
+
+public final int getPort() { throw new RuntimeException("Stub!"); }
+
+public final java.net.InetAddress getAddress() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getHostName() { throw new RuntimeException("Stub!"); }
+
+public final java.lang.String getHostString() { throw new RuntimeException("Stub!"); }
+
+public final boolean isUnresolved() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public final boolean equals(java.lang.Object obj) { throw new RuntimeException("Stub!"); }
+
+public final int hashCode() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/net/InetSocketAddress.java b/java/net/InetSocketAddress.java
new file mode 100644
index 0000000..74b559b
--- /dev/null
+++ b/java/net/InetSocketAddress.java
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+
+/**
+ *
+ * This class implements an IP Socket Address (IP address + port number)
+ * It can also be a pair (hostname + port number), in which case an attempt
+ * will be made to resolve the hostname. If resolution fails then the address
+ * is said to be <I>unresolved</I> but can still be used on some circumstances
+ * like connecting through a proxy.
+ * <p>
+ * It provides an immutable object used by sockets for binding, connecting, or
+ * as returned values.
+ * <p>
+ * The <i>wildcard</i> is a special local IP address. It usually means "any"
+ * and can only be used for {@code bind} operations.
+ *
+ * @see java.net.Socket
+ * @see java.net.ServerSocket
+ * @since 1.4
+ */
+public class InetSocketAddress
+    extends SocketAddress
+{
+    // Private implementation class pointed to by all public methods.
+    private static class InetSocketAddressHolder {
+        // The hostname of the Socket Address
+        private String hostname;
+        // The IP address of the Socket Address
+        private InetAddress addr;
+        // The port number of the Socket Address
+        private int port;
+
+        private InetSocketAddressHolder(String hostname, InetAddress addr, int port) {
+            this.hostname = hostname;
+            this.addr = addr;
+            this.port = port;
+        }
+
+        private int getPort() {
+            return port;
+        }
+
+        private InetAddress getAddress() {
+            return addr;
+        }
+
+        private String getHostName() {
+            if (hostname != null)
+                return hostname;
+            if (addr != null)
+                return addr.getHostName();
+            return null;
+        }
+
+        private String getHostString() {
+            if (hostname != null)
+                return hostname;
+            if (addr != null) {
+                if (addr.holder().getHostName() != null)
+                    return addr.holder().getHostName();
+                else
+                    return addr.getHostAddress();
+            }
+            return null;
+        }
+
+        private boolean isUnresolved() {
+            return addr == null;
+        }
+
+        @Override
+        public String toString() {
+            if (isUnresolved()) {
+                return hostname + ":" + port;
+            } else {
+                return addr.toString() + ":" + port;
+            }
+        }
+
+        @Override
+        public final boolean equals(Object obj) {
+            if (obj == null || !(obj instanceof InetSocketAddressHolder))
+                return false;
+            InetSocketAddressHolder that = (InetSocketAddressHolder)obj;
+            boolean sameIP;
+            if (addr != null)
+                sameIP = addr.equals(that.addr);
+            else if (hostname != null)
+                sameIP = (that.addr == null) &&
+                    hostname.equalsIgnoreCase(that.hostname);
+            else
+                sameIP = (that.addr == null) && (that.hostname == null);
+            return sameIP && (port == that.port);
+        }
+
+        @Override
+        public final int hashCode() {
+            if (addr != null)
+                return addr.hashCode() + port;
+            if (hostname != null)
+                return hostname.toLowerCase().hashCode() + port;
+            return port;
+        }
+    }
+
+    private final transient InetSocketAddressHolder holder;
+
+    private static final long serialVersionUID = 5076001401234631237L;
+
+    private static int checkPort(int port) {
+        if (port < 0 || port > 0xFFFF)
+            throw new IllegalArgumentException("port out of range:" + port);
+        return port;
+    }
+
+    private static String checkHost(String hostname) {
+        if (hostname == null)
+            throw new IllegalArgumentException("hostname can't be null");
+        return hostname;
+    }
+
+    // BEGIN Android-added: InetSocketAddress() ctor used by IoBridge.
+    /**
+     * @hide internal use only
+     */
+    public InetSocketAddress() {
+        // These will be filled in the native implementation of recvfrom.
+        holder = new InetSocketAddressHolder(null, null, 0);
+    }
+    // END Android-added: InetSocketAddress() ctor used by IoBridge.
+
+    /**
+     * Creates a socket address where the IP address is the wildcard address
+     * and the port number a specified value.
+     * <p>
+     * A valid port value is between 0 and 65535.
+     * A port number of {@code zero} will let the system pick up an
+     * ephemeral port in a {@code bind} operation.
+     * <p>
+     * @param   port    The port number
+     * @throws IllegalArgumentException if the port parameter is outside the specified
+     * range of valid port values.
+     */
+    public InetSocketAddress(int port) {
+        // Android-changed: Defaults to IPv6.
+        // this(InetAddress.anyLocalAddress(), port);
+        this((InetAddress)null, port);
+    }
+
+    /**
+     *
+     * Creates a socket address from an IP address and a port number.
+     * <p>
+     * A valid port value is between 0 and 65535.
+     * A port number of {@code zero} will let the system pick up an
+     * ephemeral port in a {@code bind} operation.
+     * <P>
+     * A {@code null} address will assign the <i>wildcard</i> address.
+     * <p>
+     * @param   addr    The IP address
+     * @param   port    The port number
+     * @throws IllegalArgumentException if the port parameter is outside the specified
+     * range of valid port values.
+     */
+    public InetSocketAddress(InetAddress addr, int port) {
+        holder = new InetSocketAddressHolder(
+                        null,
+                        // Android-changed: Defaults to IPv6 if addr is null.
+                        // addr == null ? InetAddress.anyLocalAddress() : addr,
+                        addr == null ? Inet6Address.ANY : addr,
+                        checkPort(port));
+    }
+
+    /**
+     *
+     * Creates a socket address from a hostname and a port number.
+     * <p>
+     * An attempt will be made to resolve the hostname into an InetAddress.
+     * If that attempt fails, the address will be flagged as <I>unresolved</I>.
+     * <p>
+     * If there is a security manager, its {@code checkConnect} method
+     * is called with the host name as its argument to check the permission
+     * to resolve it. This could result in a SecurityException.
+     * <P>
+     * A valid port value is between 0 and 65535.
+     * A port number of {@code zero} will let the system pick up an
+     * ephemeral port in a {@code bind} operation.
+     * <P>
+     * @param   hostname the Host name
+     * @param   port    The port number
+     * @throws IllegalArgumentException if the port parameter is outside the range
+     * of valid port values, or if the hostname parameter is <TT>null</TT>.
+     * @throws SecurityException if a security manager is present and
+     *                           permission to resolve the host name is
+     *                           denied.
+     * @see     #isUnresolved()
+     */
+    public InetSocketAddress(String hostname, int port) {
+        checkHost(hostname);
+        InetAddress addr = null;
+        String host = null;
+        try {
+            addr = InetAddress.getByName(hostname);
+        } catch(UnknownHostException e) {
+            host = hostname;
+        }
+        holder = new InetSocketAddressHolder(host, addr, checkPort(port));
+    }
+
+    // private constructor for creating unresolved instances
+    private InetSocketAddress(int port, String hostname) {
+        holder = new InetSocketAddressHolder(hostname, null, port);
+    }
+
+    /**
+     *
+     * Creates an unresolved socket address from a hostname and a port number.
+     * <p>
+     * No attempt will be made to resolve the hostname into an InetAddress.
+     * The address will be flagged as <I>unresolved</I>.
+     * <p>
+     * A valid port value is between 0 and 65535.
+     * A port number of {@code zero} will let the system pick up an
+     * ephemeral port in a {@code bind} operation.
+     * <P>
+     * @param   host    the Host name
+     * @param   port    The port number
+     * @throws IllegalArgumentException if the port parameter is outside
+     *                  the range of valid port values, or if the hostname
+     *                  parameter is <TT>null</TT>.
+     * @see     #isUnresolved()
+     * @return  a {@code InetSocketAddress} representing the unresolved
+     *          socket address
+     * @since 1.5
+     */
+    public static InetSocketAddress createUnresolved(String host, int port) {
+        return new InetSocketAddress(checkPort(port), checkHost(host));
+    }
+
+    /**
+     * @serialField hostname String
+     * @serialField addr InetAddress
+     * @serialField port int
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+         new ObjectStreamField("hostname", String.class),
+         new ObjectStreamField("addr", InetAddress.class),
+         new ObjectStreamField("port", int.class)};
+
+    private void writeObject(ObjectOutputStream out)
+        throws IOException
+    {
+        // Don't call defaultWriteObject()
+         ObjectOutputStream.PutField pfields = out.putFields();
+         pfields.put("hostname", holder.hostname);
+         pfields.put("addr", holder.addr);
+         pfields.put("port", holder.port);
+         out.writeFields();
+     }
+
+    private void readObject(ObjectInputStream in)
+        throws IOException, ClassNotFoundException
+    {
+        // Don't call defaultReadObject()
+        ObjectInputStream.GetField oisFields = in.readFields();
+        final String oisHostname = (String)oisFields.get("hostname", null);
+        final InetAddress oisAddr = (InetAddress)oisFields.get("addr", null);
+        final int oisPort = oisFields.get("port", -1);
+
+        // Check that our invariants are satisfied
+        checkPort(oisPort);
+        if (oisHostname == null && oisAddr == null)
+            throw new InvalidObjectException("hostname and addr " +
+                                             "can't both be null");
+
+        InetSocketAddressHolder h = new InetSocketAddressHolder(oisHostname,
+                                                                oisAddr,
+                                                                oisPort);
+        UNSAFE.putObject(this, FIELDS_OFFSET, h);
+    }
+
+    private void readObjectNoData()
+        throws ObjectStreamException
+    {
+        throw new InvalidObjectException("Stream data required");
+    }
+
+    private static final long FIELDS_OFFSET;
+    private static final sun.misc.Unsafe UNSAFE;
+    static {
+        try {
+            sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
+            FIELDS_OFFSET = unsafe.objectFieldOffset(
+                    InetSocketAddress.class.getDeclaredField("holder"));
+            UNSAFE = unsafe;
+        } catch (ReflectiveOperationException e) {
+            throw new Error(e);
+        }
+    }
+
+    /**
+     * Gets the port number.
+     *
+     * @return the port number.
+     */
+    public final int getPort() {
+        return holder.getPort();
+    }
+
+    /**
+     *
+     * Gets the {@code InetAddress}.
+     *
+     * @return the InetAdress or {@code null} if it is unresolved.
+     */
+    public final InetAddress getAddress() {
+        return holder.getAddress();
+    }
+
+    /**
+     * Gets the {@code hostname}.
+     * Note: This method may trigger a name service reverse lookup if the
+     * address was created with a literal IP address.
+     *
+     * @return  the hostname part of the address.
+     */
+    public final String getHostName() {
+        return holder.getHostName();
+    }
+
+    /**
+     * Returns the hostname, or the String form of the address if it
+     * doesn't have a hostname (it was created using a literal).
+     * This has the benefit of <b>not</b> attempting a reverse lookup.
+     *
+     * @return the hostname, or String representation of the address.
+     * @since 1.7
+     */
+    public final String getHostString() {
+        return holder.getHostString();
+    }
+
+    /**
+     * Checks whether the address has been resolved or not.
+     *
+     * @return {@code true} if the hostname couldn't be resolved into
+     *          an {@code InetAddress}.
+     */
+    public final boolean isUnresolved() {
+        return holder.isUnresolved();
+    }
+
+    /**
+     * Constructs a string representation of this InetSocketAddress.
+     * This String is constructed by calling toString() on the InetAddress
+     * and concatenating the port number (with a colon). If the address
+     * is unresolved then the part before the colon will only contain the hostname.
+     *
+     * @return  a string representation of this object.
+     */
+    @Override
+    public String toString() {
+        return holder.toString();
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is
+     * not {@code null} and it represents the same address as
+     * this object.
+     * <p>
+     * Two instances of {@code InetSocketAddress} represent the same
+     * address if both the InetAddresses (or hostnames if it is unresolved) and port
+     * numbers are equal.
+     * If both addresses are unresolved, then the hostname and the port number
+     * are compared.
+     *
+     * Note: Hostnames are case insensitive. e.g. "FooBar" and "foobar" are
+     * considered equal.
+     *
+     * @param   obj   the object to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see java.net.InetAddress#equals(java.lang.Object)
+     */
+    @Override
+    public final boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof InetSocketAddress))
+            return false;
+        return holder.equals(((InetSocketAddress) obj).holder);
+    }
+
+    /**
+     * Returns a hashcode for this socket address.
+     *
+     * @return  a hash code value for this socket address.
+     */
+    @Override
+    public final int hashCode() {
+        return holder.hashCode();
+    }
+}
diff --git a/java/net/InterfaceAddress.java b/java/net/InterfaceAddress.java
new file mode 100644
index 0000000..85f9e58
--- /dev/null
+++ b/java/net/InterfaceAddress.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This class represents a Network Interface address. In short it's an
+ * IP address, a subnet mask and a broadcast address when the address is
+ * an IPv4 one. An IP address and a network prefix length in the case
+ * of IPv6 address.
+ *
+ * @see java.net.NetworkInterface
+ * @since 1.6
+ */
+public class InterfaceAddress {
+    private InetAddress address = null;
+    private Inet4Address broadcast = null;
+    private short        maskLength = 0;
+
+    /*
+     * Package private constructor. Can't be built directly, instances are
+     * obtained through the NetworkInterface class.
+     */
+    InterfaceAddress() {
+    }
+
+    // BEGIN Android-added: Rewrote NetworkInterface on top of Libcore.io.
+    InterfaceAddress(InetAddress address, Inet4Address broadcast, InetAddress netmask) {
+        this.address = address;
+        this.broadcast = broadcast;
+        this.maskLength = countPrefixLength(netmask);
+    }
+
+    /**
+     * Counts the prefix length for the netmask address.
+     *
+     * A valid netmask address must start with a continuous sequence of 1, followed by a continuous
+     * sequence of 0.
+     */
+    private short countPrefixLength(InetAddress netmask) {
+        short count = 0;
+        for (byte b : netmask.getAddress()) {
+            for (; b != 0; b <<= 1, ++count);
+        }
+        return count;
+    }
+    // END Android-added: Rewrote NetworkInterface on top of Libcore.io.
+
+    /**
+     * Returns an {@code InetAddress} for this address.
+     *
+     * @return the {@code InetAddress} for this address.
+     */
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    /**
+     * Returns an {@code InetAddress} for the broadcast address
+     * for this InterfaceAddress.
+     * <p>
+     * Only IPv4 networks have broadcast address therefore, in the case
+     * of an IPv6 network, {@code null} will be returned.
+     *
+     * @return the {@code InetAddress} representing the broadcast
+     *         address or {@code null} if there is no broadcast address.
+     */
+    public InetAddress getBroadcast() {
+        return broadcast;
+    }
+
+    /**
+     * Returns the network prefix length for this address. This is also known
+     * as the subnet mask in the context of IPv4 addresses.
+     * Typical IPv4 values would be 8 (255.0.0.0), 16 (255.255.0.0)
+     * or 24 (255.255.255.0). <p>
+     * Typical IPv6 values would be 128 (::1/128) or 10 (fe80::203:baff:fe27:1243/10)
+     *
+     * @return a {@code short} representing the prefix length for the
+     *         subnet of that address.
+     */
+     public short getNetworkPrefixLength() {
+        return maskLength;
+    }
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is
+     * not {@code null} and it represents the same interface address as
+     * this object.
+     * <p>
+     * Two instances of {@code InterfaceAddress} represent the same
+     * address if the InetAddress, the prefix length and the broadcast are
+     * the same for both.
+     *
+     * @param   obj   the object to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see     java.net.InterfaceAddress#hashCode()
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof InterfaceAddress)) {
+            return false;
+        }
+        InterfaceAddress cmp = (InterfaceAddress) obj;
+        if ( !(address == null ? cmp.address == null : address.equals(cmp.address)) )
+            return false;
+        if ( !(broadcast  == null ? cmp.broadcast == null : broadcast.equals(cmp.broadcast)) )
+            return false;
+        if (maskLength != cmp.maskLength)
+            return false;
+        return true;
+    }
+
+    /**
+     * Returns a hashcode for this Interface address.
+     *
+     * @return  a hash code value for this Interface address.
+     */
+    public int hashCode() {
+        return address.hashCode() + ((broadcast != null) ? broadcast.hashCode() : 0) + maskLength;
+    }
+
+    /**
+     * Converts this Interface address to a {@code String}. The
+     * string returned is of the form: InetAddress / prefix length [ broadcast address ].
+     *
+     * @return  a string representation of this Interface address.
+     */
+    public String toString() {
+        return address + "/" + maskLength + " [" + broadcast + "]";
+    }
+
+}
diff --git a/java/net/JarURLConnection.java b/java/net/JarURLConnection.java
new file mode 100644
index 0000000..70dedec
--- /dev/null
+++ b/java/net/JarURLConnection.java
@@ -0,0 +1,309 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.util.jar.JarFile;
+import java.util.jar.JarEntry;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.security.Permission;
+import sun.net.www.ParseUtil;
+
+/**
+ * A URL Connection to a Java ARchive (JAR) file or an entry in a JAR
+ * file.
+ *
+ * <p>The syntax of a JAR URL is:
+ *
+ * <pre>
+ * jar:&lt;url&gt;!/{entry}
+ * </pre>
+ *
+ * <p>for example:
+ *
+ * <p>{@code jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class}
+ *
+ * <p>Jar URLs should be used to refer to a JAR file or entries in
+ * a JAR file. The example above is a JAR URL which refers to a JAR
+ * entry. If the entry name is omitted, the URL refers to the whole
+ * JAR file:
+ *
+ * {@code jar:http://www.foo.com/bar/baz.jar!/}
+ *
+ * <p>Users should cast the generic URLConnection to a
+ * JarURLConnection when they know that the URL they created is a JAR
+ * URL, and they need JAR-specific functionality. For example:
+ *
+ * <pre>
+ * URL url = new URL("jar:file:/home/duke/duke.jar!/");
+ * JarURLConnection jarConnection = (JarURLConnection)url.openConnection();
+ * Manifest manifest = jarConnection.getManifest();
+ * </pre>
+ *
+ * <p>JarURLConnection instances can only be used to read from JAR files.
+ * It is not possible to get a {@link java.io.OutputStream} to modify or write
+ * to the underlying JAR file using this class.
+ * <p>Examples:
+ *
+ * <dl>
+ *
+ * <dt>A Jar entry
+ * <dd>{@code jar:http://www.foo.com/bar/baz.jar!/COM/foo/Quux.class}
+ *
+ * <dt>A Jar file
+ * <dd>{@code jar:http://www.foo.com/bar/baz.jar!/}
+ *
+ * <dt>A Jar directory
+ * <dd>{@code jar:http://www.foo.com/bar/baz.jar!/COM/foo/}
+ *
+ * </dl>
+ *
+ * <p>{@code !/} is referred to as the <em>separator</em>.
+ *
+ * <p>When constructing a JAR url via {@code new URL(context, spec)},
+ * the following rules apply:
+ *
+ * <ul>
+ *
+ * <li>if there is no context URL and the specification passed to the
+ * URL constructor doesn't contain a separator, the URL is considered
+ * to refer to a JarFile.
+ *
+ * <li>if there is a context URL, the context URL is assumed to refer
+ * to a JAR file or a Jar directory.
+ *
+ * <li>if the specification begins with a '/', the Jar directory is
+ * ignored, and the spec is considered to be at the root of the Jar
+ * file.
+ *
+ * <p>Examples:
+ *
+ * <dl>
+ *
+ * <dt>context: <b>jar:http://www.foo.com/bar/jar.jar!/</b>,
+ * spec:<b>baz/entry.txt</b>
+ *
+ * <dd>url:<b>jar:http://www.foo.com/bar/jar.jar!/baz/entry.txt</b>
+ *
+ * <dt>context: <b>jar:http://www.foo.com/bar/jar.jar!/baz</b>,
+ * spec:<b>entry.txt</b>
+ *
+ * <dd>url:<b>jar:http://www.foo.com/bar/jar.jar!/baz/entry.txt</b>
+ *
+ * <dt>context: <b>jar:http://www.foo.com/bar/jar.jar!/baz</b>,
+ * spec:<b>/entry.txt</b>
+ *
+ * <dd>url:<b>jar:http://www.foo.com/bar/jar.jar!/entry.txt</b>
+ *
+ * </dl>
+ *
+ * </ul>
+ *
+ * @see java.net.URL
+ * @see java.net.URLConnection
+ *
+ * @see java.util.jar.JarFile
+ * @see java.util.jar.JarInputStream
+ * @see java.util.jar.Manifest
+ * @see java.util.zip.ZipEntry
+ *
+ * @author Benjamin Renaud
+ * @since 1.2
+ */
+public abstract class JarURLConnection extends URLConnection {
+
+    private URL jarFileURL;
+    private String entryName;
+
+    /**
+     * The connection to the JAR file URL, if the connection has been
+     * initiated. This should be set by connect.
+     */
+    protected URLConnection jarFileURLConnection;
+
+    /**
+     * Creates the new JarURLConnection to the specified URL.
+     * @param url the URL
+     * @throws MalformedURLException if no legal protocol
+     * could be found in a specification string or the
+     * string could not be parsed.
+     */
+
+    protected JarURLConnection(URL url) throws MalformedURLException {
+        super(url);
+        parseSpecs(url);
+    }
+
+    /* get the specs for a given url out of the cache, and compute and
+     * cache them if they're not there.
+     */
+    private void parseSpecs(URL url) throws MalformedURLException {
+        String spec = url.getFile();
+
+        int separator = spec.indexOf("!/");
+        /*
+         * REMIND: we don't handle nested JAR URLs
+         */
+        if (separator == -1) {
+            throw new MalformedURLException("no !/ found in url spec:" + spec);
+        }
+
+        jarFileURL = new URL(spec.substring(0, separator++));
+        entryName = null;
+
+        /* if ! is the last letter of the innerURL, entryName is null */
+        if (++separator != spec.length()) {
+            entryName = spec.substring(separator, spec.length());
+            entryName = ParseUtil.decode (entryName);
+        }
+    }
+
+    /**
+     * Returns the URL for the Jar file for this connection.
+     *
+     * @return the URL for the Jar file for this connection.
+     */
+    public URL getJarFileURL() {
+        return jarFileURL;
+    }
+
+    /**
+     * Return the entry name for this connection. This method
+     * returns null if the JAR file URL corresponding to this
+     * connection points to a JAR file and not a JAR file entry.
+     *
+     * @return the entry name for this connection, if any.
+     */
+    public String getEntryName() {
+        return entryName;
+    }
+
+    /**
+     * Return the JAR file for this connection.
+     *
+     * @return the JAR file for this connection. If the connection is
+     * a connection to an entry of a JAR file, the JAR file object is
+     * returned
+     *
+     * @exception IOException if an IOException occurs while trying to
+     * connect to the JAR file for this connection.
+     *
+     * @see #connect
+     */
+    public abstract JarFile getJarFile() throws IOException;
+
+    /**
+     * Returns the Manifest for this connection, or null if none.
+     *
+     * @return the manifest object corresponding to the JAR file object
+     * for this connection.
+     *
+     * @exception IOException if getting the JAR file for this
+     * connection causes an IOException to be thrown.
+     *
+     * @see #getJarFile
+     */
+    public Manifest getManifest() throws IOException {
+        return getJarFile().getManifest();
+    }
+
+    /**
+     * Return the JAR entry object for this connection, if any. This
+     * method returns null if the JAR file URL corresponding to this
+     * connection points to a JAR file and not a JAR file entry.
+     *
+     * @return the JAR entry object for this connection, or null if
+     * the JAR URL for this connection points to a JAR file.
+     *
+     * @exception IOException if getting the JAR file for this
+     * connection causes an IOException to be thrown.
+     *
+     * @see #getJarFile
+     * @see #getJarEntry
+     */
+    public JarEntry getJarEntry() throws IOException {
+        return getJarFile().getJarEntry(entryName);
+    }
+
+    /**
+     * Return the Attributes object for this connection if the URL
+     * for it points to a JAR file entry, null otherwise.
+     *
+     * @return the Attributes object for this connection if the URL
+     * for it points to a JAR file entry, null otherwise.
+     *
+     * @exception IOException if getting the JAR entry causes an
+     * IOException to be thrown.
+     *
+     * @see #getJarEntry
+     */
+    public Attributes getAttributes() throws IOException {
+        JarEntry e = getJarEntry();
+        return e != null ? e.getAttributes() : null;
+    }
+
+    /**
+     * Returns the main Attributes for the JAR file for this
+     * connection.
+     *
+     * @return the main Attributes for the JAR file for this
+     * connection.
+     *
+     * @exception IOException if getting the manifest causes an
+     * IOException to be thrown.
+     *
+     * @see #getJarFile
+     * @see #getManifest
+     */
+    public Attributes getMainAttributes() throws IOException {
+        Manifest man = getManifest();
+        return man != null ? man.getMainAttributes() : null;
+    }
+
+    /**
+     * Return the Certificate object for this connection if the URL
+     * for it points to a JAR file entry, null otherwise. This method
+     * can only be called once
+     * the connection has been completely verified by reading
+     * from the input stream until the end of the stream has been
+     * reached. Otherwise, this method will return {@code null}
+     *
+     * @return the Certificate object for this connection if the URL
+     * for it points to a JAR file entry, null otherwise.
+     *
+     * @exception IOException if getting the JAR entry causes an
+     * IOException to be thrown.
+     *
+     * @see #getJarEntry
+     */
+    public java.security.cert.Certificate[] getCertificates()
+         throws IOException
+    {
+        JarEntry e = getJarEntry();
+        return e != null ? e.getCertificates() : null;
+    }
+}
diff --git a/java/net/MalformedURLException.java b/java/net/MalformedURLException.java
new file mode 100644
index 0000000..7aef75c
--- /dev/null
+++ b/java/net/MalformedURLException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Thrown to indicate that a malformed URL has occurred. Either no
+ * legal protocol could be found in a specification string or the
+ * string could not be parsed.
+ *
+ * @author  Arthur van Hoff
+ * @since   JDK1.0
+ */
+public class MalformedURLException extends IOException {
+    private static final long serialVersionUID = -182787522200415866L;
+
+    /**
+     * Constructs a {@code MalformedURLException} with no detail message.
+     */
+    public MalformedURLException() {
+    }
+
+    /**
+     * Constructs a {@code MalformedURLException} with the
+     * specified detail message.
+     *
+     * @param   msg   the detail message.
+     */
+    public MalformedURLException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/net/MulticastSocket.java b/java/net/MulticastSocket.java
new file mode 100644
index 0000000..83a18c3
--- /dev/null
+++ b/java/net/MulticastSocket.java
@@ -0,0 +1,712 @@
+/*
+ * Copyright (c) 1995, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.util.Enumeration;
+
+// Android-changed: Updated example code to handle non-ASCII characters
+/**
+ * The multicast datagram socket class is useful for sending
+ * and receiving IP multicast packets.  A MulticastSocket is
+ * a (UDP) DatagramSocket, with additional capabilities for
+ * joining "groups" of other multicast hosts on the internet.
+ * <P>
+ * A multicast group is specified by a class D IP address
+ * and by a standard UDP port number. Class D IP addresses
+ * are in the range <CODE>224.0.0.0</CODE> to <CODE>239.255.255.255</CODE>,
+ * inclusive. The address 224.0.0.0 is reserved and should not be used.
+ * <P>
+ * One would join a multicast group by first creating a MulticastSocket
+ * with the desired port, then invoking the
+ * <CODE>joinGroup(InetAddress groupAddr)</CODE>
+ * method:
+ * <PRE>
+ * // join a Multicast group and send the group salutations
+ * ...
+ * String msg = "Hello";
+ * InetAddress group = InetAddress.getByName("228.5.6.7");
+ * MulticastSocket s = new MulticastSocket(6789);
+ * s.joinGroup(group);
+ * byte[] bytes = msg.getBytes(StandardCharsets.UTF_8);
+ * DatagramPacket hi = new DatagramPacket(bytes, bytes.length,
+ *                             group, 6789);
+ * s.send(hi);
+ * // get their responses!
+ * byte[] buf = new byte[1000];
+ * DatagramPacket recv = new DatagramPacket(buf, buf.length);
+ * s.receive(recv);
+ * ...
+ * // OK, I'm done talking - leave the group...
+ * s.leaveGroup(group);
+ * </PRE>
+ *
+ * When one sends a message to a multicast group, <B>all</B> subscribing
+ * recipients to that host and port receive the message (within the
+ * time-to-live range of the packet, see below).  The socket needn't
+ * be a member of the multicast group to send messages to it.
+ * <P>
+ * When a socket subscribes to a multicast group/port, it receives
+ * datagrams sent by other hosts to the group/port, as do all other
+ * members of the group and port.  A socket relinquishes membership
+ * in a group by the leaveGroup(InetAddress addr) method.  <B>
+ * Multiple MulticastSocket's</B> may subscribe to a multicast group
+ * and port concurrently, and they will all receive group datagrams.
+ * <P>
+ * Currently applets are not allowed to use multicast sockets.
+ *
+ * @author Pavani Diwanji
+ * @since  JDK1.1
+ */
+public
+class MulticastSocket extends DatagramSocket {
+
+    /**
+     * Used on some platforms to record if an outgoing interface
+     * has been set for this socket.
+     */
+    private boolean interfaceSet;
+
+    /**
+     * Create a multicast socket.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with 0 as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     * <p>
+     * When the socket is created the
+     * {@link DatagramSocket#setReuseAddress(boolean)} method is
+     * called to enable the SO_REUSEADDR socket option.
+     *
+     * @exception IOException if an I/O exception occurs
+     * while creating the MulticastSocket
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     * @see SecurityManager#checkListen
+     * @see java.net.DatagramSocket#setReuseAddress(boolean)
+     */
+    public MulticastSocket() throws IOException {
+        this(new InetSocketAddress(0));
+    }
+
+    /**
+     * Create a multicast socket and bind it to a specific port.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with the {@code port} argument
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     * <p>
+     * When the socket is created the
+     * {@link DatagramSocket#setReuseAddress(boolean)} method is
+     * called to enable the SO_REUSEADDR socket option.
+     *
+     * @param port port to use
+     * @exception IOException if an I/O exception occurs
+     * while creating the MulticastSocket
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     * @see SecurityManager#checkListen
+     * @see java.net.DatagramSocket#setReuseAddress(boolean)
+     */
+    public MulticastSocket(int port) throws IOException {
+        this(new InetSocketAddress(port));
+    }
+
+    /**
+     * Create a MulticastSocket bound to the specified socket address.
+     * <p>
+     * Or, if the address is {@code null}, create an unbound socket.
+     *
+     * <p>If there is a security manager,
+     * its {@code checkListen} method is first called
+     * with the SocketAddress port as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     * <p>
+     * When the socket is created the
+     * {@link DatagramSocket#setReuseAddress(boolean)} method is
+     * called to enable the SO_REUSEADDR socket option.
+     *
+     * @param bindaddr Socket address to bind to, or {@code null} for
+     *                 an unbound socket.
+     * @exception IOException if an I/O exception occurs
+     * while creating the MulticastSocket
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkListen} method doesn't allow the operation.
+     * @see SecurityManager#checkListen
+     * @see java.net.DatagramSocket#setReuseAddress(boolean)
+     *
+     * @since 1.4
+     */
+    public MulticastSocket(SocketAddress bindaddr) throws IOException {
+        super((SocketAddress) null);
+
+        // Enable SO_REUSEADDR before binding
+        setReuseAddress(true);
+
+        if (bindaddr != null) {
+            try {
+                bind(bindaddr);
+            } finally {
+                if (!isBound())
+                    close();
+            }
+        }
+    }
+
+    /**
+     * The lock on the socket's TTL. This is for set/getTTL and
+     * send(packet,ttl).
+     */
+    private Object ttlLock = new Object();
+
+    /**
+     * The lock on the socket's interface - used by setInterface
+     * and getInterface
+     */
+    private Object infLock = new Object();
+
+    /**
+     * The "last" interface set by setInterface on this MulticastSocket
+     */
+    private InetAddress infAddress = null;
+
+
+    /**
+     * Set the default time-to-live for multicast packets sent out
+     * on this {@code MulticastSocket} in order to control the
+     * scope of the multicasts.
+     *
+     * <p>The ttl is an <b>unsigned</b> 8-bit quantity, and so <B>must</B> be
+     * in the range {@code 0 <= ttl <= 0xFF }.
+     *
+     * @param ttl the time-to-live
+     * @exception IOException if an I/O exception occurs
+     * while setting the default time-to-live value
+     * @deprecated use the setTimeToLive method instead, which uses
+     * <b>int</b> instead of <b>byte</b> as the type for ttl.
+     * @see #getTTL()
+     */
+    @Deprecated
+    public void setTTL(byte ttl) throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setTTL(ttl);
+    }
+
+    /**
+     * Set the default time-to-live for multicast packets sent out
+     * on this {@code MulticastSocket} in order to control the
+     * scope of the multicasts.
+     *
+     * <P> The ttl <B>must</B> be in the range {@code  0 <= ttl <=
+     * 255} or an {@code IllegalArgumentException} will be thrown.
+     * Multicast packets sent with a TTL of {@code 0} are not transmitted
+     * on the network but may be delivered locally.
+     *
+     * @param  ttl
+     *         the time-to-live
+     *
+     * @throws  IOException
+     *          if an I/O exception occurs while setting the
+     *          default time-to-live value
+     *
+     * @see #getTimeToLive()
+     */
+    public void setTimeToLive(int ttl) throws IOException {
+        if (ttl < 0 || ttl > 255) {
+            throw new IllegalArgumentException("ttl out of range");
+        }
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setTimeToLive(ttl);
+    }
+
+    /**
+     * Get the default time-to-live for multicast packets sent out on
+     * the socket.
+     *
+     * @exception IOException if an I/O exception occurs
+     * while getting the default time-to-live value
+     * @return the default time-to-live value
+     * @deprecated use the getTimeToLive method instead, which returns
+     * an <b>int</b> instead of a <b>byte</b>.
+     * @see #setTTL(byte)
+     */
+    @Deprecated
+    public byte getTTL() throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return getImpl().getTTL();
+    }
+
+    /**
+     * Get the default time-to-live for multicast packets sent out on
+     * the socket.
+     * @exception IOException if an I/O exception occurs while
+     * getting the default time-to-live value
+     * @return the default time-to-live value
+     * @see #setTimeToLive(int)
+     */
+    public int getTimeToLive() throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return getImpl().getTimeToLive();
+    }
+
+    /**
+     * Joins a multicast group. Its behavior may be affected by
+     * {@code setInterface} or {@code setNetworkInterface}.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkMulticast} method
+     * with the {@code mcastaddr} argument
+     * as its argument.
+     *
+     * @param mcastaddr is the multicast address to join
+     *
+     * @exception IOException if there is an error joining
+     * or when the address is not a multicast address.
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkMulticast} method doesn't allow the join.
+     *
+     * @see SecurityManager#checkMulticast(InetAddress)
+     */
+    public void joinGroup(InetAddress mcastaddr) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+
+        checkAddress(mcastaddr, "joinGroup");
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkMulticast(mcastaddr);
+        }
+
+        if (!mcastaddr.isMulticastAddress()) {
+            throw new SocketException("Not a multicast address");
+        }
+
+        /**
+         * required for some platforms where it's not possible to join
+         * a group without setting the interface first.
+         */
+        NetworkInterface defaultInterface = NetworkInterface.getDefault();
+
+        if (!interfaceSet && defaultInterface != null) {
+            setNetworkInterface(defaultInterface);
+        }
+
+        getImpl().join(mcastaddr);
+    }
+
+    /**
+     * Leave a multicast group. Its behavior may be affected by
+     * {@code setInterface} or {@code setNetworkInterface}.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkMulticast} method
+     * with the {@code mcastaddr} argument
+     * as its argument.
+     *
+     * @param mcastaddr is the multicast address to leave
+     * @exception IOException if there is an error leaving
+     * or when the address is not a multicast address.
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkMulticast} method doesn't allow the operation.
+     *
+     * @see SecurityManager#checkMulticast(InetAddress)
+     */
+    public void leaveGroup(InetAddress mcastaddr) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+
+        checkAddress(mcastaddr, "leaveGroup");
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkMulticast(mcastaddr);
+        }
+
+        if (!mcastaddr.isMulticastAddress()) {
+            throw new SocketException("Not a multicast address");
+        }
+
+        getImpl().leave(mcastaddr);
+    }
+
+    /**
+     * Joins the specified multicast group at the specified interface.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkMulticast} method
+     * with the {@code mcastaddr} argument
+     * as its argument.
+     *
+     * @param mcastaddr is the multicast address to join
+     * @param netIf specifies the local interface to receive multicast
+     *        datagram packets, or <i>null</i> to defer to the interface set by
+     *       {@link MulticastSocket#setInterface(InetAddress)} or
+     *       {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
+     *
+     * @exception IOException if there is an error joining
+     * or when the address is not a multicast address.
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkMulticast} method doesn't allow the join.
+     * @throws  IllegalArgumentException if mcastaddr is null or is a
+     *          SocketAddress subclass not supported by this socket
+     *
+     * @see SecurityManager#checkMulticast(InetAddress)
+     * @since 1.4
+     */
+    public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf)
+        throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+
+        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+
+        if (oldImpl)
+            throw new UnsupportedOperationException();
+
+        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "joinGroup");
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
+        }
+
+        if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
+            throw new SocketException("Not a multicast address");
+        }
+
+        getImpl().joinGroup(mcastaddr, netIf);
+    }
+
+    /**
+     * Leave a multicast group on a specified local interface.
+     *
+     * <p>If there is a security manager, this method first
+     * calls its {@code checkMulticast} method
+     * with the {@code mcastaddr} argument
+     * as its argument.
+     *
+     * @param mcastaddr is the multicast address to leave
+     * @param netIf specifies the local interface or <i>null</i> to defer
+     *             to the interface set by
+     *             {@link MulticastSocket#setInterface(InetAddress)} or
+     *             {@link MulticastSocket#setNetworkInterface(NetworkInterface)}
+     * @exception IOException if there is an error leaving
+     * or when the address is not a multicast address.
+     * @exception  SecurityException  if a security manager exists and its
+     * {@code checkMulticast} method doesn't allow the operation.
+     * @throws  IllegalArgumentException if mcastaddr is null or is a
+     *          SocketAddress subclass not supported by this socket
+     *
+     * @see SecurityManager#checkMulticast(InetAddress)
+     * @since 1.4
+     */
+    public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf)
+        throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+
+        if (mcastaddr == null || !(mcastaddr instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+
+        if (oldImpl)
+            throw new UnsupportedOperationException();
+
+        checkAddress(((InetSocketAddress)mcastaddr).getAddress(), "leaveGroup");
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkMulticast(((InetSocketAddress)mcastaddr).getAddress());
+        }
+
+        if (!((InetSocketAddress)mcastaddr).getAddress().isMulticastAddress()) {
+            throw new SocketException("Not a multicast address");
+        }
+
+        getImpl().leaveGroup(mcastaddr, netIf);
+     }
+
+    /**
+     * Set the multicast network interface used by methods
+     * whose behavior would be affected by the value of the
+     * network interface. Useful for multihomed hosts.
+     * @param inf the InetAddress
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as a TCP error.
+     * @see #getInterface()
+     */
+    public void setInterface(InetAddress inf) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+        checkAddress(inf, "setInterface");
+        synchronized (infLock) {
+            getImpl().setOption(SocketOptions.IP_MULTICAST_IF, inf);
+            infAddress = inf;
+            interfaceSet = true;
+        }
+    }
+
+    /**
+     * Retrieve the address of the network interface used for
+     * multicast packets.
+     *
+     * @return An {@code InetAddress} representing
+     *  the address of the network interface used for
+     *  multicast packets.
+     *
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as a TCP error.
+     *
+     * @see #setInterface(java.net.InetAddress)
+     */
+    public InetAddress getInterface() throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+        synchronized (infLock) {
+            InetAddress ia =
+                (InetAddress)getImpl().getOption(SocketOptions.IP_MULTICAST_IF);
+
+            /**
+             * No previous setInterface or interface can be
+             * set using setNetworkInterface
+             */
+            if (infAddress == null) {
+                return ia;
+            }
+
+            /**
+             * Same interface set with setInterface?
+             */
+            if (ia.equals(infAddress)) {
+                return ia;
+            }
+
+            /**
+             * Different InetAddress from what we set with setInterface
+             * so enumerate the current interface to see if the
+             * address set by setInterface is bound to this interface.
+             */
+            try {
+                NetworkInterface ni = NetworkInterface.getByInetAddress(ia);
+                Enumeration<InetAddress> addrs = ni.getInetAddresses();
+                while (addrs.hasMoreElements()) {
+                    InetAddress addr = addrs.nextElement();
+                    if (addr.equals(infAddress)) {
+                        return infAddress;
+                    }
+                }
+
+                /**
+                 * No match so reset infAddress to indicate that the
+                 * interface has changed via means
+                 */
+                infAddress = null;
+                return ia;
+            } catch (Exception e) {
+                return ia;
+            }
+        }
+    }
+
+    /**
+     * Specify the network interface for outgoing multicast datagrams
+     * sent on this socket.
+     *
+     * @param netIf the interface
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as a TCP error.
+     * @see #getNetworkInterface()
+     * @since 1.4
+     */
+    public void setNetworkInterface(NetworkInterface netIf)
+        throws SocketException {
+
+        synchronized (infLock) {
+            getImpl().setOption(SocketOptions.IP_MULTICAST_IF2, netIf);
+            infAddress = null;
+            interfaceSet = true;
+        }
+    }
+
+    /**
+     * Get the multicast network interface set.
+     *
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as a TCP error.
+     * @return the multicast {@code NetworkInterface} currently set
+     * @see #setNetworkInterface(NetworkInterface)
+     * @since 1.4
+     */
+    public NetworkInterface getNetworkInterface() throws SocketException {
+        // Android-changed: Support Integer IP_MULTICAST_IF2 values for app compat.
+        Integer niIndex
+            = (Integer)getImpl().getOption(SocketOptions.IP_MULTICAST_IF2);
+        if (niIndex == 0) {
+            InetAddress[] addrs = new InetAddress[1];
+            addrs[0] = InetAddress.anyLocalAddress();
+            return new NetworkInterface(addrs[0].getHostName(), 0, addrs);
+        } else {
+            return NetworkInterface.getByIndex(niIndex);
+        }
+    }
+
+    /**
+     * Disable/Enable local loopback of multicast datagrams
+     * The option is used by the platform's networking code as a hint
+     * for setting whether multicast data will be looped back to
+     * the local socket.
+     *
+     * <p>Because this option is a hint, applications that want to
+     * verify what loopback mode is set to should call
+     * {@link #getLoopbackMode()}
+     * @param disable {@code true} to disable the LoopbackMode
+     * @throws SocketException if an error occurs while setting the value
+     * @since 1.4
+     * @see #getLoopbackMode
+     */
+    public void setLoopbackMode(boolean disable) throws SocketException {
+        getImpl().setOption(SocketOptions.IP_MULTICAST_LOOP, Boolean.valueOf(disable));
+    }
+
+    /**
+     * Get the setting for local loopback of multicast datagrams.
+     *
+     * @throws SocketException  if an error occurs while getting the value
+     * @return true if the LoopbackMode has been disabled
+     * @since 1.4
+     * @see #setLoopbackMode
+     */
+    public boolean getLoopbackMode() throws SocketException {
+        return ((Boolean)getImpl().getOption(SocketOptions.IP_MULTICAST_LOOP)).booleanValue();
+    }
+
+    /**
+     * Sends a datagram packet to the destination, with a TTL (time-
+     * to-live) other than the default for the socket.  This method
+     * need only be used in instances where a particular TTL is desired;
+     * otherwise it is preferable to set a TTL once on the socket, and
+     * use that default TTL for all packets.  This method does <B>not
+     * </B> alter the default TTL for the socket. Its behavior may be
+     * affected by {@code setInterface}.
+     *
+     * <p>If there is a security manager, this method first performs some
+     * security checks. First, if {@code p.getAddress().isMulticastAddress()}
+     * is true, this method calls the
+     * security manager's {@code checkMulticast} method
+     * with {@code p.getAddress()} and {@code ttl} as its arguments.
+     * If the evaluation of that expression is false,
+     * this method instead calls the security manager's
+     * {@code checkConnect} method with arguments
+     * {@code p.getAddress().getHostAddress()} and
+     * {@code p.getPort()}. Each call to a security manager method
+     * could result in a SecurityException if the operation is not allowed.
+     *
+     * @param p is the packet to be sent. The packet should contain
+     * the destination multicast ip address and the data to be sent.
+     * One does not need to be the member of the group to send
+     * packets to a destination multicast address.
+     * @param ttl optional time to live for multicast packet.
+     * default ttl is 1.
+     *
+     * @exception IOException is raised if an error occurs i.e
+     * error while setting ttl.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkMulticast} or {@code checkConnect}
+     *             method doesn't allow the send.
+     *
+     * @deprecated Use the following code or its equivalent instead:
+     *  ......
+     *  int ttl = mcastSocket.getTimeToLive();
+     *  mcastSocket.setTimeToLive(newttl);
+     *  mcastSocket.send(p);
+     *  mcastSocket.setTimeToLive(ttl);
+     *  ......
+     *
+     * @see DatagramSocket#send
+     * @see DatagramSocket#receive
+     * @see SecurityManager#checkMulticast(java.net.InetAddress, byte)
+     * @see SecurityManager#checkConnect
+     */
+    @Deprecated
+    public void send(DatagramPacket p, byte ttl)
+        throws IOException {
+            if (isClosed())
+                throw new SocketException("Socket is closed");
+            checkAddress(p.getAddress(), "send");
+            synchronized(ttlLock) {
+                synchronized(p) {
+                    if (connectState == ST_NOT_CONNECTED) {
+                        // Security manager makes sure that the multicast address
+                        // is allowed one and that the ttl used is less
+                        // than the allowed maxttl.
+                        SecurityManager security = System.getSecurityManager();
+                        if (security != null) {
+                            if (p.getAddress().isMulticastAddress()) {
+                                security.checkMulticast(p.getAddress(), ttl);
+                            } else {
+                                security.checkConnect(p.getAddress().getHostAddress(),
+                                                      p.getPort());
+                            }
+                        }
+                    } else {
+                        // we're connected
+                        InetAddress packetAddress = null;
+                        packetAddress = p.getAddress();
+                        if (packetAddress == null) {
+                            p.setAddress(connectedAddress);
+                            p.setPort(connectedPort);
+                        } else if ((!packetAddress.equals(connectedAddress)) ||
+                                   p.getPort() != connectedPort) {
+                            throw new SecurityException("connected address and packet address" +
+                                                        " differ");
+                        }
+                    }
+                    byte dttl = getTTL();
+                    try {
+                        if (ttl != dttl) {
+                            // set the ttl
+                            getImpl().setTTL(ttl);
+                        }
+                        // call the datagram method to send
+                        getImpl().send(p);
+                    } finally {
+                        // set it back to default
+                        if (ttl != dttl) {
+                            getImpl().setTTL(dttl);
+                        }
+                    }
+                } // synch p
+            }  //synch ttl
+    } //method
+}
diff --git a/java/net/NetPermission.java b/java/net/NetPermission.java
new file mode 100644
index 0000000..b5a0eab
--- /dev/null
+++ b/java/net/NetPermission.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.security.*;
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class NetPermission extends BasicPermission {
+
+    public NetPermission(String name)
+    {
+        super("");
+    }
+
+    public NetPermission(String name, String actions)
+    {
+        super("", "");
+    }
+}
diff --git a/java/net/NetworkInterface.java b/java/net/NetworkInterface.java
new file mode 100644
index 0000000..a30b6bf
--- /dev/null
+++ b/java/net/NetworkInterface.java
@@ -0,0 +1,748 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import android.system.ErrnoException;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+
+import android.system.StructIfaddrs;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+import sun.security.action.*;
+import java.security.AccessController;
+
+import static android.system.OsConstants.*;
+
+// Android-note: NetworkInterface has been rewritten to avoid native code.
+// Fix upstream bug not returning link-down interfaces. http://b/26238832
+// Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+/**
+ * This class represents a Network Interface made up of a name,
+ * and a list of IP addresses assigned to this interface.
+ * It is used to identify the local interface on which a multicast group
+ * is joined.
+ *
+ * Interfaces are normally known by names such as "le0".
+ * <p>
+ * <a name="access-restrictions"></a>Note that information about
+ * {@link NetworkInterface}s may be restricted. For example, non-system apps
+ * with {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R} will only
+ * have access to information about {@link NetworkInterface}s that are
+ * associated with an {@link InetAddress}.
+ *
+ * @since 1.4
+ */
+public final class NetworkInterface {
+    private String name;
+    private String displayName;
+    private int index;
+    private InetAddress addrs[];
+    private InterfaceAddress bindings[];
+    // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+    // private NetworkInterface childs[];
+    private List<NetworkInterface> childs;
+    private NetworkInterface parent = null;
+    private boolean virtual = false;
+    private static final NetworkInterface defaultInterface;
+    private static final int defaultIndex; /* index of defaultInterface */
+
+    // Android-changed: Fix upstream bug not returning link-down interfaces. http://b/26238832
+    private byte[] hardwareAddr;
+
+    static {
+        // Android-removed: Android doesn't need to call native init.
+        /*
+        AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    System.loadLibrary("net");
+                    return null;
+                }
+            });
+
+        init();
+        */
+        defaultInterface = DefaultInterface.getDefault();
+        if (defaultInterface != null) {
+            defaultIndex = defaultInterface.getIndex();
+        } else {
+            defaultIndex = 0;
+        }
+    }
+
+    /**
+     * Returns an NetworkInterface object with index set to 0 and name to null.
+     * Setting such an interface on a MulticastSocket will cause the
+     * kernel to choose one interface for sending multicast packets.
+     *
+     */
+    NetworkInterface() {
+    }
+
+    NetworkInterface(String name, int index, InetAddress[] addrs) {
+        this.name = name;
+        this.index = index;
+        this.addrs = addrs;
+    }
+
+    /**
+     * Get the name of this network interface.
+     *
+     * @return the name of this network interface
+     */
+    public String getName() {
+            return name;
+    }
+
+    /**
+     * Convenience method to return an Enumeration with all or a
+     * subset of the InetAddresses bound to this network interface.
+     * <p>
+     * If there is a security manager, its {@code checkConnect}
+     * method is called for each InetAddress. Only InetAddresses where
+     * the {@code checkConnect} doesn't throw a SecurityException
+     * will be returned in the Enumeration. However, if the caller has the
+     * {@link NetPermission}("getNetworkInformation") permission, then all
+     * InetAddresses are returned.
+     * @return an Enumeration object with all or a subset of the InetAddresses
+     * bound to this network interface
+     */
+    public Enumeration<InetAddress> getInetAddresses() {
+
+        class checkedAddresses implements Enumeration<InetAddress> {
+
+            private int i=0, count=0;
+            private InetAddress local_addrs[];
+
+            checkedAddresses() {
+                local_addrs = new InetAddress[addrs.length];
+                boolean trusted = true;
+
+                SecurityManager sec = System.getSecurityManager();
+                if (sec != null) {
+                    try {
+                        sec.checkPermission(new NetPermission("getNetworkInformation"));
+                    } catch (SecurityException e) {
+                        trusted = false;
+                    }
+                }
+                for (int j=0; j<addrs.length; j++) {
+                    try {
+                        if (sec != null && !trusted) {
+                            sec.checkConnect(addrs[j].getHostAddress(), -1);
+                        }
+                        local_addrs[count++] = addrs[j];
+                    } catch (SecurityException e) { }
+                }
+
+            }
+
+            public InetAddress nextElement() {
+                if (i < count) {
+                    return local_addrs[i++];
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+
+            public boolean hasMoreElements() {
+                return (i < count);
+            }
+        }
+        return new checkedAddresses();
+
+    }
+
+    /**
+     * Get a List of all or a subset of the {@code InterfaceAddresses}
+     * of this network interface.
+     * <p>
+     * If there is a security manager, its {@code checkConnect}
+     * method is called with the InetAddress for each InterfaceAddress.
+     * Only InterfaceAddresses where the {@code checkConnect} doesn't throw
+     * a SecurityException will be returned in the List.
+     *
+     * @return a {@code List} object with all or a subset of the
+     *         InterfaceAddresss of this network interface
+     * @since 1.6
+     */
+    public java.util.List<InterfaceAddress> getInterfaceAddresses() {
+        java.util.List<InterfaceAddress> lst = new java.util.ArrayList<InterfaceAddress>(1);
+        // BEGIN Android-changed: Cherry-picked upstream OpenJDK9 change rev 59a110a38cea
+        // http://b/30628919
+        if (bindings != null) {
+            SecurityManager sec = System.getSecurityManager();
+            for (int j=0; j<bindings.length; j++) {
+                try {
+                    if (sec != null) {
+                        sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1);
+                    }
+                    lst.add(bindings[j]);
+                } catch (SecurityException e) { }
+            }
+        }
+        // END Android-changed: Cherry-picked upstream OpenJDK9 change rev 59a110a38cea
+        return lst;
+    }
+
+    /**
+     * Get an Enumeration with all the subinterfaces (also known as virtual
+     * interfaces) attached to this network interface.
+     * <p>
+     * For instance eth0:1 will be a subinterface to eth0.
+     *
+     * @return an Enumeration object with all of the subinterfaces
+     * of this network interface
+     * @since 1.6
+     */
+    public Enumeration<NetworkInterface> getSubInterfaces() {
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        return Collections.enumeration(childs);
+    }
+
+    /**
+     * Returns the parent NetworkInterface of this interface if this is
+     * a subinterface, or {@code null} if it is a physical
+     * (non virtual) interface or has no parent.
+     *
+     * @return The {@code NetworkInterface} this interface is attached to.
+     * @since 1.6
+     */
+    public NetworkInterface getParent() {
+        return parent;
+    }
+
+    /**
+     * Returns the index of this network interface. The index is an integer greater
+     * or equal to zero, or {@code -1} for unknown. This is a system specific value
+     * and interfaces with the same name can have different indexes on different
+     * machines.
+     *
+     * @return the index of this network interface or {@code -1} if the index is
+     *         unknown
+     * @see #getByIndex(int)
+     * @since 1.7
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * Get the display name of this network interface.
+     * A display name is a human readable String describing the network
+     * device.
+     *
+     * @return a non-empty string representing the display name of this network
+     *         interface, or null if no display name is available.
+     */
+    public String getDisplayName() {
+        /* strict TCK conformance */
+        return "".equals(displayName) ? null : displayName;
+    }
+
+    // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+    /**
+     * Searches for the network interface with the specified name.
+     *
+     * @param   name
+     *          The name of the network interface.
+     *
+     * @return  A {@code NetworkInterface} with the specified name,
+     *          or {@code null} if the network interface with the specified
+     *          name does not exist or <a href="#access-restrictions">can't be
+     *          accessed</a>.
+     *
+     * @throws  SocketException
+     *          If an I/O error occurs.
+     *
+     * @throws  NullPointerException
+     *          If the specified name is {@code null}.
+     */
+    public static NetworkInterface getByName(String name) throws SocketException {
+        if (name == null)
+            throw new NullPointerException();
+
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        NetworkInterface[] nis = getAll();
+        for (NetworkInterface ni : nis) {
+            if (ni.getName().equals(name)) {
+                return ni;
+            }
+        }
+        return null;
+    }
+
+    // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+    /**
+     * Get a network interface given its index.
+     *
+     * @param index an integer, the index of the interface
+     * @return the NetworkInterface obtained from its index, or {@code null} if
+     *         an interface with the specified index does not exist or
+     *         <a href="#access-restrictions">can't be accessed</a>.
+     * @throws  SocketException  if an I/O error occurs.
+     * @throws  IllegalArgumentException if index has a negative value
+     * @see #getIndex()
+     * @since 1.7
+     */
+    public static NetworkInterface getByIndex(int index) throws SocketException {
+        if (index < 0)
+            throw new IllegalArgumentException("Interface index can't be negative");
+
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        NetworkInterface[] nis = getAll();
+        for (NetworkInterface ni : nis) {
+            if (ni.getIndex() == index) {
+                return ni;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Convenience method to search for a network interface that
+     * has the specified Internet Protocol (IP) address bound to
+     * it.
+     * <p>
+     * If the specified IP address is bound to multiple network
+     * interfaces it is not defined which network interface is
+     * returned.
+     *
+     * @param   addr
+     *          The {@code InetAddress} to search with.
+     *
+     * @return  A {@code NetworkInterface}
+     *          or {@code null} if there is no network interface
+     *          with the specified IP address.
+     *
+     * @throws  SocketException
+     *          If an I/O error occurs.
+     *
+     * @throws  NullPointerException
+     *          If the specified address is {@code null}.
+     */
+    public static NetworkInterface getByInetAddress(InetAddress addr) throws SocketException {
+        if (addr == null) {
+            throw new NullPointerException();
+        }
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
+            throw new IllegalArgumentException ("invalid address type");
+        }
+
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        NetworkInterface[] nis = getAll();
+        for (NetworkInterface ni : nis) {
+            for (InetAddress inetAddress : Collections.list(ni.getInetAddresses())) {
+                if (inetAddress.equals(addr)) {
+                    return ni;
+                }
+            }
+        }
+        return null;
+    }
+
+    // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+    /**
+     * Returns all the interfaces on this machine. The {@code Enumeration}
+     * contains at least one element, possibly representing a loopback
+     * interface that only supports communication between entities on
+     * this machine.
+     *
+     * NOTE: can use getNetworkInterfaces()+getInetAddresses()
+     *       to obtain all IP addresses for this node
+     * <p>
+     * For non-system apps with
+     * {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R}, this
+     * method will only return information for {@link NetworkInterface}s that
+     * are associated with an {@link InetAddress}.
+     *
+     * @return an Enumeration of NetworkInterfaces found on this machine
+     *         that <a href="#access-restrictions">are accessible</a>.
+     * @exception  SocketException  if an I/O error occurs.
+     */
+
+    public static Enumeration<NetworkInterface> getNetworkInterfaces()
+        throws SocketException {
+        final NetworkInterface[] netifs = getAll();
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        // // specified to return null if no network interfaces
+        // if (netifs == null)
+        if (netifs.length == 0)
+            return null;
+
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        /*
+        return new Enumeration<NetworkInterface>() {
+            private int i = 0;
+            public NetworkInterface nextElement() {
+                if (netifs != null && i < netifs.length) {
+                    NetworkInterface netif = netifs[i++];
+                    return netif;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+
+            public boolean hasMoreElements() {
+                return (netifs != null && i < netifs.length);
+            }
+        };
+        */
+        return Collections.enumeration(Arrays.asList(netifs));
+    }
+
+    // BEGIN Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+    // private native static NetworkInterface[] getAll()
+    //    throws SocketException;
+    private static NetworkInterface[] getAll() throws SocketException {
+        // Group Ifaddrs by interface name.
+        Map<String, List<StructIfaddrs>> inetMap = new HashMap<>();
+
+        StructIfaddrs[] ifaddrs;
+        try {
+            ifaddrs = Libcore.os.getifaddrs();
+        } catch (ErrnoException e) {
+            throw e.rethrowAsSocketException();
+        }
+
+        for (StructIfaddrs ifa : ifaddrs) {
+            String name = ifa.ifa_name;
+
+            List<StructIfaddrs> ifas;
+            if ((ifas = inetMap.get(name)) == null) {
+                ifas = new ArrayList<>();
+                inetMap.put(name, ifas);
+            }
+
+            ifas.add(ifa);
+        }
+
+        // Populate NetworkInterface instances.
+        Map<String, NetworkInterface> nis = new HashMap<>(inetMap.size());
+        for (Map.Entry<String, List<StructIfaddrs>> e : inetMap.entrySet()) {
+            String name = e.getKey();
+            int index = Libcore.os.if_nametoindex(e.getKey());
+            if (index == 0) {
+                // This interface has gone away between getifaddrs and if_nametoindex
+                continue;
+            }
+
+            NetworkInterface ni = new NetworkInterface(name, index, null);
+            ni.displayName = name;
+
+            List<InetAddress> addrs = new ArrayList<>();
+            List<InterfaceAddress> binds = new ArrayList<>();
+
+            for (StructIfaddrs ifa : e.getValue()) {
+                if (ifa.ifa_addr != null) {
+                    addrs.add(ifa.ifa_addr);
+                    binds.add(new InterfaceAddress(ifa.ifa_addr, (Inet4Address) ifa.ifa_broadaddr,
+                                                   ifa.ifa_netmask));
+                }
+
+                if (ifa.hwaddr != null) {
+                    ni.hardwareAddr = ifa.hwaddr;
+                }
+            }
+
+            ni.addrs = addrs.toArray(new InetAddress[addrs.size()]);
+            ni.bindings = binds.toArray(new InterfaceAddress[binds.size()]);
+            ni.childs = new ArrayList<>(0);
+            nis.put(name, ni);
+        }
+
+        // Populate childs/parent.
+        for (Map.Entry<String, NetworkInterface> e : nis.entrySet()) {
+            NetworkInterface ni = e.getValue();
+            String niName = ni.getName();
+            int colonIdx = niName.indexOf(':');
+            if (colonIdx != -1) {
+                // This is a virtual interface.
+                String parentName = niName.substring(0, colonIdx);
+                NetworkInterface parent = nis.get(parentName);
+
+                ni.virtual = true;
+                ni.parent = parent;
+                parent.childs.add(ni);
+            }
+        }
+
+        return nis.values().toArray(new NetworkInterface[nis.size()]);
+    }
+    // END Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+
+    /**
+     * Returns whether a network interface is up and running.
+     *
+     * @return  {@code true} if the interface is up and running.
+     * @exception       SocketException if an I/O error occurs.
+     * @since 1.6
+     */
+
+    public boolean isUp() throws SocketException {
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        final int mask = IFF_UP | IFF_RUNNING;
+        return (getFlags() & mask) == mask;
+    }
+
+    /**
+     * Returns whether a network interface is a loopback interface.
+     *
+     * @return  {@code true} if the interface is a loopback interface.
+     * @exception       SocketException if an I/O error occurs.
+     * @since 1.6
+     */
+
+    public boolean isLoopback() throws SocketException {
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        return (getFlags() & IFF_LOOPBACK) != 0;
+    }
+
+    /**
+     * Returns whether a network interface is a point to point interface.
+     * A typical point to point interface would be a PPP connection through
+     * a modem.
+     *
+     * @return  {@code true} if the interface is a point to point
+     *          interface.
+     * @exception       SocketException if an I/O error occurs.
+     * @since 1.6
+     */
+
+    public boolean isPointToPoint() throws SocketException {
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        return (getFlags() & IFF_POINTOPOINT) != 0;
+    }
+
+    /**
+     * Returns whether a network interface supports multicasting or not.
+     *
+     * @return  {@code true} if the interface supports Multicasting.
+     * @exception       SocketException if an I/O error occurs.
+     * @since 1.6
+     */
+
+    public boolean supportsMulticast() throws SocketException {
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        return (getFlags() & IFF_MULTICAST) != 0;
+    }
+
+    // Android-added: Document restrictions for targetSdkVersion >= R. http://b/141455849
+    /**
+     * Returns the hardware address (usually MAC) of the interface if it
+     * has one and if it can be accessed given the current privileges.
+     * If a security manager is set, then the caller must have
+     * the permission {@link NetPermission}("getNetworkInformation").
+     *
+     * @return  a byte array containing the address, or {@code null} if
+     *          the address doesn't exist, is not accessible or a security
+     *          manager is set and the caller does not have the permission
+     *          NetPermission("getNetworkInformation"). For example, this
+     *          method will generally return {@code null} when called by
+     *          non-system apps having
+     *          {@code targetSdkVersion >= android.os.Build.VERSION_CODES.R}.
+     *
+     * @exception       SocketException if an I/O error occurs.
+     * @since 1.6
+     */
+    public byte[] getHardwareAddress() throws SocketException {
+        // BEGIN Android-changed: Fix upstream not returning link-down interfaces. http://b/26238832
+        /*
+        for (InetAddress addr : addrs) {
+            if (addr instanceof Inet4Address) {
+                return getMacAddr0(((Inet4Address)addr).getAddress(), name, index);
+            }
+        }
+        return getMacAddr0(null, name, index);
+         */
+        NetworkInterface ni = getByName(name);
+        if (ni == null) {
+            throw new SocketException("NetworkInterface doesn't exist anymore");
+        }
+        return ni.hardwareAddr;
+        // END Android-changed: Fix upstream not returning link-down interfaces. http://b/26238832
+    }
+
+    /**
+     * Returns the Maximum Transmission Unit (MTU) of this interface.
+     *
+     * @return the value of the MTU for that interface.
+     * @exception       SocketException if an I/O error occurs.
+     * @since 1.6
+     */
+    public int getMTU() throws SocketException {
+        // Android-changed: Rewrote NetworkInterface on top of Libcore.io.
+        // return getMTU0(name, index);
+        FileDescriptor fd = null;
+        try {
+            fd = Libcore.rawOs.socket(AF_INET, SOCK_DGRAM, 0);
+            return Libcore.rawOs.ioctlMTU(fd, name);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsSocketException();
+        } catch (Exception ex) {
+            throw new SocketException(ex);
+        } finally {
+            IoUtils.closeQuietly(fd);
+        }
+    }
+
+    /**
+     * Returns whether this interface is a virtual interface (also called
+     * subinterface).
+     * Virtual interfaces are, on some systems, interfaces created as a child
+     * of a physical interface and given different settings (like address or
+     * MTU). Usually the name of the interface will the name of the parent
+     * followed by a colon (:) and a number identifying the child since there
+     * can be several virtual interfaces attached to a single physical
+     * interface.
+     *
+     * @return {@code true} if this interface is a virtual interface.
+     * @since 1.6
+     */
+    public boolean isVirtual() {
+        return virtual;
+    }
+
+    // BEGIN Android-removed: Rewrote NetworkInterface on top of Libcore.io.
+    /*
+    private native static boolean isUp0(String name, int ind) throws SocketException;
+    private native static boolean isLoopback0(String name, int ind) throws SocketException;
+    private native static boolean supportsMulticast0(String name, int ind) throws SocketException;
+    private native static boolean isP2P0(String name, int ind) throws SocketException;
+    private native static byte[] getMacAddr0(byte[] inAddr, String name, int ind) throws SocketException;
+    private native static int getMTU0(String name, int ind) throws SocketException;
+    */
+    // END Android-removed: Rewrote NetworkInterface on top of Libcore.io.
+
+    // BEGIN Android-added: Rewrote NetworkInterface on top of Libcore.io.
+    private int getFlags() throws SocketException {
+        FileDescriptor fd = null;
+        try {
+            fd = Libcore.rawOs.socket(AF_INET, SOCK_DGRAM, 0);
+            return Libcore.rawOs.ioctlFlags(fd, name);
+        } catch (ErrnoException e) {
+            throw e.rethrowAsSocketException();
+        } catch (Exception ex) {
+            throw new SocketException(ex);
+        } finally {
+            IoUtils.closeQuietly(fd);
+        }
+    }
+    // END Android-added: Rewrote NetworkInterface on top of Libcore.io.
+
+    /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is
+     * not {@code null} and it represents the same NetworkInterface
+     * as this object.
+     * <p>
+     * Two instances of {@code NetworkInterface} represent the same
+     * NetworkInterface if both name and addrs are the same for both.
+     *
+     * @param   obj   the object to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see     java.net.InetAddress#getAddress()
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof NetworkInterface)) {
+            return false;
+        }
+        NetworkInterface that = (NetworkInterface)obj;
+        if (this.name != null ) {
+            if (!this.name.equals(that.name)) {
+                return false;
+            }
+        } else {
+            if (that.name != null) {
+                return false;
+            }
+        }
+
+        if (this.addrs == null) {
+            return that.addrs == null;
+        } else if (that.addrs == null) {
+            return false;
+        }
+
+        /* Both addrs not null. Compare number of addresses */
+
+        if (this.addrs.length != that.addrs.length) {
+            return false;
+        }
+
+        InetAddress[] thatAddrs = that.addrs;
+        int count = thatAddrs.length;
+
+        for (int i=0; i<count; i++) {
+            boolean found = false;
+            for (int j=0; j<count; j++) {
+                if (addrs[i].equals(thatAddrs[j])) {
+                    found = true;
+                    break;
+                }
+            }
+            if (!found) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public int hashCode() {
+        return name == null? 0: name.hashCode();
+    }
+
+    public String toString() {
+        String result = "name:";
+        result += name == null? "null": name;
+        if (displayName != null) {
+            result += " (" + displayName + ")";
+        }
+        return result;
+    }
+
+    // Android-removed: Android doesn't need to call native init.
+    // private static native void init();
+
+    /**
+     * Returns the default network interface of this system
+     *
+     * @return the default interface
+     */
+    static NetworkInterface getDefault() {
+        return defaultInterface;
+    }
+}
diff --git a/java/net/NoRouteToHostException.java b/java/net/NoRouteToHostException.java
new file mode 100644
index 0000000..76f0814
--- /dev/null
+++ b/java/net/NoRouteToHostException.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Signals that an error occurred while attempting to connect a
+ * socket to a remote address and port.  Typically, the remote
+ * host cannot be reached because of an intervening firewall, or
+ * if an intermediate router is down.
+ *
+ * @since   JDK1.1
+ */
+public class NoRouteToHostException extends SocketException {
+    private static final long serialVersionUID = -1897550894873493790L;
+
+    /**
+     * Constructs a new NoRouteToHostException with the specified detail
+     * message as to why the remote host cannot be reached.
+     * A detail message is a String that gives a specific
+     * description of this error.
+     * @param msg the detail message
+     */
+    public NoRouteToHostException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Construct a new NoRouteToHostException with no detailed message.
+     */
+    public NoRouteToHostException() {}
+}
diff --git a/java/net/PasswordAuthentication.java b/java/net/PasswordAuthentication.java
new file mode 100644
index 0000000..5529568
--- /dev/null
+++ b/java/net/PasswordAuthentication.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+
+/**
+ * The class PasswordAuthentication is a data holder that is used by
+ * Authenticator.  It is simply a repository for a user name and a password.
+ *
+ * @see java.net.Authenticator
+ * @see java.net.Authenticator#getPasswordAuthentication()
+ *
+ * @author  Bill Foote
+ * @since   1.2
+ */
+
+public final class PasswordAuthentication {
+
+    private String userName;
+    private char[] password;
+
+    /**
+     * Creates a new {@code PasswordAuthentication} object from the given
+     * user name and password.
+     *
+     * <p> Note that the given user password is cloned before it is stored in
+     * the new {@code PasswordAuthentication} object.
+     *
+     * @param userName the user name
+     * @param password the user's password
+     */
+    public PasswordAuthentication(String userName, char[] password) {
+        this.userName = userName;
+        this.password = password.clone();
+    }
+
+    /**
+     * Returns the user name.
+     *
+     * @return the user name
+     */
+    public String getUserName() {
+        return userName;
+    }
+
+    /**
+     * Returns the user password.
+     *
+     * <p> Note that this method returns a reference to the password. It is
+     * the caller's responsibility to zero out the password information after
+     * it is no longer needed.
+     *
+     * @return the password
+     */
+    public char[] getPassword() {
+        return password;
+    }
+}
diff --git a/java/net/PlainDatagramSocketImpl.java b/java/net/PlainDatagramSocketImpl.java
new file mode 100644
index 0000000..d4b1f2c
--- /dev/null
+++ b/java/net/PlainDatagramSocketImpl.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2007,2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+import android.system.ErrnoException;
+import android.system.StructGroupReq;
+
+import java.io.IOException;
+import libcore.io.IoBridge;
+import libcore.io.Libcore;
+import libcore.util.EmptyArray;
+
+import jdk.net.*;
+
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNSPEC;
+import static android.system.OsConstants.IPPROTO_IP;
+import static android.system.OsConstants.IP_MULTICAST_ALL;
+import static android.system.OsConstants.MSG_PEEK;
+import static android.system.OsConstants.POLLERR;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static libcore.io.IoBridge.JAVA_IP_MULTICAST_TTL;
+import static libcore.io.IoBridge.JAVA_MCAST_JOIN_GROUP;
+import static libcore.io.IoBridge.JAVA_MCAST_LEAVE_GROUP;
+import static sun.net.ExtendedOptionsImpl.*;
+
+/*
+ * On Unix systems we simply delegate to native methods.
+ *
+ * @author Chris Hegarty
+ */
+
+class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
+{
+    // Android-removed: init method has been removed
+    // static {
+    //     init();
+    // }
+
+    protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
+        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+            super.setOption(name, value);
+        } else {
+            if (isClosed()) {
+                throw new SocketException("Socket closed");
+            }
+            checkSetOptionPermission(name);
+            checkValueType(value, SocketFlow.class);
+            setFlowOption(getFileDescriptor(), (SocketFlow)value);
+        }
+    }
+
+    protected <T> T getOption(SocketOption<T> name) throws IOException {
+        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+            return super.getOption(name);
+        }
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+        checkGetOptionPermission(name);
+        SocketFlow flow = SocketFlow.create();
+        getFlowOption(getFileDescriptor(), flow);
+        return (T)flow;
+    }
+
+    protected void socketSetOption(int opt, Object val) throws SocketException {
+        try {
+            socketSetOption0(opt, val);
+        } catch (SocketException se) {
+            if (!connected)
+                throw se;
+        }
+    }
+
+    // BEGIN Android-changed: Rewrote on top of Libcore.io.
+    protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.bind(fd, laddr, lport);
+
+        if (lport == 0) {
+            // Now that we're a connected socket, let's extract the port number that the system
+            // chose for us and store it in the Socket object.
+            localPort = IoBridge.getLocalInetSocketAddress(fd).getPort();
+        } else {
+            localPort = lport;
+        }
+    }
+
+    protected void send(DatagramPacket p) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+        if (p.getData() == null || p.getAddress() == null) {
+            throw new NullPointerException("null buffer || null address");
+        }
+
+        int port = connected ? 0 : p.getPort();
+        InetAddress address = connected ? null : p.getAddress();
+        IoBridge.sendto(fd, p.getData(), p.getOffset(), p.getLength(), 0, address, port);
+    }
+
+    protected synchronized int peek(InetAddress i) throws IOException {
+        DatagramPacket p = new DatagramPacket(EmptyArray.BYTE, 0);
+        doRecv(p, MSG_PEEK);
+        i.holder().address = p.getAddress().holder().address;
+        return p.getPort();
+    }
+
+    protected synchronized int peekData(DatagramPacket p) throws IOException {
+        doRecv(p, MSG_PEEK);
+        return p.getPort();
+    }
+
+    protected synchronized void receive0(DatagramPacket p) throws IOException {
+        doRecv(p, 0);
+    }
+
+    private void doRecv(DatagramPacket p, int flags) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        if (timeout != 0) {
+            IoBridge.poll(fd, POLLIN | POLLERR, timeout);
+        }
+
+        IoBridge.recvfrom(false, fd, p.getData(), p.getOffset(), p.bufLength, flags, p,
+                connected);
+    }
+
+    protected void setTimeToLive(int ttl) throws IOException {
+        IoBridge.setSocketOption(fd, JAVA_IP_MULTICAST_TTL, ttl);
+    }
+
+    protected int getTimeToLive() throws IOException {
+        return (Integer) IoBridge.getSocketOption(fd, JAVA_IP_MULTICAST_TTL);
+    }
+
+    protected void setTTL(byte ttl) throws IOException {
+        setTimeToLive((int) ttl & 0xff);
+    }
+
+    protected byte getTTL() throws IOException {
+        return (byte) getTimeToLive();
+    }
+
+    private static StructGroupReq makeGroupReq(InetAddress gr_group,
+            NetworkInterface networkInterface) {
+        int gr_interface = (networkInterface != null) ? networkInterface.getIndex() : 0;
+        return new StructGroupReq(gr_interface, gr_group);
+    }
+
+    protected void join(InetAddress inetaddr, NetworkInterface netIf) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.setSocketOption(fd, JAVA_MCAST_JOIN_GROUP, makeGroupReq(inetaddr, netIf));
+    }
+
+    protected void leave(InetAddress inetaddr, NetworkInterface netIf)
+        throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.setSocketOption(fd, JAVA_MCAST_LEAVE_GROUP, makeGroupReq(inetaddr, netIf));
+    }
+
+    protected void datagramSocketCreate() throws SocketException {
+        fd = IoBridge.socket(AF_INET6, SOCK_DGRAM, 0);
+        IoBridge.setSocketOption(fd, SO_BROADCAST, true);
+
+        try {
+            Libcore.os.setsockoptInt(fd, IPPROTO_IP, IP_MULTICAST_ALL, 0);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsSocketException();
+        }
+    }
+
+    protected void datagramSocketClose() {
+        try {
+            IoBridge.closeAndSignalBlockedThreads(fd);
+        } catch (IOException ignored) { }
+    }
+
+    protected void socketSetOption0(int opt, Object val) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.setSocketOption(fd, opt, val);
+    }
+
+    protected Object socketGetOption(int opt) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        return IoBridge.getSocketOption(fd, opt);
+    }
+
+    protected void connect0(InetAddress address, int port) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.connect(fd, address, port);
+    }
+
+    protected void disconnect0(int family) {
+        if (isClosed()) {
+            return;
+        }
+
+        InetAddress inetAddressUnspec = new InetAddress();
+        inetAddressUnspec.holder().family = AF_UNSPEC;
+
+        try {
+            IoBridge.connect(fd, inetAddressUnspec, 0);
+        } catch (SocketException ignored) { }
+    }
+    // END Android-changed: Rewrote on top of Libcore.io.
+
+    // Android-removed: JNI has been removed
+    // /**
+    //  * Perform class load-time initializations.
+    //  */
+    // private native static void init();
+}
diff --git a/java/net/PlainSocketImpl.java b/java/net/PlainSocketImpl.java
new file mode 100644
index 0000000..89ee53e
--- /dev/null
+++ b/java/net/PlainSocketImpl.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+import android.system.ErrnoException;
+
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import libcore.io.AsynchronousCloseMonitor;
+import libcore.io.IoBridge;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+
+import jdk.net.*;
+
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.EAGAIN;
+import static android.system.OsConstants.EBADF;
+import static android.system.OsConstants.EINVAL;
+import static android.system.OsConstants.MSG_OOB;
+import static android.system.OsConstants.POLLERR;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.SHUT_RDWR;
+import static sun.net.ExtendedOptionsImpl.*;
+
+// Android-changed: Rewritten to use android.system POSIX calls and assume AF_INET6.
+/*
+ * On Unix systems we simply delegate to native methods.
+ *
+ * @author Chris Hegarty
+ */
+
+class PlainSocketImpl extends AbstractPlainSocketImpl
+{
+    // Android-removed: Android doesn't need to call native initProto.
+    /*
+    static {
+        initProto();
+    }
+    */
+
+    /**
+     * Constructs an empty instance.
+     */
+    PlainSocketImpl() {
+        // Android-changed: Let PlainSocketImpl construct its own FileDescriptor.
+        this.fd = new FileDescriptor();
+    }
+
+    /**
+     * Constructs an instance with the given file descriptor.
+     */
+    // Android-removed: Let PlainSocketImpl construct its own FileDescriptor.
+    /*
+    PlainSocketImpl(FileDescriptor fd) {
+        this.fd = fd;
+    }
+    */
+
+    protected <T> void setOption(SocketOption<T> name, T value) throws IOException {
+        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+            super.setOption(name, value);
+        } else {
+            if (isClosedOrPending()) {
+                throw new SocketException("Socket closed");
+            }
+            checkSetOptionPermission(name);
+            checkValueType(value, SocketFlow.class);
+            setFlowOption(getFileDescriptor(), (SocketFlow)value);
+        }
+    }
+
+    protected <T> T getOption(SocketOption<T> name) throws IOException {
+        if (!name.equals(ExtendedSocketOptions.SO_FLOW_SLA)) {
+            return super.getOption(name);
+        }
+        if (isClosedOrPending()) {
+            throw new SocketException("Socket closed");
+        }
+        checkGetOptionPermission(name);
+        SocketFlow flow = SocketFlow.create();
+        getFlowOption(getFileDescriptor(), flow);
+        return (T)flow;
+    }
+
+    // BEGIN Android-changed: Rewrote on top of Libcore.io.
+    protected void socketSetOption(int opt, Object val) throws SocketException {
+        try {
+            socketSetOption0(opt, val);
+        } catch (SocketException se) {
+            if (socket == null || !socket.isConnected())
+                throw se;
+        }
+    }
+
+    void socketCreate(boolean isStream) throws IOException {
+        // The fd object must not change after calling bind, because we rely on this undocumented
+        // behaviour. See libcore.java.net.SocketTest#testFileDescriptorStaysSame.
+        fd.setInt$(IoBridge.socket(AF_INET6, isStream ? SOCK_STREAM : SOCK_DGRAM, 0).getInt$());
+        IoUtils.setFdOwner(fd, this);
+
+        if (serverSocket != null) {
+            IoUtils.setBlocking(fd, false);
+            IoBridge.setSocketOption(fd, SO_REUSEADDR, true);
+        }
+    }
+
+    void socketConnect(InetAddress address, int port, int timeout) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.connect(fd, address, port, timeout);
+
+        this.address = address;
+        this.port = port;
+
+        if (localport == 0) {
+            // If socket is pending close, fd becomes an AF_UNIX socket and calling
+            // getLocalInetSocketAddress will fail.
+            // http://b/34645743
+            if (!isClosedOrPending()) {
+                localport = IoBridge.getLocalInetSocketAddress(fd).getPort();
+            }
+        }
+    }
+
+    void socketBind(InetAddress address, int port) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        IoBridge.bind(fd, address, port);
+
+        this.address = address;
+        if (port == 0) {
+            // Now that we're a connected socket, let's extract the port number that the system
+            // chose for us and store it in the Socket object.
+            localport = IoBridge.getLocalInetSocketAddress(fd).getPort();
+        } else {
+            localport = port;
+        }
+    }
+
+    void socketListen(int count) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        try {
+            Libcore.os.listen(fd, count);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsSocketException();
+        }
+    }
+
+    void socketAccept(SocketImpl s) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        // poll() with a timeout of 0 means "poll for zero millis", but a Socket timeout == 0 means
+        // "wait forever". When timeout == 0 we pass -1 to poll.
+        if (timeout <= 0) {
+            IoBridge.poll(fd, POLLIN | POLLERR, -1);
+        } else {
+            IoBridge.poll(fd, POLLIN | POLLERR, timeout);
+        }
+
+        InetSocketAddress peerAddress = new InetSocketAddress();
+        try {
+            FileDescriptor newfd = Libcore.os.accept(fd, peerAddress);
+
+            s.fd.setInt$(newfd.getInt$());
+            IoUtils.setFdOwner(s.fd, s);
+            s.address = peerAddress.getAddress();
+            s.port = peerAddress.getPort();
+        } catch (ErrnoException errnoException) {
+            if (errnoException.errno == EAGAIN) {
+                SocketTimeoutException e = new SocketTimeoutException();
+                e.initCause(errnoException);
+                throw e;
+            } else if (errnoException.errno == EINVAL || errnoException.errno == EBADF) {
+                throw new SocketException("Socket closed");
+            }
+            errnoException.rethrowAsSocketException();
+        }
+
+        s.localport = IoBridge.getLocalInetSocketAddress(s.fd).getPort();
+    }
+
+    int socketAvailable() throws IOException {
+        return IoBridge.available(fd);
+    }
+
+    void socketClose0(boolean useDeferredClose) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("socket already closed");
+        }
+
+        FileDescriptor markerFD = null;
+        if (useDeferredClose) {
+            markerFD = getMarkerFD();
+        }
+
+        if (useDeferredClose && markerFD != null) {
+            try {
+                Libcore.os.dup2(markerFD, fd.getInt$());
+                Libcore.os.close(markerFD);
+
+                // This effectively closes the socket, needs to signal threads that blocks on this
+                // file descriptor.
+                AsynchronousCloseMonitor.signalBlockedThreads(fd);
+            } catch (ErrnoException errnoException) {
+                // close should not throw
+            }
+        } else {
+            // If requested or a markerFD cannot be created, a non-deferred close is performed
+            // instead.
+            IoBridge.closeAndSignalBlockedThreads(fd);
+        }
+    }
+
+    /*
+     * Create the marker file descriptor by establishing a loopback connection which we shutdown but
+     * do not close the fd. The result is an fd that can be used for read/write.
+     *
+     * The purpose is to keep hold of the raw fd handle until we are sure it is not used in any
+     * thread. Otherwise if we close the file descriptor directly, the system might reuse the raw fd
+     * number and threads holding old fd value might behave incorrectly.
+     */
+    private FileDescriptor getMarkerFD() throws SocketException {
+        FileDescriptor fd1 = new FileDescriptor();
+        FileDescriptor fd2 = new FileDescriptor();
+        try {
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd1, fd2);
+
+            // Shutdown fd1, any reads to this fd will get EOF; any writes will get an error.
+            Libcore.os.shutdown(fd1, SHUT_RDWR);
+            Libcore.os.close(fd2);
+        } catch (ErrnoException errnoException) {
+            // We might have reached the maximum file descriptor number and socketpair(2) would
+            // fail. In this case, return null and let caller to fall back to an alternative method
+            // that does not allocate more file descriptors.
+            return null;
+        }
+        return fd1;
+    }
+
+    void socketShutdown(int howto) throws IOException {
+        try {
+            Libcore.os.shutdown(fd, howto);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsIOException();
+        }
+    }
+
+    void socketSetOption0(int cmd, Object value) throws SocketException {
+        // OpenJDK does not set SO_TIMEOUT on Linux.
+        if (cmd == SO_TIMEOUT) {
+            return;
+        }
+
+        IoBridge.setSocketOption(fd, cmd, value);
+    }
+
+    Object socketGetOption(int opt) throws SocketException {
+        return IoBridge.getSocketOption(fd, opt);
+    }
+
+    void socketSendUrgentData(int data) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        try {
+            byte[] buffer = new byte[] { (byte) data };
+            Libcore.os.sendto(fd, buffer, 0, 1, MSG_OOB, null, 0);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsSocketException();
+        }
+    }
+    // END Android-changed: Rewrote on top of Libcore.io.
+
+}
diff --git a/java/net/PortUnreachableException.java b/java/net/PortUnreachableException.java
new file mode 100644
index 0000000..3e7558b
--- /dev/null
+++ b/java/net/PortUnreachableException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Signals that an ICMP Port Unreachable message has been
+ * received on a connected datagram.
+ *
+ * @since   1.4
+ */
+
+public class PortUnreachableException extends SocketException {
+    private static final long serialVersionUID = 8462541992376507323L;
+
+    /**
+     * Constructs a new {@code PortUnreachableException} with a
+     * detail message.
+     * @param msg the detail message
+     */
+    public PortUnreachableException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Construct a new {@code PortUnreachableException} with no
+     * detailed message.
+     */
+    public PortUnreachableException() {}
+
+    // Android-added: PortUnreachableException ctor used by IoBridge.
+    /** @hide */
+    public PortUnreachableException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+}
diff --git a/java/net/ProtocolException.java b/java/net/ProtocolException.java
new file mode 100644
index 0000000..5944282
--- /dev/null
+++ b/java/net/ProtocolException.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Thrown to indicate that there is an error in the underlying
+ * protocol, such as a TCP error.
+ *
+ * @author  Chris Warth
+ * @since   JDK1.0
+ */
+public
+class ProtocolException extends IOException {
+    private static final long serialVersionUID = -6098449442062388080L;
+
+    /**
+     * Constructs a new {@code ProtocolException} with the
+     * specified detail message.
+     *
+     * @param   host   the detail message.
+     */
+    public ProtocolException(String host) {
+        super(host);
+    }
+
+    /**
+     * Constructs a new {@code ProtocolException} with no detail message.
+     */
+    public ProtocolException() {
+    }
+}
diff --git a/java/net/ProtocolFamily.java b/java/net/ProtocolFamily.java
new file mode 100644
index 0000000..5d02326
--- /dev/null
+++ b/java/net/ProtocolFamily.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Represents a family of communication protocols.
+ *
+ * @since 1.7
+ */
+
+public interface ProtocolFamily {
+    /**
+     * Returns the name of the protocol family.
+     *
+     * @return the name of the protocol family
+     */
+    String name();
+}
diff --git a/java/net/Proxy.java b/java/net/Proxy.java
new file mode 100644
index 0000000..8ba020e
--- /dev/null
+++ b/java/net/Proxy.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This class represents a proxy setting, typically a type (http, socks) and
+ * a socket address.
+ * A {@code Proxy} is an immutable object.
+ *
+ * @see     java.net.ProxySelector
+ * @author Yingxian Wang
+ * @author Jean-Christophe Collet
+ * @since   1.5
+ */
+public class Proxy {
+
+    /**
+     * Represents the proxy type.
+     *
+     * @since 1.5
+     */
+    public enum Type {
+        /**
+         * Represents a direct connection, or the absence of a proxy.
+         */
+        DIRECT,
+        /**
+         * Represents proxy for high level protocols such as HTTP or FTP.
+         */
+        HTTP,
+        /**
+         * Represents a SOCKS (V4 or V5) proxy.
+         */
+        SOCKS
+    };
+
+    private Type type;
+    private SocketAddress sa;
+
+    /**
+     * A proxy setting that represents a {@code DIRECT} connection,
+     * basically telling the protocol handler not to use any proxying.
+     * Used, for instance, to create sockets bypassing any other global
+     * proxy settings (like SOCKS):
+     * <P>
+     * {@code Socket s = new Socket(Proxy.NO_PROXY);}
+     *
+     */
+    public final static Proxy NO_PROXY = new Proxy();
+
+    // Creates the proxy that represents a {@code DIRECT} connection.
+    private Proxy() {
+        type = Type.DIRECT;
+        sa = null;
+    }
+
+    /**
+     * Creates an entry representing a PROXY connection.
+     * Certain combinations are illegal. For instance, for types Http, and
+     * Socks, a SocketAddress <b>must</b> be provided.
+     * <P>
+     * Use the {@code Proxy.NO_PROXY} constant
+     * for representing a direct connection.
+     *
+     * @param type the {@code Type} of the proxy
+     * @param sa the {@code SocketAddress} for that proxy
+     * @throws IllegalArgumentException when the type and the address are
+     * incompatible
+     */
+    public Proxy(Type type, SocketAddress sa) {
+        if ((type == Type.DIRECT) || !(sa instanceof InetSocketAddress))
+            throw new IllegalArgumentException("type " + type + " is not compatible with address " + sa);
+        this.type = type;
+        this.sa = sa;
+    }
+
+    /**
+     * Returns the proxy type.
+     *
+     * @return a Type representing the proxy type
+     */
+    public Type type() {
+        return type;
+    }
+
+    /**
+     * Returns the socket address of the proxy, or
+     * {@code null} if its a direct connection.
+     *
+     * @return a {@code SocketAddress} representing the socket end
+     *         point of the proxy
+     */
+    public SocketAddress address() {
+        return sa;
+    }
+
+    /**
+     * Constructs a string representation of this Proxy.
+     * This String is constructed by calling toString() on its type
+     * and concatenating " @ " and the toString() result from its address
+     * if its type is not {@code DIRECT}.
+     *
+     * @return  a string representation of this object.
+     */
+    public String toString() {
+        if (type() == Type.DIRECT)
+            return "DIRECT";
+        return type() + " @ " + address();
+    }
+
+        /**
+     * Compares this object against the specified object.
+     * The result is {@code true} if and only if the argument is
+     * not {@code null} and it represents the same proxy as
+     * this object.
+     * <p>
+     * Two instances of {@code Proxy} represent the same
+     * address if both the SocketAddresses and type are equal.
+     *
+     * @param   obj   the object to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     * @see java.net.InetSocketAddress#equals(java.lang.Object)
+     */
+    public final boolean equals(Object obj) {
+        if (obj == null || !(obj instanceof Proxy))
+            return false;
+        Proxy p = (Proxy) obj;
+        if (p.type() == type()) {
+            if (address() == null) {
+                return (p.address() == null);
+            } else
+                return address().equals(p.address());
+        }
+        return false;
+    }
+
+    /**
+     * Returns a hashcode for this Proxy.
+     *
+     * @return  a hash code value for this Proxy.
+     */
+    public final int hashCode() {
+        if (address() == null)
+            return type().hashCode();
+        return type().hashCode() + address().hashCode();
+    }
+}
diff --git a/java/net/ProxySelector.java b/java/net/ProxySelector.java
new file mode 100644
index 0000000..d6bb536
--- /dev/null
+++ b/java/net/ProxySelector.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.util.List;
+import sun.security.util.SecurityConstants;
+
+/**
+ * Selects the proxy server to use, if any, when connecting to the
+ * network resource referenced by a URL. A proxy selector is a
+ * concrete sub-class of this class and is registered by invoking the
+ * {@link java.net.ProxySelector#setDefault setDefault} method. The
+ * currently registered proxy selector can be retrieved by calling
+ * {@link java.net.ProxySelector#getDefault getDefault} method.
+ *
+ * <p> When a proxy selector is registered, for instance, a subclass
+ * of URLConnection class should call the {@link #select select}
+ * method for each URL request so that the proxy selector can decide
+ * if a direct, or proxied connection should be used. The {@link
+ * #select select} method returns an iterator over a collection with
+ * the preferred connection approach.
+ *
+ * <p> If a connection cannot be established to a proxy (PROXY or
+ * SOCKS) servers then the caller should call the proxy selector's
+ * {@link #connectFailed connectFailed} method to notify the proxy
+ * selector that the proxy server is unavailable. </p>
+ *
+ * <P>The default proxy selector does enforce a
+ * <a href="doc-files/net-properties.html#Proxies">set of System Properties</a>
+ * related to proxy settings.</P>
+ *
+ * @author Yingxian Wang
+ * @author Jean-Christophe Collet
+ * @since 1.5
+ */
+public abstract class ProxySelector {
+    /**
+     * The system wide proxy selector that selects the proxy server to
+     * use, if any, when connecting to a remote object referenced by
+     * an URL.
+     *
+     * @see #setDefault(ProxySelector)
+     */
+    private static ProxySelector theProxySelector;
+
+    static {
+        try {
+            Class<?> c = Class.forName("sun.net.spi.DefaultProxySelector");
+            if (c != null && ProxySelector.class.isAssignableFrom(c)) {
+                theProxySelector = (ProxySelector) c.newInstance();
+            }
+        } catch (Exception e) {
+            theProxySelector = null;
+        }
+    }
+
+    /**
+     * Gets the system-wide proxy selector.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     * {@link NetPermission}{@code ("getProxySelector")}
+     * @see #setDefault(ProxySelector)
+     * @return the system-wide {@code ProxySelector}
+     * @since 1.5
+     */
+    public static ProxySelector getDefault() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.GET_PROXYSELECTOR_PERMISSION);
+        }
+        return theProxySelector;
+    }
+
+    /**
+     * Sets (or unsets) the system-wide proxy selector.
+     *
+     * Note: non-standard protocol handlers may ignore this setting.
+     *
+     * @param ps The HTTP proxy selector, or
+     *          {@code null} to unset the proxy selector.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     * {@link NetPermission}{@code ("setProxySelector")}
+     *
+     * @see #getDefault()
+     * @since 1.5
+     */
+    public static void setDefault(ProxySelector ps) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.SET_PROXYSELECTOR_PERMISSION);
+        }
+        theProxySelector = ps;
+    }
+
+    /**
+     * Selects all the applicable proxies based on the protocol to
+     * access the resource with and a destination address to access
+     * the resource at.
+     * The format of the URI is defined as follow:
+     * <UL>
+     * <LI>http URI for http connections</LI>
+     * <LI>https URI for https connections
+     * <LI>{@code socket://host:port}<br>
+     *     for tcp client sockets connections</LI>
+     * </UL>
+     *
+     * @param   uri
+     *          The URI that a connection is required to
+     *
+     * @return  a List of Proxies. Each element in the
+     *          the List is of type
+     *          {@link java.net.Proxy Proxy};
+     *          when no proxy is available, the list will
+     *          contain one element of type
+     *          {@link java.net.Proxy Proxy}
+     *          that represents a direct connection.
+     * @throws IllegalArgumentException if the argument is null
+     */
+    public abstract List<Proxy> select(URI uri);
+
+    /**
+     * Called to indicate that a connection could not be established
+     * to a proxy/socks server. An implementation of this method can
+     * temporarily remove the proxies or reorder the sequence of
+     * proxies returned by {@link #select(URI)}, using the address
+     * and the IOException caught when trying to connect.
+     *
+     * @param   uri
+     *          The URI that the proxy at sa failed to serve.
+     * @param   sa
+     *          The socket address of the proxy/SOCKS server
+     *
+     * @param   ioe
+     *          The I/O exception thrown when the connect failed.
+     * @throws IllegalArgumentException if either argument is null
+     */
+    public abstract void connectFailed(URI uri, SocketAddress sa, IOException ioe);
+}
diff --git a/java/net/ResponseCache.java b/java/net/ResponseCache.java
new file mode 100644
index 0000000..2dfaf4a
--- /dev/null
+++ b/java/net/ResponseCache.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.List;
+import sun.security.util.SecurityConstants;
+
+/**
+ * Represents implementations of URLConnection caches. An instance of
+ * such a class can be registered with the system by doing
+ * ResponseCache.setDefault(ResponseCache), and the system will call
+ * this object in order to:
+ *
+ *    <ul><li>store resource data which has been retrieved from an
+ *            external source into the cache</li>
+ *         <li>try to fetch a requested resource that may have been
+ *            stored in the cache</li>
+ *    </ul>
+ *
+ * The ResponseCache implementation decides which resources
+ * should be cached, and for how long they should be cached. If a
+ * request resource cannot be retrieved from the cache, then the
+ * protocol handlers will fetch the resource from its original
+ * location.
+ *
+ * The settings for URLConnection#useCaches controls whether the
+ * protocol is allowed to use a cached response.
+ *
+ * For more information on HTTP caching, see <a
+ * href="http://www.ietf.org/rfc/rfc2616.txt"><i>RFC&nbsp;2616: Hypertext
+ * Transfer Protocol -- HTTP/1.1</i></a>
+ *
+ * @author Yingxian Wang
+ * @since 1.5
+ */
+public abstract class ResponseCache {
+
+    /**
+     * The system wide cache that provides access to a url
+     * caching mechanism.
+     *
+     * @see #setDefault(ResponseCache)
+     * @see #getDefault()
+     */
+    private static ResponseCache theResponseCache;
+
+    /**
+     * Gets the system-wide response cache.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     * {@link NetPermission}{@code ("getResponseCache")}
+     *
+     * @see #setDefault(ResponseCache)
+     * @return the system-wide {@code ResponseCache}
+     * @since 1.5
+     */
+    public synchronized  static ResponseCache getDefault() {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.GET_RESPONSECACHE_PERMISSION);
+        }
+        return theResponseCache;
+    }
+
+    /**
+     * Sets (or unsets) the system-wide cache.
+     *
+     * Note: non-standard procotol handlers may ignore this setting.
+     *
+     * @param responseCache The response cache, or
+     *          {@code null} to unset the cache.
+     *
+     * @throws  SecurityException
+     *          If a security manager has been installed and it denies
+     * {@link NetPermission}{@code ("setResponseCache")}
+     *
+     * @see #getDefault()
+     * @since 1.5
+     */
+    public synchronized static void setDefault(ResponseCache responseCache) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            sm.checkPermission(SecurityConstants.SET_RESPONSECACHE_PERMISSION);
+        }
+        theResponseCache = responseCache;
+    }
+
+    /**
+     * Retrieve the cached response based on the requesting uri,
+     * request method and request headers. Typically this method is
+     * called by the protocol handler before it sends out the request
+     * to get the network resource. If a cached response is returned,
+     * that resource is used instead.
+     *
+     * @param uri a {@code URI} used to reference the requested
+     *            network resource
+     * @param rqstMethod a {@code String} representing the request
+     *            method
+     * @param rqstHeaders - a Map from request header
+     *            field names to lists of field values representing
+     *            the current request headers
+     * @return a {@code CacheResponse} instance if available
+     *          from cache, or null otherwise
+     * @throws  IOException if an I/O error occurs
+     * @throws  IllegalArgumentException if any one of the arguments is null
+     *
+     * @see     java.net.URLConnection#setUseCaches(boolean)
+     * @see     java.net.URLConnection#getUseCaches()
+     * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
+     * @see     java.net.URLConnection#getDefaultUseCaches()
+     */
+    public abstract CacheResponse
+        get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders)
+        throws IOException;
+
+    /**
+     * The protocol handler calls this method after a resource has
+     * been retrieved, and the ResponseCache must decide whether or
+     * not to store the resource in its cache. If the resource is to
+     * be cached, then put() must return a CacheRequest object which
+     * contains an OutputStream that the protocol handler will
+     * use to write the resource into the cache. If the resource is
+     * not to be cached, then put must return null.
+     *
+     * @param uri a {@code URI} used to reference the requested
+     *            network resource
+     * @param conn - a URLConnection instance that is used to fetch
+     *            the response to be cached
+     * @return a {@code CacheRequest} for recording the
+     *            response to be cached. Null return indicates that
+     *            the caller does not intend to cache the response.
+     * @throws IOException if an I/O error occurs
+     * @throws IllegalArgumentException if any one of the arguments is
+     *            null
+     */
+    public abstract CacheRequest put(URI uri, URLConnection conn)  throws IOException;
+}
diff --git a/java/net/SecureCacheResponse.java b/java/net/SecureCacheResponse.java
new file mode 100644
index 0000000..64fd414
--- /dev/null
+++ b/java/net/SecureCacheResponse.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.security.cert.Certificate;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import java.security.Principal;
+import java.util.List;
+
+/**
+ * Represents a cache response originally retrieved through secure
+ * means, such as TLS.
+ *
+ * @since 1.5
+ */
+public abstract class SecureCacheResponse extends CacheResponse {
+    /**
+     * Returns the cipher suite in use on the original connection that
+     * retrieved the network resource.
+     *
+     * @return a string representing the cipher suite
+     */
+    public abstract String getCipherSuite();
+
+    /**
+     * Returns the certificate chain that were sent to the server during
+     * handshaking of the original connection that retrieved the
+     * network resource.  Note: This method is useful only
+     * when using certificate-based cipher suites.
+     *
+     * @return an immutable List of Certificate representing the
+     *           certificate chain that was sent to the server. If no
+     *           certificate chain was sent, null will be returned.
+     * @see #getLocalPrincipal()
+     */
+    public abstract List<Certificate> getLocalCertificateChain();
+
+    /**
+     * Returns the server's certificate chain, which was established as
+     * part of defining the session in the original connection that
+     * retrieved the network resource, from cache.  Note: This method
+     * can be used only when using certificate-based cipher suites;
+     * using it with non-certificate-based cipher suites, such as
+     * Kerberos, will throw an SSLPeerUnverifiedException.
+     *
+     * @return an immutable List of Certificate representing the server's
+     *         certificate chain.
+     * @throws SSLPeerUnverifiedException if the peer is not verified.
+     * @see #getPeerPrincipal()
+     */
+    public abstract List<Certificate> getServerCertificateChain()
+        throws SSLPeerUnverifiedException;
+
+    /**
+     * Returns the server's principal which was established as part of
+     * defining the session during the original connection that
+     * retrieved the network resource.
+     *
+     * @return the server's principal. Returns an X500Principal of the
+     * end-entity certiticate for X509-based cipher suites, and
+     * KerberosPrincipal for Kerberos cipher suites.
+     *
+     * @throws SSLPeerUnverifiedException if the peer was not verified.
+     *
+     * @see #getServerCertificateChain()
+     * @see #getLocalPrincipal()
+     */
+     public abstract Principal getPeerPrincipal()
+             throws SSLPeerUnverifiedException;
+
+    /**
+      * Returns the principal that was sent to the server during
+      * handshaking in the original connection that retrieved the
+      * network resource.
+      *
+      * @return the principal sent to the server. Returns an X500Principal
+      * of the end-entity certificate for X509-based cipher suites, and
+      * KerberosPrincipal for Kerberos cipher suites. If no principal was
+      * sent, then null is returned.
+      *
+      * @see #getLocalCertificateChain()
+      * @see #getPeerPrincipal()
+      */
+     public abstract Principal getLocalPrincipal();
+}
diff --git a/java/net/ServerSocket.annotated.java b/java/net/ServerSocket.annotated.java
new file mode 100644
index 0000000..1fcd05f
--- /dev/null
+++ b/java/net/ServerSocket.annotated.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+import java.nio.channels.ServerSocketChannel;
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class ServerSocket implements java.io.Closeable {
+
+public ServerSocket() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ServerSocket(int port) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ServerSocket(int port, int backlog) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public ServerSocket(int port, int backlog, java.net.InetAddress bindAddr) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void bind(java.net.SocketAddress endpoint) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void bind(java.net.SocketAddress endpoint, int backlog) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+public int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getLocalSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.Socket accept() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public SocketImpl getImpl() throws SocketException { throw new RuntimeException("Stub!"); }
+
+protected final void implAccept(java.net.Socket s) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void close() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.ServerSocketChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+public boolean isBound() { throw new RuntimeException("Stub!"); }
+
+public boolean isClosed() { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSoTimeout(int timeout) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSoTimeout() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setReuseAddress(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getReuseAddress() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setSocketFactory(java.net.SocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getReceiveBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/net/ServerSocket.java b/java/net/ServerSocket.java
new file mode 100644
index 0000000..444a84d
--- /dev/null
+++ b/java/net/ServerSocket.java
@@ -0,0 +1,932 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.nio.channels.ServerSocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+
+/**
+ * This class implements server sockets. A server socket waits for
+ * requests to come in over the network. It performs some operation
+ * based on that request, and then possibly returns a result to the requester.
+ * <p>
+ * The actual work of the server socket is performed by an instance
+ * of the {@code SocketImpl} class. An application can
+ * change the socket factory that creates the socket
+ * implementation to configure itself to create sockets
+ * appropriate to the local firewall.
+ *
+ * @author  unascribed
+ * @see     java.net.SocketImpl
+ * @see     java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
+ * @see     java.nio.channels.ServerSocketChannel
+ * @since   JDK1.0
+ */
+public
+class ServerSocket implements java.io.Closeable {
+    /**
+     * Various states of this socket.
+     */
+    private boolean created = false;
+    private boolean bound = false;
+    private boolean closed = false;
+    private Object closeLock = new Object();
+
+    /**
+     * The implementation of this Socket.
+     */
+    private SocketImpl impl;
+
+    /**
+     * Are we using an older SocketImpl?
+     */
+    private boolean oldImpl = false;
+
+    /**
+     * Package-private constructor to create a ServerSocket associated with
+     * the given SocketImpl.
+     */
+    ServerSocket(SocketImpl impl) {
+        this.impl = impl;
+        impl.setServerSocket(this);
+    }
+
+    /**
+     * Creates an unbound server socket.
+     *
+     * @exception IOException IO error when opening the socket.
+     * @revised 1.4
+     */
+    public ServerSocket() throws IOException {
+        setImpl();
+    }
+
+    /**
+     * Creates a server socket, bound to the specified port. A port number
+     * of {@code 0} means that the port number is automatically
+     * allocated, typically from an ephemeral port range. This port
+     * number can then be retrieved by calling {@link #getLocalPort getLocalPort}.
+     * <p>
+     * The maximum queue length for incoming connection indications (a
+     * request to connect) is set to {@code 50}. If a connection
+     * indication arrives when the queue is full, the connection is refused.
+     * <p>
+     * If the application has specified a server socket factory, that
+     * factory's {@code createSocketImpl} method is called to create
+     * the actual socket implementation. Otherwise a "plain" socket is created.
+     * <p>
+     * If there is a security manager,
+     * its {@code checkListen} method is called
+     * with the {@code port} argument
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     *
+     * @param      port  the port number, or {@code 0} to use a port
+     *                   number that is automatically allocated.
+     *
+     * @exception  IOException  if an I/O error occurs when opening the socket.
+     * @exception  SecurityException
+     * if a security manager exists and its {@code checkListen}
+     * method doesn't allow the operation.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     *
+     * @see        java.net.SocketImpl
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
+     * @see        SecurityManager#checkListen
+     */
+    public ServerSocket(int port) throws IOException {
+        this(port, 50, null);
+    }
+
+    /**
+     * Creates a server socket and binds it to the specified local port
+     * number, with the specified backlog.
+     * A port number of {@code 0} means that the port number is
+     * automatically allocated, typically from an ephemeral port range.
+     * This port number can then be retrieved by calling
+     * {@link #getLocalPort getLocalPort}.
+     * <p>
+     * The maximum queue length for incoming connection indications (a
+     * request to connect) is set to the {@code backlog} parameter. If
+     * a connection indication arrives when the queue is full, the
+     * connection is refused.
+     * <p>
+     * If the application has specified a server socket factory, that
+     * factory's {@code createSocketImpl} method is called to create
+     * the actual socket implementation. Otherwise a "plain" socket is created.
+     * <p>
+     * If there is a security manager,
+     * its {@code checkListen} method is called
+     * with the {@code port} argument
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * The {@code backlog} argument is the requested maximum number of
+     * pending connections on the socket. Its exact semantics are implementation
+     * specific. In particular, an implementation may impose a maximum length
+     * or may choose to ignore the parameter altogther. The value provided
+     * should be greater than {@code 0}. If it is less than or equal to
+     * {@code 0}, then an implementation specific default will be used.
+     * <P>
+     *
+     * @param      port     the port number, or {@code 0} to use a port
+     *                      number that is automatically allocated.
+     * @param      backlog  requested maximum length of the queue of incoming
+     *                      connections.
+     *
+     * @exception  IOException  if an I/O error occurs when opening the socket.
+     * @exception  SecurityException
+     * if a security manager exists and its {@code checkListen}
+     * method doesn't allow the operation.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     *
+     * @see        java.net.SocketImpl
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        java.net.ServerSocket#setSocketFactory(java.net.SocketImplFactory)
+     * @see        SecurityManager#checkListen
+     */
+    public ServerSocket(int port, int backlog) throws IOException {
+        this(port, backlog, null);
+    }
+
+    /**
+     * Create a server with the specified port, listen backlog, and
+     * local IP address to bind to.  The <i>bindAddr</i> argument
+     * can be used on a multi-homed host for a ServerSocket that
+     * will only accept connect requests to one of its addresses.
+     * If <i>bindAddr</i> is null, it will default accepting
+     * connections on any/all local addresses.
+     * The port must be between 0 and 65535, inclusive.
+     * A port number of {@code 0} means that the port number is
+     * automatically allocated, typically from an ephemeral port range.
+     * This port number can then be retrieved by calling
+     * {@link #getLocalPort getLocalPort}.
+     *
+     * <P>If there is a security manager, this method
+     * calls its {@code checkListen} method
+     * with the {@code port} argument
+     * as its argument to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * The {@code backlog} argument is the requested maximum number of
+     * pending connections on the socket. Its exact semantics are implementation
+     * specific. In particular, an implementation may impose a maximum length
+     * or may choose to ignore the parameter altogther. The value provided
+     * should be greater than {@code 0}. If it is less than or equal to
+     * {@code 0}, then an implementation specific default will be used.
+     * <P>
+     * @param port  the port number, or {@code 0} to use a port
+     *              number that is automatically allocated.
+     * @param backlog requested maximum length of the queue of incoming
+     *                connections.
+     * @param bindAddr the local InetAddress the server will bind to
+     *
+     * @throws  SecurityException if a security manager exists and
+     * its {@code checkListen} method doesn't allow the operation.
+     *
+     * @throws  IOException if an I/O error occurs when opening the socket.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     *
+     * @see SocketOptions
+     * @see SocketImpl
+     * @see SecurityManager#checkListen
+     * @since   JDK1.1
+     */
+    public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException {
+        setImpl();
+        if (port < 0 || port > 0xFFFF)
+            throw new IllegalArgumentException(
+                       "Port value out of range: " + port);
+        if (backlog < 1)
+          backlog = 50;
+        try {
+            bind(new InetSocketAddress(bindAddr, port), backlog);
+        } catch(SecurityException e) {
+            close();
+            throw e;
+        } catch(IOException e) {
+            close();
+            throw e;
+        }
+    }
+
+    // Android-changed: Made getImpl() public and @hide, for internal use.
+    /**
+     * Get the {@code SocketImpl} attached to this socket, creating
+     * it if necessary.
+     *
+     * @return  the {@code SocketImpl} attached to that ServerSocket.
+     * @throws SocketException if creation fails.
+     * @since 1.4
+     * @hide
+     */
+    public SocketImpl getImpl() throws SocketException {
+        if (!created)
+            createImpl();
+        return impl;
+    }
+
+    private void checkOldImpl() {
+        if (impl == null)
+            return;
+        // SocketImpl.connect() is a protected method, therefore we need to use
+        // getDeclaredMethod, therefore we need permission to access the member
+        try {
+            AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Void>() {
+                    public Void run() throws NoSuchMethodException {
+                        impl.getClass().getDeclaredMethod("connect",
+                                                          SocketAddress.class,
+                                                          int.class);
+                        return null;
+                    }
+                });
+        } catch (java.security.PrivilegedActionException e) {
+            oldImpl = true;
+        }
+    }
+
+    private void setImpl() {
+        if (factory != null) {
+            impl = factory.createSocketImpl();
+            checkOldImpl();
+        } else {
+            // No need to do a checkOldImpl() here, we know it's an up to date
+            // SocketImpl!
+            impl = new SocksSocketImpl();
+        }
+        if (impl != null)
+            impl.setServerSocket(this);
+    }
+
+    /**
+     * Creates the socket implementation.
+     *
+     * @throws IOException if creation fails
+     * @since 1.4
+     */
+    void createImpl() throws SocketException {
+        if (impl == null)
+            setImpl();
+        try {
+            impl.create(true);
+            created = true;
+        } catch (IOException e) {
+            throw new SocketException(e.getMessage());
+        }
+    }
+
+    /**
+     *
+     * Binds the {@code ServerSocket} to a specific address
+     * (IP address and port number).
+     * <p>
+     * If the address is {@code null}, then the system will pick up
+     * an ephemeral port and a valid local address to bind the socket.
+     * <p>
+     * @param   endpoint        The IP address and port number to bind to.
+     * @throws  IOException if the bind operation fails, or if the socket
+     *                     is already bound.
+     * @throws  SecurityException       if a {@code SecurityManager} is present and
+     * its {@code checkListen} method doesn't allow the operation.
+     * @throws  IllegalArgumentException if endpoint is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     */
+    public void bind(SocketAddress endpoint) throws IOException {
+        bind(endpoint, 50);
+    }
+
+    /**
+     *
+     * Binds the {@code ServerSocket} to a specific address
+     * (IP address and port number).
+     * <p>
+     * If the address is {@code null}, then the system will pick up
+     * an ephemeral port and a valid local address to bind the socket.
+     * <P>
+     * The {@code backlog} argument is the requested maximum number of
+     * pending connections on the socket. Its exact semantics are implementation
+     * specific. In particular, an implementation may impose a maximum length
+     * or may choose to ignore the parameter altogther. The value provided
+     * should be greater than {@code 0}. If it is less than or equal to
+     * {@code 0}, then an implementation specific default will be used.
+     * @param   endpoint        The IP address and port number to bind to.
+     * @param   backlog         requested maximum length of the queue of
+     *                          incoming connections.
+     * @throws  IOException if the bind operation fails, or if the socket
+     *                     is already bound.
+     * @throws  SecurityException       if a {@code SecurityManager} is present and
+     * its {@code checkListen} method doesn't allow the operation.
+     * @throws  IllegalArgumentException if endpoint is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     */
+    public void bind(SocketAddress endpoint, int backlog) throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!oldImpl && isBound())
+            throw new SocketException("Already bound");
+        if (endpoint == null)
+            endpoint = new InetSocketAddress(0);
+        if (!(endpoint instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+        InetSocketAddress epoint = (InetSocketAddress) endpoint;
+        if (epoint.isUnresolved())
+            throw new SocketException("Unresolved address");
+        if (backlog < 1)
+          backlog = 50;
+        try {
+            SecurityManager security = System.getSecurityManager();
+            if (security != null)
+                security.checkListen(epoint.getPort());
+            getImpl().bind(epoint.getAddress(), epoint.getPort());
+            getImpl().listen(backlog);
+            bound = true;
+        } catch(SecurityException e) {
+            bound = false;
+            throw e;
+        } catch(IOException e) {
+            bound = false;
+            throw e;
+        }
+    }
+
+    /**
+     * Returns the local address of this server socket.
+     * <p>
+     * If the socket was bound prior to being {@link #close closed},
+     * then this method will continue to return the local address
+     * after the socket is closed.
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * the {@link InetAddress#getLoopbackAddress loopback} address is returned.
+     *
+     * @return  the address to which this socket is bound,
+     *          or the loopback address if denied by the security manager,
+     *          or {@code null} if the socket is unbound.
+     *
+     * @see SecurityManager#checkConnect
+     */
+    public InetAddress getInetAddress() {
+        if (!isBound())
+            return null;
+        try {
+            InetAddress in = getImpl().getInetAddress();
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkConnect(in.getHostAddress(), -1);
+            return in;
+        } catch (SecurityException e) {
+            return InetAddress.getLoopbackAddress();
+        } catch (SocketException e) {
+            // nothing
+            // If we're bound, the impl has been created
+            // so we shouldn't get here
+        }
+        return null;
+    }
+
+    /**
+     * Returns the port number on which this socket is listening.
+     * <p>
+     * If the socket was bound prior to being {@link #close closed},
+     * then this method will continue to return the port number
+     * after the socket is closed.
+     *
+     * @return  the port number to which this socket is listening or
+     *          -1 if the socket is not bound yet.
+     */
+    public int getLocalPort() {
+        if (!isBound())
+            return -1;
+        try {
+            return getImpl().getLocalPort();
+        } catch (SocketException e) {
+            // nothing
+            // If we're bound, the impl has been created
+            // so we shouldn't get here
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the address of the endpoint this socket is bound to.
+     * <p>
+     * If the socket was bound prior to being {@link #close closed},
+     * then this method will continue to return the address of the endpoint
+     * after the socket is closed.
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link InetAddress#getLoopbackAddress loopback} address and the local
+     * port to which the socket is bound is returned.
+     *
+     * @return a {@code SocketAddress} representing the local endpoint of
+     *         this socket, or a {@code SocketAddress} representing the
+     *         loopback address if denied by the security manager,
+     *         or {@code null} if the socket is not bound yet.
+     *
+     * @see #getInetAddress()
+     * @see #getLocalPort()
+     * @see #bind(SocketAddress)
+     * @see SecurityManager#checkConnect
+     * @since 1.4
+     */
+
+    public SocketAddress getLocalSocketAddress() {
+        if (!isBound())
+            return null;
+        return new InetSocketAddress(getInetAddress(), getLocalPort());
+    }
+
+    /**
+     * Listens for a connection to be made to this socket and accepts
+     * it. The method blocks until a connection is made.
+     *
+     * <p>A new Socket {@code s} is created and, if there
+     * is a security manager,
+     * the security manager's {@code checkAccept} method is called
+     * with {@code s.getInetAddress().getHostAddress()} and
+     * {@code s.getPort()}
+     * as its arguments to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @exception  IOException  if an I/O error occurs when waiting for a
+     *               connection.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkAccept} method doesn't allow the operation.
+     * @exception  SocketTimeoutException if a timeout was previously set with setSoTimeout and
+     *             the timeout has been reached.
+     * @exception  java.nio.channels.IllegalBlockingModeException
+     *             if this socket has an associated channel, the channel is in
+     *             non-blocking mode, and there is no connection ready to be
+     *             accepted
+     *
+     * @return the new Socket
+     * @see SecurityManager#checkAccept
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public Socket accept() throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!isBound())
+            throw new SocketException("Socket is not bound yet");
+        Socket s = new Socket((SocketImpl) null);
+        implAccept(s);
+        return s;
+    }
+
+    /**
+     * Subclasses of ServerSocket use this method to override accept()
+     * to return their own subclass of socket.  So a FooServerSocket
+     * will typically hand this method an <i>empty</i> FooSocket.  On
+     * return from implAccept the FooSocket will be connected to a client.
+     *
+     * @param s the Socket
+     * @throws java.nio.channels.IllegalBlockingModeException
+     *         if this socket has an associated channel,
+     *         and the channel is in non-blocking mode
+     * @throws IOException if an I/O error occurs when waiting
+     * for a connection.
+     * @since   JDK1.1
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    protected final void implAccept(Socket s) throws IOException {
+        SocketImpl si = null;
+        try {
+            if (s.impl == null)
+              s.setImpl();
+            else {
+                s.impl.reset();
+            }
+            si = s.impl;
+            s.impl = null;
+            si.address = new InetAddress();
+            si.fd = new FileDescriptor();
+            getImpl().accept(si);
+
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkAccept(si.getInetAddress().getHostAddress(),
+                                     si.getPort());
+            }
+        } catch (IOException e) {
+            if (si != null)
+                si.reset();
+            s.impl = si;
+            throw e;
+        } catch (SecurityException e) {
+            if (si != null)
+                si.reset();
+            s.impl = si;
+            throw e;
+        }
+        s.impl = si;
+        s.postAccept();
+    }
+
+    /**
+     * Closes this socket.
+     *
+     * Any thread currently blocked in {@link #accept()} will throw
+     * a {@link SocketException}.
+     *
+     * <p> If this socket has an associated channel then the channel is closed
+     * as well.
+     *
+     * @exception  IOException  if an I/O error occurs when closing the socket.
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public void close() throws IOException {
+        synchronized(closeLock) {
+            if (isClosed())
+                return;
+            if (created)
+                impl.close();
+            closed = true;
+        }
+    }
+
+    /**
+     * Returns the unique {@link java.nio.channels.ServerSocketChannel} object
+     * associated with this socket, if any.
+     *
+     * <p> A server socket will have a channel if, and only if, the channel
+     * itself was created via the {@link
+     * java.nio.channels.ServerSocketChannel#open ServerSocketChannel.open}
+     * method.
+     *
+     * @return  the server-socket channel associated with this socket,
+     *          or {@code null} if this socket was not created
+     *          for a channel
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public ServerSocketChannel getChannel() {
+        return null;
+    }
+
+    /**
+     * Returns the binding state of the ServerSocket.
+     *
+     * @return true if the ServerSocket successfully bound to an address
+     * @since 1.4
+     */
+    public boolean isBound() {
+        // Before 1.3 ServerSockets were always bound during creation
+        return bound || oldImpl;
+    }
+
+    /**
+     * Returns the closed state of the ServerSocket.
+     *
+     * @return true if the socket has been closed
+     * @since 1.4
+     */
+    public boolean isClosed() {
+        synchronized(closeLock) {
+            return closed;
+        }
+    }
+
+    /**
+     * Enable/disable {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} with the
+     * specified timeout, in milliseconds.  With this option set to a non-zero
+     * timeout, a call to accept() for this ServerSocket
+     * will block for only this amount of time.  If the timeout expires,
+     * a <B>java.net.SocketTimeoutException</B> is raised, though the
+     * ServerSocket is still valid.  The option <B>must</B> be enabled
+     * prior to entering the blocking operation to have effect.  The
+     * timeout must be {@code > 0}.
+     * A timeout of zero is interpreted as an infinite timeout.
+     * @param timeout the specified timeout, in milliseconds
+     * @exception SocketException if there is an error in
+     * the underlying protocol, such as a TCP error.
+     * @since   JDK1.1
+     * @see #getSoTimeout()
+     */
+    public synchronized void setSoTimeout(int timeout) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+    }
+
+    /**
+     * Retrieve setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}.
+     * 0 returns implies that the option is disabled (i.e., timeout of infinity).
+     * @return the {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT} value
+     * @exception IOException if an I/O error occurs
+     * @since   JDK1.1
+     * @see #setSoTimeout(int)
+     */
+    public synchronized int getSoTimeout() throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
+        /* extra type safety */
+        if (o instanceof Integer) {
+            return ((Integer) o).intValue();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Enable/disable the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     * socket option.
+     * <p>
+     * When a TCP connection is closed the connection may remain
+     * in a timeout state for a period of time after the connection
+     * is closed (typically known as the {@code TIME_WAIT} state
+     * or {@code 2MSL} wait state).
+     * For applications using a well known socket address or port
+     * it may not be possible to bind a socket to the required
+     * {@code SocketAddress} if there is a connection in the
+     * timeout state involving the socket address or port.
+     * <p>
+     * Enabling {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} prior to
+     * binding the socket using {@link #bind(SocketAddress)} allows the socket
+     * to be bound even though a previous connection is in a timeout state.
+     * <p>
+     * When a {@code ServerSocket} is created the initial setting
+     * of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is not defined.
+     * Applications can use {@link #getReuseAddress()} to determine the initial
+     * setting of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}.
+     * <p>
+     * The behaviour when {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is
+     * enabled or disabled after a socket is bound (See {@link #isBound()})
+     * is not defined.
+     *
+     * @param on  whether to enable or disable the socket option
+     * @exception SocketException if an error occurs enabling or
+     *            disabling the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     *            socket option, or the socket is closed.
+     * @since 1.4
+     * @see #getReuseAddress()
+     * @see #bind(SocketAddress)
+     * @see #isBound()
+     * @see #isClosed()
+     */
+    public void setReuseAddress(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
+     *
+     * @return a {@code boolean} indicating whether or not
+     *         {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   1.4
+     * @see #setReuseAddress(boolean)
+     */
+    public boolean getReuseAddress() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
+    }
+
+    /**
+     * Returns the implementation address and implementation port of
+     * this socket as a {@code String}.
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * an {@code InetAddress} representing the
+     * {@link InetAddress#getLoopbackAddress loopback} address is returned as
+     * the implementation address.
+     *
+     * @return  a string representation of this socket.
+     */
+    public String toString() {
+        if (!isBound())
+            return "ServerSocket[unbound]";
+        InetAddress in;
+        if (System.getSecurityManager() != null)
+            in = InetAddress.getLoopbackAddress();
+        else
+            in = impl.getInetAddress();
+        return "ServerSocket[addr=" + in +
+                ",localport=" + impl.getLocalPort()  + "]";
+    }
+
+    void setBound() {
+        bound = true;
+    }
+
+    void setCreated() {
+        created = true;
+    }
+
+    /**
+     * The factory for all server sockets.
+     */
+    private static SocketImplFactory factory = null;
+
+    /**
+     * Sets the server socket implementation factory for the
+     * application. The factory can be specified only once.
+     * <p>
+     * When an application creates a new server socket, the socket
+     * implementation factory's {@code createSocketImpl} method is
+     * called to create the actual socket implementation.
+     * <p>
+     * Passing {@code null} to the method is a no-op unless the factory
+     * was already set.
+     * <p>
+     * If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param      fac   the desired factory.
+     * @exception  IOException  if an I/O error occurs when setting the
+     *               socket factory.
+     * @exception  SocketException  if the factory has already been defined.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't allow the operation.
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        SecurityManager#checkSetFactory
+     */
+    public static synchronized void setSocketFactory(SocketImplFactory fac) throws IOException {
+        if (factory != null) {
+            throw new SocketException("factory already defined");
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSetFactory();
+        }
+        factory = fac;
+    }
+
+    /**
+     * Sets a default proposed value for the
+     * {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option for sockets
+     * accepted from this {@code ServerSocket}. The value actually set
+     * in the accepted socket must be determined by calling
+     * {@link Socket#getReceiveBufferSize()} after the socket
+     * is returned by {@link #accept()}.
+     * <p>
+     * The value of {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is used both to
+     * set the size of the internal socket receive buffer, and to set the size
+     * of the TCP receive window that is advertized to the remote peer.
+     * <p>
+     * It is possible to change the value subsequently, by calling
+     * {@link Socket#setReceiveBufferSize(int)}. However, if the application
+     * wishes to allow a receive window larger than 64K bytes, as defined by RFC1323
+     * then the proposed value must be set in the ServerSocket <B>before</B>
+     * it is bound to a local address. This implies, that the ServerSocket must be
+     * created with the no-argument constructor, then setReceiveBufferSize() must
+     * be called and lastly the ServerSocket is bound to an address by calling bind().
+     * <p>
+     * Failure to do this will not cause an error, and the buffer size may be set to the
+     * requested value but the TCP receive window in sockets accepted from
+     * this ServerSocket will be no larger than 64K bytes.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @param size the size to which to set the receive buffer
+     * size. This value must be greater than 0.
+     *
+     * @exception IllegalArgumentException if the
+     * value is 0 or is negative.
+     *
+     * @since 1.4
+     * @see #getReceiveBufferSize
+     */
+     public synchronized void setReceiveBufferSize (int size) throws SocketException {
+        if (!(size > 0)) {
+            throw new IllegalArgumentException("negative receive size");
+        }
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+    }
+
+    /**
+     * Gets the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option
+     * for this {@code ServerSocket}, that is the proposed buffer size that
+     * will be used for Sockets accepted from this {@code ServerSocket}.
+     *
+     * <p>Note, the value actually set in the accepted socket is determined by
+     * calling {@link Socket#getReceiveBufferSize()}.
+     * @return the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF}
+     *         option for this {@code Socket}.
+     * @exception SocketException if there is an error
+     *            in the underlying protocol, such as a TCP error.
+     * @see #setReceiveBufferSize(int)
+     * @since 1.4
+     */
+    public synchronized int getReceiveBufferSize()
+    throws SocketException{
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        int result = 0;
+        Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
+        if (o instanceof Integer) {
+            result = ((Integer)o).intValue();
+        }
+        return result;
+    }
+
+    /**
+     * Sets performance preferences for this ServerSocket.
+     *
+     * <p> Sockets use the TCP/IP protocol by default.  Some implementations
+     * may offer alternative protocols which have different performance
+     * characteristics than TCP/IP.  This method allows the application to
+     * express its own preferences as to how these tradeoffs should be made
+     * when the implementation chooses from the available protocols.
+     *
+     * <p> Performance preferences are described by three integers
+     * whose values indicate the relative importance of short connection time,
+     * low latency, and high bandwidth.  The absolute values of the integers
+     * are irrelevant; in order to choose a protocol the values are simply
+     * compared, with larger values indicating stronger preferences.  If the
+     * application prefers short connection time over both low latency and high
+     * bandwidth, for example, then it could invoke this method with the values
+     * {@code (1, 0, 0)}.  If the application prefers high bandwidth above low
+     * latency, and low latency above short connection time, then it could
+     * invoke this method with the values {@code (0, 1, 2)}.
+     *
+     * <p> Invoking this method after this socket has been bound
+     * will have no effect. This implies that in order to use this capability
+     * requires the socket to be created with the no-argument constructor.
+     *
+     * @param  connectionTime
+     *         An {@code int} expressing the relative importance of a short
+     *         connection time
+     *
+     * @param  latency
+     *         An {@code int} expressing the relative importance of low
+     *         latency
+     *
+     * @param  bandwidth
+     *         An {@code int} expressing the relative importance of high
+     *         bandwidth
+     *
+     * @since 1.5
+     */
+    public void setPerformancePreferences(int connectionTime,
+                                          int latency,
+                                          int bandwidth)
+    {
+        /* Not implemented yet */
+    }
+
+    // Android-added: getFileDescriptor$(), for testing / internal use.
+    /**
+     * @hide internal use only
+     */
+    public FileDescriptor getFileDescriptor$() {
+        return impl.getFileDescriptor();
+    }
+}
diff --git a/java/net/Socket.annotated.java b/java/net/Socket.annotated.java
new file mode 100644
index 0000000..e021788
--- /dev/null
+++ b/java/net/Socket.annotated.java
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+import java.nio.channels.SocketChannel;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public class Socket implements java.io.Closeable {
+
+public Socket() { throw new RuntimeException("Stub!"); }
+
+public Socket(java.net.Proxy proxy) { throw new RuntimeException("Stub!"); }
+
+protected Socket(java.net.SocketImpl impl) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.lang.String host, int port) throws java.io.IOException, java.net.UnknownHostException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.net.InetAddress address, int port) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.lang.String host, int port, java.net.InetAddress localAddr, int localPort) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public Socket(java.net.InetAddress address, int port, java.net.InetAddress localAddr, int localPort) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public Socket(java.lang.String host, int port, boolean stream) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+@Deprecated
+public Socket(java.net.InetAddress host, int port, boolean stream) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.SocketAddress endpoint) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void connect(java.net.SocketAddress endpoint, int timeout) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void bind(java.net.SocketAddress bindpoint) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.InetAddress getLocalAddress() { throw new RuntimeException("Stub!"); }
+
+public int getPort() { throw new RuntimeException("Stub!"); }
+
+public int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getRemoteSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.net.SocketAddress getLocalSocketAddress() { throw new RuntimeException("Stub!"); }
+
+public java.nio.channels.SocketChannel getChannel() { throw new RuntimeException("Stub!"); }
+
+public java.io.InputStream getInputStream() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.io.OutputStream getOutputStream() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setTcpNoDelay(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getTcpNoDelay() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setSoLinger(boolean on, int linger) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public int getSoLinger() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void sendUrgentData(int data) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setOOBInline(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getOOBInline() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSoTimeout(int timeout) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSoTimeout() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setSendBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getSendBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void setReceiveBufferSize(int size) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized int getReceiveBufferSize() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setKeepAlive(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getKeepAlive() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setTrafficClass(int tc) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public int getTrafficClass() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public void setReuseAddress(boolean on) throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public boolean getReuseAddress() throws java.net.SocketException { throw new RuntimeException("Stub!"); }
+
+public synchronized void close() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void shutdownInput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void shutdownOutput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+public boolean isConnected() { throw new RuntimeException("Stub!"); }
+
+public boolean isBound() { throw new RuntimeException("Stub!"); }
+
+public boolean isClosed() { throw new RuntimeException("Stub!"); }
+
+public boolean isInputShutdown() { throw new RuntimeException("Stub!"); }
+
+public boolean isOutputShutdown() { throw new RuntimeException("Stub!"); }
+
+public static synchronized void setSocketImplFactory(java.net.SocketImplFactory fac) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+@libcore.api.IntraCoreApi
+public java.io.FileDescriptor getFileDescriptor$() { throw new RuntimeException("Stub!"); }
+}
+
diff --git a/java/net/Socket.java b/java/net/Socket.java
new file mode 100644
index 0000000..bae1d1c
--- /dev/null
+++ b/java/net/Socket.java
@@ -0,0 +1,1783 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.FileDescriptor;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.IOException;
+import java.nio.channels.SocketChannel;
+import java.security.AccessController;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedAction;
+
+/**
+ * This class implements client sockets (also called just
+ * "sockets"). A socket is an endpoint for communication
+ * between two machines.
+ * <p>
+ * The actual work of the socket is performed by an instance of the
+ * {@code SocketImpl} class. An application, by changing
+ * the socket factory that creates the socket implementation,
+ * can configure itself to create sockets appropriate to the local
+ * firewall.
+ *
+ * @author  unascribed
+ * @see     java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
+ * @see     java.net.SocketImpl
+ * @see     java.nio.channels.SocketChannel
+ * @since   JDK1.0
+ */
+public
+class Socket implements java.io.Closeable {
+    /**
+     * Various states of this socket.
+     */
+    private boolean created = false;
+    private boolean bound = false;
+    private boolean connected = false;
+    private boolean closed = false;
+    private Object closeLock = new Object();
+    private boolean shutIn = false;
+    private boolean shutOut = false;
+
+    /**
+     * The implementation of this Socket.
+     */
+    SocketImpl impl;
+
+    /**
+     * Are we using an older SocketImpl?
+     */
+    private boolean oldImpl = false;
+
+    /**
+     * Creates an unconnected socket, with the
+     * system-default type of SocketImpl.
+     *
+     * @since   JDK1.1
+     * @revised 1.4
+     */
+    public Socket() {
+        setImpl();
+    }
+
+    /**
+     * Creates an unconnected socket, specifying the type of proxy, if any,
+     * that should be used regardless of any other settings.
+     * <P>
+     * If there is a security manager, its {@code checkConnect} method
+     * is called with the proxy host address and port number
+     * as its arguments. This could result in a SecurityException.
+     * <P>
+     * Examples:
+     * <UL> <LI>{@code Socket s = new Socket(Proxy.NO_PROXY);} will create
+     * a plain socket ignoring any other proxy configuration.</LI>
+     * <LI>{@code Socket s = new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress("socks.mydom.com", 1080)));}
+     * will create a socket connecting through the specified SOCKS proxy
+     * server.</LI>
+     * </UL>
+     *
+     * @param proxy a {@link java.net.Proxy Proxy} object specifying what kind
+     *              of proxying should be used.
+     * @throws IllegalArgumentException if the proxy is of an invalid type
+     *          or {@code null}.
+     * @throws SecurityException if a security manager is present and
+     *                           permission to connect to the proxy is
+     *                           denied.
+     * @see java.net.ProxySelector
+     * @see java.net.Proxy
+     *
+     * @since   1.5
+     */
+    public Socket(Proxy proxy) {
+        // Create a copy of Proxy as a security measure
+        if (proxy == null) {
+            throw new IllegalArgumentException("Invalid Proxy");
+        }
+        Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY
+                                          : sun.net.ApplicationProxy.create(proxy);
+        Proxy.Type type = p.type();
+        // Android-changed: Removed HTTP proxy support.
+        // if (type == Proxy.Type.SOCKS || type == Proxy.Type.HTTP) {
+        if (type == Proxy.Type.SOCKS) {
+            SecurityManager security = System.getSecurityManager();
+            InetSocketAddress epoint = (InetSocketAddress) p.address();
+            if (epoint.getAddress() != null) {
+                checkAddress (epoint.getAddress(), "Socket");
+            }
+            if (security != null) {
+                if (epoint.isUnresolved())
+                    epoint = new InetSocketAddress(epoint.getHostName(), epoint.getPort());
+                if (epoint.isUnresolved())
+                    security.checkConnect(epoint.getHostName(), epoint.getPort());
+                else
+                    security.checkConnect(epoint.getAddress().getHostAddress(),
+                                  epoint.getPort());
+            }
+            // Android-changed: Removed HTTP proxy support.
+            // impl = type == Proxy.Type.SOCKS ? new SocksSocketImpl(p)
+            //                                : new HttpConnectSocketImpl(p);
+            impl = new SocksSocketImpl(p);
+            impl.setSocket(this);
+        } else {
+            if (p == Proxy.NO_PROXY) {
+                if (factory == null) {
+                    impl = new PlainSocketImpl();
+                    impl.setSocket(this);
+                } else
+                    setImpl();
+            } else
+                throw new IllegalArgumentException("Invalid Proxy");
+        }
+    }
+
+    /**
+     * Creates an unconnected Socket with a user-specified
+     * SocketImpl.
+     * <P>
+     * @param impl an instance of a <B>SocketImpl</B>
+     * the subclass wishes to use on the Socket.
+     *
+     * @exception SocketException if there is an error in the underlying protocol,
+     * such as a TCP error.
+     * @since   JDK1.1
+     */
+    protected Socket(SocketImpl impl) throws SocketException {
+        this.impl = impl;
+        if (impl != null) {
+            checkOldImpl();
+            this.impl.setSocket(this);
+        }
+    }
+
+    /**
+     * Creates a stream socket and connects it to the specified port
+     * number on the named host.
+     * <p>
+     * If the specified host is {@code null} it is the equivalent of
+     * specifying the address as
+     * {@link java.net.InetAddress#getByName InetAddress.getByName}{@code (null)}.
+     * In other words, it is equivalent to specifying an address of the
+     * loopback interface. </p>
+     * <p>
+     * If the application has specified a server socket factory, that
+     * factory's {@code createSocketImpl} method is called to create
+     * the actual socket implementation. Otherwise a "plain" socket is created.
+     * <p>
+     * If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with the host address and {@code port}
+     * as its arguments. This could result in a SecurityException.
+     *
+     * @param      host   the host name, or {@code null} for the loopback address.
+     * @param      port   the port number.
+     *
+     * @exception  UnknownHostException if the IP address of
+     * the host could not be determined.
+     *
+     * @exception  IOException  if an I/O error occurs when creating the socket.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkConnect} method doesn't allow the operation.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
+     * @see        java.net.SocketImpl
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        SecurityManager#checkConnect
+     */
+    public Socket(String host, int port)
+        throws UnknownHostException, IOException
+    {
+        // Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+        this(InetAddress.getAllByName(host), port, (SocketAddress) null, true);
+    }
+
+    /**
+     * Creates a stream socket and connects it to the specified port
+     * number at the specified IP address.
+     * <p>
+     * If the application has specified a socket factory, that factory's
+     * {@code createSocketImpl} method is called to create the
+     * actual socket implementation. Otherwise a "plain" socket is created.
+     * <p>
+     * If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with the host address and {@code port}
+     * as its arguments. This could result in a SecurityException.
+     *
+     * @param      address   the IP address.
+     * @param      port      the port number.
+     * @exception  IOException  if an I/O error occurs when creating the socket.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkConnect} method doesn't allow the operation.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     * @exception  NullPointerException if {@code address} is null.
+     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
+     * @see        java.net.SocketImpl
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        SecurityManager#checkConnect
+     */
+    public Socket(InetAddress address, int port) throws IOException {
+        // Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+        this(nonNullAddress(address), port, (SocketAddress) null, true);
+    }
+
+    /**
+     * Creates a socket and connects it to the specified remote host on
+     * the specified remote port. The Socket will also bind() to the local
+     * address and port supplied.
+     * <p>
+     * If the specified host is {@code null} it is the equivalent of
+     * specifying the address as
+     * {@link java.net.InetAddress#getByName InetAddress.getByName}{@code (null)}.
+     * In other words, it is equivalent to specifying an address of the
+     * loopback interface. </p>
+     * <p>
+     * A local port number of {@code zero} will let the system pick up a
+     * free port in the {@code bind} operation.</p>
+     * <p>
+     * If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with the host address and {@code port}
+     * as its arguments. This could result in a SecurityException.
+     *
+     * @param host the name of the remote host, or {@code null} for the loopback address.
+     * @param port the remote port
+     * @param localAddr the local address the socket is bound to, or
+     *        {@code null} for the {@code anyLocal} address.
+     * @param localPort the local port the socket is bound to, or
+     *        {@code zero} for a system selected free port.
+     * @exception  IOException  if an I/O error occurs when creating the socket.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkConnect} method doesn't allow the connection
+     *             to the destination, or if its {@code checkListen} method
+     *             doesn't allow the bind to the local port.
+     * @exception  IllegalArgumentException if the port parameter or localPort
+     *             parameter is outside the specified range of valid port values,
+     *             which is between 0 and 65535, inclusive.
+     * @see        SecurityManager#checkConnect
+     * @since   JDK1.1
+     */
+    public Socket(String host, int port, InetAddress localAddr,
+                  int localPort) throws IOException {
+        // Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+        this(InetAddress.getAllByName(host), port,
+             new InetSocketAddress(localAddr, localPort), true);
+    }
+
+    /**
+     * Creates a socket and connects it to the specified remote address on
+     * the specified remote port. The Socket will also bind() to the local
+     * address and port supplied.
+     * <p>
+     * If the specified local address is {@code null} it is the equivalent of
+     * specifying the address as the AnyLocal address
+     * (see {@link java.net.InetAddress#isAnyLocalAddress InetAddress.isAnyLocalAddress}{@code ()}).
+     * <p>
+     * A local port number of {@code zero} will let the system pick up a
+     * free port in the {@code bind} operation.</p>
+     * <p>
+     * If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with the host address and {@code port}
+     * as its arguments. This could result in a SecurityException.
+     *
+     * @param address the remote address
+     * @param port the remote port
+     * @param localAddr the local address the socket is bound to, or
+     *        {@code null} for the {@code anyLocal} address.
+     * @param localPort the local port the socket is bound to or
+     *        {@code zero} for a system selected free port.
+     * @exception  IOException  if an I/O error occurs when creating the socket.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkConnect} method doesn't allow the connection
+     *             to the destination, or if its {@code checkListen} method
+     *             doesn't allow the bind to the local port.
+     * @exception  IllegalArgumentException if the port parameter or localPort
+     *             parameter is outside the specified range of valid port values,
+     *             which is between 0 and 65535, inclusive.
+     * @exception  NullPointerException if {@code address} is null.
+     * @see        SecurityManager#checkConnect
+     * @since   JDK1.1
+     */
+    public Socket(InetAddress address, int port, InetAddress localAddr,
+                  int localPort) throws IOException {
+        // Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+        this(nonNullAddress(address), port,
+             new InetSocketAddress(localAddr, localPort), true);
+    }
+
+    /**
+     * Creates a stream socket and connects it to the specified port
+     * number on the named host.
+     * <p>
+     * If the specified host is {@code null} it is the equivalent of
+     * specifying the address as
+     * {@link java.net.InetAddress#getByName InetAddress.getByName}{@code (null)}.
+     * In other words, it is equivalent to specifying an address of the
+     * loopback interface. </p>
+     * <p>
+     * If the stream argument is {@code true}, this creates a
+     * stream socket. If the stream argument is {@code false}, it
+     * creates a datagram socket.
+     * <p>
+     * If the application has specified a server socket factory, that
+     * factory's {@code createSocketImpl} method is called to create
+     * the actual socket implementation. Otherwise a "plain" socket is created.
+     * <p>
+     * If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with the host address and {@code port}
+     * as its arguments. This could result in a SecurityException.
+     * <p>
+     * If a UDP socket is used, TCP/IP related socket options will not apply.
+     *
+     * @param      host     the host name, or {@code null} for the loopback address.
+     * @param      port     the port number.
+     * @param      stream   a {@code boolean} indicating whether this is
+     *                      a stream socket or a datagram socket.
+     * @exception  IOException  if an I/O error occurs when creating the socket.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkConnect} method doesn't allow the operation.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
+     * @see        java.net.SocketImpl
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        SecurityManager#checkConnect
+     * @deprecated Use DatagramSocket instead for UDP transport.
+     */
+    @Deprecated
+    public Socket(String host, int port, boolean stream) throws IOException {
+        // Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+        this(InetAddress.getAllByName(host), port, (SocketAddress) null, stream);
+    }
+
+    /**
+     * Creates a socket and connects it to the specified port number at
+     * the specified IP address.
+     * <p>
+     * If the stream argument is {@code true}, this creates a
+     * stream socket. If the stream argument is {@code false}, it
+     * creates a datagram socket.
+     * <p>
+     * If the application has specified a server socket factory, that
+     * factory's {@code createSocketImpl} method is called to create
+     * the actual socket implementation. Otherwise a "plain" socket is created.
+     *
+     * <p>If there is a security manager, its
+     * {@code checkConnect} method is called
+     * with {@code host.getHostAddress()} and {@code port}
+     * as its arguments. This could result in a SecurityException.
+     * <p>
+     * If UDP socket is used, TCP/IP related socket options will not apply.
+     *
+     * @param      host     the IP address.
+     * @param      port      the port number.
+     * @param      stream    if {@code true}, create a stream socket;
+     *                       otherwise, create a datagram socket.
+     * @exception  IOException  if an I/O error occurs when creating the socket.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkConnect} method doesn't allow the operation.
+     * @exception  IllegalArgumentException if the port parameter is outside
+     *             the specified range of valid port values, which is between
+     *             0 and 65535, inclusive.
+     * @exception  NullPointerException if {@code host} is null.
+     * @see        java.net.Socket#setSocketImplFactory(java.net.SocketImplFactory)
+     * @see        java.net.SocketImpl
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        SecurityManager#checkConnect
+     * @deprecated Use DatagramSocket instead for UDP transport.
+     */
+    @Deprecated
+    public Socket(InetAddress host, int port, boolean stream) throws IOException {
+        // Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+        this(nonNullAddress(host), port, new InetSocketAddress(0), stream);
+    }
+
+    // BEGIN Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+    private static InetAddress[] nonNullAddress(InetAddress address) {
+        // backward compatibility
+        if (address == null)
+            throw new NullPointerException();
+
+        return new InetAddress[] { address };
+    }
+
+    private Socket(InetAddress[] addresses, int port, SocketAddress localAddr,
+            boolean stream) throws IOException {
+        if (addresses == null || addresses.length == 0) {
+            throw new SocketException("Impossible: empty address list");
+        }
+
+        for (int i = 0; i < addresses.length; i++) {
+            setImpl();
+            try {
+                InetSocketAddress address = new InetSocketAddress(addresses[i], port);
+                createImpl(stream);
+                if (localAddr != null) {
+                    bind(localAddr);
+                }
+                connect(address);
+                break;
+            } catch (IOException | IllegalArgumentException | SecurityException e) {
+                try {
+                    // Android-changed: Let ctor call impl.close() instead of overridable close().
+                    // Subclasses may not expect a call to close() coming from this constructor.
+                    impl.close();
+                    closed = true;
+                } catch (IOException ce) {
+                    e.addSuppressed(ce);
+                }
+
+                // Only stop on the last address.
+                if (i == addresses.length - 1) {
+                    throw e;
+                }
+            }
+
+            // Discard the connection state and try again.
+            impl = null;
+            created = false;
+            bound = false;
+            closed = false;
+        }
+    }
+    // END Android-changed: App compat. Socket ctor should try all addresses. http://b/30007735
+
+    /**
+     * Creates the socket implementation.
+     *
+     * @param stream a {@code boolean} value : {@code true} for a TCP socket,
+     *               {@code false} for UDP.
+     * @throws IOException if creation fails
+     * @since 1.4
+     */
+     void createImpl(boolean stream) throws SocketException {
+        if (impl == null)
+            setImpl();
+        try {
+            impl.create(stream);
+            created = true;
+        } catch (IOException e) {
+            throw new SocketException(e.getMessage());
+        }
+    }
+
+    private void checkOldImpl() {
+        if (impl == null)
+            return;
+        // SocketImpl.connect() is a protected method, therefore we need to use
+        // getDeclaredMethod, therefore we need permission to access the member
+
+        oldImpl = AccessController.doPrivileged
+                                (new PrivilegedAction<Boolean>() {
+            public Boolean run() {
+                Class<?> clazz = impl.getClass();
+                while (true) {
+                    try {
+                        clazz.getDeclaredMethod("connect", SocketAddress.class, int.class);
+                        return Boolean.FALSE;
+                    } catch (NoSuchMethodException e) {
+                        clazz = clazz.getSuperclass();
+                        // java.net.SocketImpl class will always have this abstract method.
+                        // If we have not found it by now in the hierarchy then it does not
+                        // exist, we are an old style impl.
+                        if (clazz.equals(java.net.SocketImpl.class)) {
+                            return Boolean.TRUE;
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Sets impl to the system-default type of SocketImpl.
+     * @since 1.4
+     */
+    void setImpl() {
+        if (factory != null) {
+            impl = factory.createSocketImpl();
+            checkOldImpl();
+        } else {
+            // No need to do a checkOldImpl() here, we know it's an up to date
+            // SocketImpl!
+            impl = new SocksSocketImpl();
+        }
+        if (impl != null)
+            impl.setSocket(this);
+    }
+
+
+    /**
+     * Get the {@code SocketImpl} attached to this socket, creating
+     * it if necessary.
+     *
+     * @return  the {@code SocketImpl} attached to that ServerSocket.
+     * @throws SocketException if creation fails
+     * @since 1.4
+     */
+    SocketImpl getImpl() throws SocketException {
+        if (!created)
+            createImpl(true);
+        return impl;
+    }
+
+    /**
+     * Connects this socket to the server.
+     *
+     * @param   endpoint the {@code SocketAddress}
+     * @throws  IOException if an error occurs during the connection
+     * @throws  java.nio.channels.IllegalBlockingModeException
+     *          if this socket has an associated channel,
+     *          and the channel is in non-blocking mode
+     * @throws  IllegalArgumentException if endpoint is null or is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public void connect(SocketAddress endpoint) throws IOException {
+        connect(endpoint, 0);
+    }
+
+    /**
+     * Connects this socket to the server with a specified timeout value.
+     * A timeout of zero is interpreted as an infinite timeout. The connection
+     * will then block until established or an error occurs.
+     *
+     * @param   endpoint the {@code SocketAddress}
+     * @param   timeout  the timeout value to be used in milliseconds.
+     * @throws  IOException if an error occurs during the connection
+     * @throws  SocketTimeoutException if timeout expires before connecting
+     * @throws  java.nio.channels.IllegalBlockingModeException
+     *          if this socket has an associated channel,
+     *          and the channel is in non-blocking mode
+     * @throws  IllegalArgumentException if endpoint is null or is a
+     *          SocketAddress subclass not supported by this socket
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public void connect(SocketAddress endpoint, int timeout) throws IOException {
+        if (endpoint == null)
+            throw new IllegalArgumentException("connect: The address can't be null");
+
+        if (timeout < 0)
+          throw new IllegalArgumentException("connect: timeout can't be negative");
+
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+
+        if (!oldImpl && isConnected())
+            throw new SocketException("already connected");
+
+        if (!(endpoint instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+
+        InetSocketAddress epoint = (InetSocketAddress) endpoint;
+        InetAddress addr = epoint.getAddress ();
+        int port = epoint.getPort();
+        checkAddress(addr, "connect");
+
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            if (epoint.isUnresolved())
+                security.checkConnect(epoint.getHostName(), port);
+            else
+                security.checkConnect(addr.getHostAddress(), port);
+        }
+        if (!created)
+            createImpl(true);
+        if (!oldImpl)
+            impl.connect(epoint, timeout);
+        else if (timeout == 0) {
+            if (epoint.isUnresolved())
+                impl.connect(addr.getHostName(), port);
+            else
+                impl.connect(addr, port);
+        } else
+            throw new UnsupportedOperationException("SocketImpl.connect(addr, timeout)");
+        connected = true;
+        /*
+         * If the socket was not bound before the connect, it is now because
+         * the kernel will have picked an ephemeral port & a local address
+         */
+        bound = true;
+    }
+
+    /**
+     * Binds the socket to a local address.
+     * <P>
+     * If the address is {@code null}, then the system will pick up
+     * an ephemeral port and a valid local address to bind the socket.
+     *
+     * @param   bindpoint the {@code SocketAddress} to bind to
+     * @throws  IOException if the bind operation fails, or if the socket
+     *                     is already bound.
+     * @throws  IllegalArgumentException if bindpoint is a
+     *          SocketAddress subclass not supported by this socket
+     * @throws  SecurityException  if a security manager exists and its
+     *          {@code checkListen} method doesn't allow the bind
+     *          to the local port.
+     *
+     * @since   1.4
+     * @see #isBound
+     */
+    public void bind(SocketAddress bindpoint) throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!oldImpl && isBound())
+            throw new SocketException("Already bound");
+
+        if (bindpoint != null && (!(bindpoint instanceof InetSocketAddress)))
+            throw new IllegalArgumentException("Unsupported address type");
+        InetSocketAddress epoint = (InetSocketAddress) bindpoint;
+        if (epoint != null && epoint.isUnresolved())
+            throw new SocketException("Unresolved address");
+        if (epoint == null) {
+            epoint = new InetSocketAddress(0);
+        }
+        InetAddress addr = epoint.getAddress();
+        int port = epoint.getPort();
+        checkAddress (addr, "bind");
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkListen(port);
+        }
+        getImpl().bind (addr, port);
+        bound = true;
+    }
+
+    private void checkAddress (InetAddress addr, String op) {
+        if (addr == null) {
+            return;
+        }
+        if (!(addr instanceof Inet4Address || addr instanceof Inet6Address)) {
+            throw new IllegalArgumentException(op + ": invalid address type");
+        }
+    }
+
+    /**
+     * set the flags after an accept() call.
+     */
+    final void postAccept() {
+        connected = true;
+        created = true;
+        bound = true;
+    }
+
+    void setCreated() {
+        created = true;
+    }
+
+    void setBound() {
+        bound = true;
+    }
+
+    void setConnected() {
+        connected = true;
+    }
+
+    /**
+     * Returns the address to which the socket is connected.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return the connected address
+     * after the socket is closed.
+     *
+     * @return  the remote IP address to which this socket is connected,
+     *          or {@code null} if the socket is not connected.
+     */
+    public InetAddress getInetAddress() {
+        if (!isConnected())
+            return null;
+        try {
+            return getImpl().getInetAddress();
+        } catch (SocketException e) {
+        }
+        return null;
+    }
+
+    /**
+     * Gets the local address to which the socket is bound.
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * the {@link InetAddress#getLoopbackAddress loopback} address is returned.
+     *
+     * @return the local address to which the socket is bound,
+     *         the loopback address if denied by the security manager, or
+     *         the wildcard address if the socket is closed or not bound yet.
+     * @since   JDK1.1
+     *
+     * @see SecurityManager#checkConnect
+     */
+    public InetAddress getLocalAddress() {
+        // This is for backward compatibility
+        if (!isBound())
+            return InetAddress.anyLocalAddress();
+        InetAddress in = null;
+        try {
+            in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR);
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkConnect(in.getHostAddress(), -1);
+            if (in.isAnyLocalAddress()) {
+                in = InetAddress.anyLocalAddress();
+            }
+        } catch (SecurityException e) {
+            in = InetAddress.getLoopbackAddress();
+        } catch (Exception e) {
+            in = InetAddress.anyLocalAddress(); // "0.0.0.0"
+        }
+        return in;
+    }
+
+    /**
+     * Returns the remote port number to which this socket is connected.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return the connected port number
+     * after the socket is closed.
+     *
+     * @return  the remote port number to which this socket is connected, or
+     *          0 if the socket is not connected yet.
+     */
+    public int getPort() {
+        if (!isConnected())
+            return 0;
+        try {
+            return getImpl().getPort();
+        } catch (SocketException e) {
+            // Shouldn't happen as we're connected
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the local port number to which this socket is bound.
+     * <p>
+     * If the socket was bound prior to being {@link #close closed},
+     * then this method will continue to return the local port number
+     * after the socket is closed.
+     *
+     * @return  the local port number to which this socket is bound or -1
+     *          if the socket is not bound yet.
+     */
+    public int getLocalPort() {
+        if (!isBound())
+            return -1;
+        try {
+            return getImpl().getLocalPort();
+        } catch(SocketException e) {
+            // shouldn't happen as we're bound
+        }
+        return -1;
+    }
+
+    /**
+     * Returns the address of the endpoint this socket is connected to, or
+     * {@code null} if it is unconnected.
+     * <p>
+     * If the socket was connected prior to being {@link #close closed},
+     * then this method will continue to return the connected address
+     * after the socket is closed.
+     *
+
+     * @return a {@code SocketAddress} representing the remote endpoint of this
+     *         socket, or {@code null} if it is not connected yet.
+     * @see #getInetAddress()
+     * @see #getPort()
+     * @see #connect(SocketAddress, int)
+     * @see #connect(SocketAddress)
+     * @since 1.4
+     */
+    public SocketAddress getRemoteSocketAddress() {
+        if (!isConnected())
+            return null;
+        return new InetSocketAddress(getInetAddress(), getPort());
+    }
+
+    /**
+     * Returns the address of the endpoint this socket is bound to.
+     * <p>
+     * If a socket bound to an endpoint represented by an
+     * {@code InetSocketAddress } is {@link #close closed},
+     * then this method will continue to return an {@code InetSocketAddress}
+     * after the socket is closed. In that case the returned
+     * {@code InetSocketAddress}'s address is the
+     * {@link InetAddress#isAnyLocalAddress wildcard} address
+     * and its port is the local port that it was bound to.
+     * <p>
+     * If there is a security manager set, its {@code checkConnect} method is
+     * called with the local address and {@code -1} as its arguments to see
+     * if the operation is allowed. If the operation is not allowed,
+     * a {@code SocketAddress} representing the
+     * {@link InetAddress#getLoopbackAddress loopback} address and the local
+     * port to which this socket is bound is returned.
+     *
+     * @return a {@code SocketAddress} representing the local endpoint of
+     *         this socket, or a {@code SocketAddress} representing the
+     *         loopback address if denied by the security manager, or
+     *         {@code null} if the socket is not bound yet.
+     *
+     * @see #getLocalAddress()
+     * @see #getLocalPort()
+     * @see #bind(SocketAddress)
+     * @see SecurityManager#checkConnect
+     * @since 1.4
+     */
+
+    public SocketAddress getLocalSocketAddress() {
+        if (!isBound())
+            return null;
+        return new InetSocketAddress(getLocalAddress(), getLocalPort());
+    }
+
+    /**
+     * Returns the unique {@link java.nio.channels.SocketChannel SocketChannel}
+     * object associated with this socket, if any.
+     *
+     * <p> A socket will have a channel if, and only if, the channel itself was
+     * created via the {@link java.nio.channels.SocketChannel#open
+     * SocketChannel.open} or {@link
+     * java.nio.channels.ServerSocketChannel#accept ServerSocketChannel.accept}
+     * methods.
+     *
+     * @return  the socket channel associated with this socket,
+     *          or {@code null} if this socket was not created
+     *          for a channel
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public SocketChannel getChannel() {
+        return null;
+    }
+
+    /**
+     * Returns an input stream for this socket.
+     *
+     * <p> If this socket has an associated channel then the resulting input
+     * stream delegates all of its operations to the channel.  If the channel
+     * is in non-blocking mode then the input stream's {@code read} operations
+     * will throw an {@link java.nio.channels.IllegalBlockingModeException}.
+     *
+     * <p>Under abnormal conditions the underlying connection may be
+     * broken by the remote host or the network software (for example
+     * a connection reset in the case of TCP connections). When a
+     * broken connection is detected by the network software the
+     * following applies to the returned input stream :-
+     *
+     * <ul>
+     *
+     *   <li><p>The network software may discard bytes that are buffered
+     *   by the socket. Bytes that aren't discarded by the network
+     *   software can be read using {@link java.io.InputStream#read read}.
+     *
+     *   <li><p>If there are no bytes buffered on the socket, or all
+     *   buffered bytes have been consumed by
+     *   {@link java.io.InputStream#read read}, then all subsequent
+     *   calls to {@link java.io.InputStream#read read} will throw an
+     *   {@link java.io.IOException IOException}.
+     *
+     *   <li><p>If there are no bytes buffered on the socket, and the
+     *   socket has not been closed using {@link #close close}, then
+     *   {@link java.io.InputStream#available available} will
+     *   return {@code 0}.
+     *
+     * </ul>
+     *
+     * <p> Closing the returned {@link java.io.InputStream InputStream}
+     * will close the associated socket.
+     *
+     * @return     an input stream for reading bytes from this socket.
+     * @exception  IOException  if an I/O error occurs when creating the
+     *             input stream, the socket is closed, the socket is
+     *             not connected, or the socket input has been shutdown
+     *             using {@link #shutdownInput()}
+     *
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public InputStream getInputStream() throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!isConnected())
+            throw new SocketException("Socket is not connected");
+        if (isInputShutdown())
+            throw new SocketException("Socket input is shutdown");
+        final Socket s = this;
+        InputStream is = null;
+        try {
+            is = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<InputStream>() {
+                    public InputStream run() throws IOException {
+                        return impl.getInputStream();
+                    }
+                });
+        } catch (java.security.PrivilegedActionException e) {
+            throw (IOException) e.getException();
+        }
+        return is;
+    }
+
+    /**
+     * Returns an output stream for this socket.
+     *
+     * <p> If this socket has an associated channel then the resulting output
+     * stream delegates all of its operations to the channel.  If the channel
+     * is in non-blocking mode then the output stream's {@code write}
+     * operations will throw an {@link
+     * java.nio.channels.IllegalBlockingModeException}.
+     *
+     * <p> Closing the returned {@link java.io.OutputStream OutputStream}
+     * will close the associated socket.
+     *
+     * @return     an output stream for writing bytes to this socket.
+     * @exception  IOException  if an I/O error occurs when creating the
+     *               output stream or if the socket is not connected.
+     * @revised 1.4
+     * @spec JSR-51
+     */
+    public OutputStream getOutputStream() throws IOException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!isConnected())
+            throw new SocketException("Socket is not connected");
+        if (isOutputShutdown())
+            throw new SocketException("Socket output is shutdown");
+        final Socket s = this;
+        OutputStream os = null;
+        try {
+            os = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<OutputStream>() {
+                    public OutputStream run() throws IOException {
+                        return impl.getOutputStream();
+                    }
+                });
+        } catch (java.security.PrivilegedActionException e) {
+            throw (IOException) e.getException();
+        }
+        return os;
+    }
+
+    /**
+     * Enable/disable {@link SocketOptions#TCP_NODELAY TCP_NODELAY}
+     * (disable/enable Nagle's algorithm).
+     *
+     * @param on {@code true} to enable TCP_NODELAY,
+     * {@code false} to disable.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @since   JDK1.1
+     *
+     * @see #getTcpNoDelay()
+     */
+    public void setTcpNoDelay(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.TCP_NODELAY, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if {@link SocketOptions#TCP_NODELAY TCP_NODELAY} is enabled.
+     *
+     * @return a {@code boolean} indicating whether or not
+     *         {@link SocketOptions#TCP_NODELAY TCP_NODELAY} is enabled.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   JDK1.1
+     * @see #setTcpNoDelay(boolean)
+     */
+    public boolean getTcpNoDelay() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Boolean) getImpl().getOption(SocketOptions.TCP_NODELAY)).booleanValue();
+    }
+
+    /**
+     * Enable/disable {@link SocketOptions#SO_LINGER SO_LINGER} with the
+     * specified linger time in seconds. The maximum timeout value is platform
+     * specific.
+     *
+     * The setting only affects socket close.
+     *
+     * @param on     whether or not to linger on.
+     * @param linger how long to linger for, if on is true.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @exception IllegalArgumentException if the linger value is negative.
+     * @since JDK1.1
+     * @see #getSoLinger()
+     */
+    public void setSoLinger(boolean on, int linger) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!on) {
+            getImpl().setOption(SocketOptions.SO_LINGER, new Boolean(on));
+        } else {
+            if (linger < 0) {
+                throw new IllegalArgumentException("invalid value for SO_LINGER");
+            }
+            if (linger > 65535)
+                linger = 65535;
+            getImpl().setOption(SocketOptions.SO_LINGER, new Integer(linger));
+        }
+    }
+
+    /**
+     * Returns setting for {@link SocketOptions#SO_LINGER SO_LINGER}.
+     * -1 returns implies that the
+     * option is disabled.
+     *
+     * The setting only affects socket close.
+     *
+     * @return the setting for {@link SocketOptions#SO_LINGER SO_LINGER}.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   JDK1.1
+     * @see #setSoLinger(boolean, int)
+     */
+    public int getSoLinger() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        Object o = getImpl().getOption(SocketOptions.SO_LINGER);
+        if (o instanceof Integer) {
+            return ((Integer) o).intValue();
+        } else {
+            return -1;
+        }
+    }
+
+    /**
+     * Send one byte of urgent data on the socket. The byte to be sent is the lowest eight
+     * bits of the data parameter. The urgent byte is
+     * sent after any preceding writes to the socket OutputStream
+     * and before any future writes to the OutputStream.
+     * @param data The byte of data to send
+     * @exception IOException if there is an error
+     *  sending the data.
+     * @since 1.4
+     */
+    public void sendUrgentData (int data) throws IOException  {
+        // Android-changed: If the socket is closed, sendUrgentData should not create a new impl.
+        // Fail early to avoid leaking resources.
+        // http://b/31818400
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+
+        if (!getImpl().supportsUrgentData ()) {
+            throw new SocketException ("Urgent data not supported");
+        }
+        getImpl().sendUrgentData (data);
+    }
+
+    /**
+     * Enable/disable {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE}
+     * (receipt of TCP urgent data)
+     *
+     * By default, this option is disabled and TCP urgent data received on a
+     * socket is silently discarded. If the user wishes to receive urgent data, then
+     * this option must be enabled. When enabled, urgent data is received
+     * inline with normal data.
+     * <p>
+     * Note, only limited support is provided for handling incoming urgent
+     * data. In particular, no notification of incoming urgent data is provided
+     * and there is no capability to distinguish between normal data and urgent
+     * data unless provided by a higher level protocol.
+     *
+     * @param on {@code true} to enable
+     *           {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE},
+     *           {@code false} to disable.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @since   1.4
+     *
+     * @see #getOOBInline()
+     */
+    public void setOOBInline(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_OOBINLINE, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE} is enabled.
+     *
+     * @return a {@code boolean} indicating whether or not
+     *         {@link SocketOptions#SO_OOBINLINE SO_OOBINLINE}is enabled.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   1.4
+     * @see #setOOBInline(boolean)
+     */
+    public boolean getOOBInline() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Boolean) getImpl().getOption(SocketOptions.SO_OOBINLINE)).booleanValue();
+    }
+
+    /**
+     *  Enable/disable {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}
+     *  with the specified timeout, in milliseconds. With this option set
+     *  to a non-zero timeout, a read() call on the InputStream associated with
+     *  this Socket will block for only this amount of time.  If the timeout
+     *  expires, a <B>java.net.SocketTimeoutException</B> is raised, though the
+     *  Socket is still valid. The option <B>must</B> be enabled
+     *  prior to entering the blocking operation to have effect. The
+     *  timeout must be {@code > 0}.
+     *  A timeout of zero is interpreted as an infinite timeout.
+     *
+     * @param timeout the specified timeout, in milliseconds.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   JDK 1.1
+     * @see #getSoTimeout()
+     */
+    public synchronized void setSoTimeout(int timeout) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (timeout < 0)
+          throw new IllegalArgumentException("timeout can't be negative");
+
+        getImpl().setOption(SocketOptions.SO_TIMEOUT, new Integer(timeout));
+    }
+
+    /**
+     * Returns setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}.
+     * 0 returns implies that the option is disabled (i.e., timeout of infinity).
+     *
+     * @return the setting for {@link SocketOptions#SO_TIMEOUT SO_TIMEOUT}
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @since   JDK1.1
+     * @see #setSoTimeout(int)
+     */
+    public synchronized int getSoTimeout() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        Object o = getImpl().getOption(SocketOptions.SO_TIMEOUT);
+        /* extra type safety */
+        if (o instanceof Integer) {
+            return ((Integer) o).intValue();
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Sets the {@link SocketOptions#SO_SNDBUF SO_SNDBUF} option to the
+     * specified value for this {@code Socket}.
+     * The {@link SocketOptions#SO_SNDBUF SO_SNDBUF} option is used by the
+     * platform's networking code as a hint for the size to set the underlying
+     * network I/O buffers.
+     *
+     * <p>Because {@link SocketOptions#SO_SNDBUF SO_SNDBUF} is a hint,
+     * applications that want to verify what size the buffers were set to
+     * should call {@link #getSendBufferSize()}.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @param size the size to which to set the send buffer
+     * size. This value must be greater than 0.
+     *
+     * @exception IllegalArgumentException if the
+     * value is 0 or is negative.
+     *
+     * @see #getSendBufferSize()
+     * @since 1.2
+     */
+    public synchronized void setSendBufferSize(int size)
+    throws SocketException{
+        if (!(size > 0)) {
+            throw new IllegalArgumentException("negative send size");
+        }
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_SNDBUF, new Integer(size));
+    }
+
+    /**
+     * Get value of the {@link SocketOptions#SO_SNDBUF SO_SNDBUF} option
+     * for this {@code Socket}, that is the buffer size used by the platform
+     * for output on this {@code Socket}.
+     * @return the value of the {@link SocketOptions#SO_SNDBUF SO_SNDBUF}
+     *         option for this {@code Socket}.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @see #setSendBufferSize(int)
+     * @since 1.2
+     */
+    public synchronized int getSendBufferSize() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        int result = 0;
+        Object o = getImpl().getOption(SocketOptions.SO_SNDBUF);
+        if (o instanceof Integer) {
+            result = ((Integer)o).intValue();
+        }
+        return result;
+    }
+
+    /**
+     * Sets the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option to the
+     * specified value for this {@code Socket}. The
+     * {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option is
+     * used by the platform's networking code as a hint for the size to set
+     * the underlying network I/O buffers.
+     *
+     * <p>Increasing the receive buffer size can increase the performance of
+     * network I/O for high-volume connection, while decreasing it can
+     * help reduce the backlog of incoming data.
+     *
+     * <p>Because {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is a hint,
+     * applications that want to verify what size the buffers were set to
+     * should call {@link #getReceiveBufferSize()}.
+     *
+     * <p>The value of {@link SocketOptions#SO_RCVBUF SO_RCVBUF} is also used
+     * to set the TCP receive window that is advertized to the remote peer.
+     * Generally, the window size can be modified at any time when a socket is
+     * connected. However, if a receive window larger than 64K is required then
+     * this must be requested <B>before</B> the socket is connected to the
+     * remote peer. There are two cases to be aware of:
+     * <ol>
+     * <li>For sockets accepted from a ServerSocket, this must be done by calling
+     * {@link ServerSocket#setReceiveBufferSize(int)} before the ServerSocket
+     * is bound to a local address.<p></li>
+     * <li>For client sockets, setReceiveBufferSize() must be called before
+     * connecting the socket to its remote peer.</li></ol>
+     * @param size the size to which to set the receive buffer
+     * size. This value must be greater than 0.
+     *
+     * @exception IllegalArgumentException if the value is 0 or is
+     * negative.
+     *
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     *
+     * @see #getReceiveBufferSize()
+     * @see ServerSocket#setReceiveBufferSize(int)
+     * @since 1.2
+     */
+    public synchronized void setReceiveBufferSize(int size)
+    throws SocketException{
+        if (size <= 0) {
+            throw new IllegalArgumentException("invalid receive size");
+        }
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_RCVBUF, new Integer(size));
+    }
+
+    /**
+     * Gets the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF} option
+     * for this {@code Socket}, that is the buffer size used by the platform
+     * for input on this {@code Socket}.
+     *
+     * @return the value of the {@link SocketOptions#SO_RCVBUF SO_RCVBUF}
+     *         option for this {@code Socket}.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @see #setReceiveBufferSize(int)
+     * @since 1.2
+     */
+    public synchronized int getReceiveBufferSize()
+    throws SocketException{
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        int result = 0;
+        Object o = getImpl().getOption(SocketOptions.SO_RCVBUF);
+        if (o instanceof Integer) {
+            result = ((Integer)o).intValue();
+        }
+        return result;
+    }
+
+    /**
+     * Enable/disable {@link SocketOptions#SO_KEEPALIVE SO_KEEPALIVE}.
+     *
+     * @param on  whether or not to have socket keep alive turned on.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since 1.3
+     * @see #getKeepAlive()
+     */
+    public void setKeepAlive(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_KEEPALIVE, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if {@link SocketOptions#SO_KEEPALIVE SO_KEEPALIVE} is enabled.
+     *
+     * @return a {@code boolean} indicating whether or not
+     *         {@link SocketOptions#SO_KEEPALIVE SO_KEEPALIVE} is enabled.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   1.3
+     * @see #setKeepAlive(boolean)
+     */
+    public boolean getKeepAlive() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Boolean) getImpl().getOption(SocketOptions.SO_KEEPALIVE)).booleanValue();
+    }
+
+    /**
+     * Sets traffic class or type-of-service octet in the IP
+     * header for packets sent from this Socket.
+     * As the underlying network implementation may ignore this
+     * value applications should consider it a hint.
+     *
+     * <P> The tc <B>must</B> be in the range {@code 0 <= tc <=
+     * 255} or an IllegalArgumentException will be thrown.
+     * <p>Notes:
+     * <p>For Internet Protocol v4 the value consists of an
+     * {@code integer}, the least significant 8 bits of which
+     * represent the value of the TOS octet in IP packets sent by
+     * the socket.
+     * RFC 1349 defines the TOS values as follows:
+     *
+     * <UL>
+     * <LI><CODE>IPTOS_LOWCOST (0x02)</CODE></LI>
+     * <LI><CODE>IPTOS_RELIABILITY (0x04)</CODE></LI>
+     * <LI><CODE>IPTOS_THROUGHPUT (0x08)</CODE></LI>
+     * <LI><CODE>IPTOS_LOWDELAY (0x10)</CODE></LI>
+     * </UL>
+     * The last low order bit is always ignored as this
+     * corresponds to the MBZ (must be zero) bit.
+     * <p>
+     * Setting bits in the precedence field may result in a
+     * SocketException indicating that the operation is not
+     * permitted.
+     * <p>
+     * As RFC 1122 section 4.2.4.2 indicates, a compliant TCP
+     * implementation should, but is not required to, let application
+     * change the TOS field during the lifetime of a connection.
+     * So whether the type-of-service field can be changed after the
+     * TCP connection has been established depends on the implementation
+     * in the underlying platform. Applications should not assume that
+     * they can change the TOS field after the connection.
+     * <p>
+     * For Internet Protocol v6 {@code tc} is the value that
+     * would be placed into the sin6_flowinfo field of the IP header.
+     *
+     * @param tc        an {@code int} value for the bitset.
+     * @throws SocketException if there is an error setting the
+     * traffic class or type-of-service
+     * @since 1.4
+     * @see #getTrafficClass
+     * @see SocketOptions#IP_TOS
+     */
+    public void setTrafficClass(int tc) throws SocketException {
+        if (tc < 0 || tc > 255)
+            throw new IllegalArgumentException("tc is not in range 0 -- 255");
+
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        try {
+            getImpl().setOption(SocketOptions.IP_TOS, tc);
+        } catch (SocketException se) {
+            // not supported if socket already connected
+            // Solaris returns error in such cases
+            if(!isConnected())
+                throw se;
+        }
+    }
+
+    /**
+     * Gets traffic class or type-of-service in the IP header
+     * for packets sent from this Socket
+     * <p>
+     * As the underlying network implementation may ignore the
+     * traffic class or type-of-service set using {@link #setTrafficClass(int)}
+     * this method may return a different value than was previously
+     * set using the {@link #setTrafficClass(int)} method on this Socket.
+     *
+     * @return the traffic class or type-of-service already set
+     * @throws SocketException if there is an error obtaining the
+     * traffic class or type-of-service value.
+     * @since 1.4
+     * @see #setTrafficClass(int)
+     * @see SocketOptions#IP_TOS
+     */
+    public int getTrafficClass() throws SocketException {
+        // Android-changed: throw SocketException if the socket is already closed. http://b/31818400
+        if (isClosed()) {
+            throw new SocketException("Socket is closed");
+        }
+
+        return ((Integer) (getImpl().getOption(SocketOptions.IP_TOS))).intValue();
+    }
+
+    /**
+     * Enable/disable the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     * socket option.
+     * <p>
+     * When a TCP connection is closed the connection may remain
+     * in a timeout state for a period of time after the connection
+     * is closed (typically known as the {@code TIME_WAIT} state
+     * or {@code 2MSL} wait state).
+     * For applications using a well known socket address or port
+     * it may not be possible to bind a socket to the required
+     * {@code SocketAddress} if there is a connection in the
+     * timeout state involving the socket address or port.
+     * <p>
+     * Enabling {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     * prior to binding the socket using {@link #bind(SocketAddress)} allows
+     * the socket to be bound even though a previous connection is in a timeout
+     * state.
+     * <p>
+     * When a {@code Socket} is created the initial setting
+     * of {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is disabled.
+     * <p>
+     * The behaviour when {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is
+     * enabled or disabled after a socket is bound (See {@link #isBound()})
+     * is not defined.
+     *
+     * @param on  whether to enable or disable the socket option
+     * @exception SocketException if an error occurs enabling or
+     *            disabling the {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR}
+     *            socket option, or the socket is closed.
+     * @since 1.4
+     * @see #getReuseAddress()
+     * @see #bind(SocketAddress)
+     * @see #isClosed()
+     * @see #isBound()
+     */
+    public void setReuseAddress(boolean on) throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        getImpl().setOption(SocketOptions.SO_REUSEADDR, Boolean.valueOf(on));
+    }
+
+    /**
+     * Tests if {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
+     *
+     * @return a {@code boolean} indicating whether or not
+     *         {@link SocketOptions#SO_REUSEADDR SO_REUSEADDR} is enabled.
+     * @exception SocketException if there is an error
+     * in the underlying protocol, such as a TCP error.
+     * @since   1.4
+     * @see #setReuseAddress(boolean)
+     */
+    public boolean getReuseAddress() throws SocketException {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue();
+    }
+
+    /**
+     * Closes this socket.
+     * <p>
+     * Any thread currently blocked in an I/O operation upon this socket
+     * will throw a {@link SocketException}.
+     * <p>
+     * Once a socket has been closed, it is not available for further networking
+     * use (i.e. can't be reconnected or rebound). A new socket needs to be
+     * created.
+     *
+     * <p> Closing this socket will also close the socket's
+     * {@link java.io.InputStream InputStream} and
+     * {@link java.io.OutputStream OutputStream}.
+     *
+     * <p> If this socket has an associated channel then the channel is closed
+     * as well.
+     *
+     * @exception  IOException  if an I/O error occurs when closing this socket.
+     * @revised 1.4
+     * @spec JSR-51
+     * @see #isClosed
+     */
+    public synchronized void close() throws IOException {
+        synchronized(closeLock) {
+            if (isClosed())
+                return;
+            if (created)
+                impl.close();
+            closed = true;
+        }
+    }
+
+    /**
+     * Places the input stream for this socket at "end of stream".
+     * Any data sent to the input stream side of the socket is acknowledged
+     * and then silently discarded.
+     * <p>
+     * If you read from a socket input stream after invoking this method on the
+     * socket, the stream's {@code available} method will return 0, and its
+     * {@code read} methods will return {@code -1} (end of stream).
+     *
+     * @exception IOException if an I/O error occurs when shutting down this
+     * socket.
+     *
+     * @since 1.3
+     * @see java.net.Socket#shutdownOutput()
+     * @see java.net.Socket#close()
+     * @see java.net.Socket#setSoLinger(boolean, int)
+     * @see #isInputShutdown
+     */
+    public void shutdownInput() throws IOException
+    {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!isConnected())
+            throw new SocketException("Socket is not connected");
+        if (isInputShutdown())
+            throw new SocketException("Socket input is already shutdown");
+        getImpl().shutdownInput();
+        shutIn = true;
+    }
+
+    /**
+     * Disables the output stream for this socket.
+     * For a TCP socket, any previously written data will be sent
+     * followed by TCP's normal connection termination sequence.
+     *
+     * If you write to a socket output stream after invoking
+     * shutdownOutput() on the socket, the stream will throw
+     * an IOException.
+     *
+     * @exception IOException if an I/O error occurs when shutting down this
+     * socket.
+     *
+     * @since 1.3
+     * @see java.net.Socket#shutdownInput()
+     * @see java.net.Socket#close()
+     * @see java.net.Socket#setSoLinger(boolean, int)
+     * @see #isOutputShutdown
+     */
+    public void shutdownOutput() throws IOException
+    {
+        if (isClosed())
+            throw new SocketException("Socket is closed");
+        if (!isConnected())
+            throw new SocketException("Socket is not connected");
+        if (isOutputShutdown())
+            throw new SocketException("Socket output is already shutdown");
+        getImpl().shutdownOutput();
+        shutOut = true;
+    }
+
+    /**
+     * Converts this socket to a {@code String}.
+     *
+     * @return  a string representation of this socket.
+     */
+    public String toString() {
+        try {
+            // Android-changed: change localport to localPort, and addr to address.
+            if (isConnected())
+                return "Socket[address=" + getImpl().getInetAddress() +
+                    ",port=" + getImpl().getPort() +
+                    ",localPort=" + getImpl().getLocalPort() + "]";
+        } catch (SocketException e) {
+        }
+        return "Socket[unconnected]";
+    }
+
+    /**
+     * Returns the connection state of the socket.
+     * <p>
+     * Note: Closing a socket doesn't clear its connection state, which means
+     * this method will return {@code true} for a closed socket
+     * (see {@link #isClosed()}) if it was successfuly connected prior
+     * to being closed.
+     *
+     * @return true if the socket was successfuly connected to a server
+     * @since 1.4
+     */
+    public boolean isConnected() {
+        // Before 1.3 Sockets were always connected during creation
+        return connected || oldImpl;
+    }
+
+    /**
+     * Returns the binding state of the socket.
+     * <p>
+     * Note: Closing a socket doesn't clear its binding state, which means
+     * this method will return {@code true} for a closed socket
+     * (see {@link #isClosed()}) if it was successfuly bound prior
+     * to being closed.
+     *
+     * @return true if the socket was successfuly bound to an address
+     * @since 1.4
+     * @see #bind
+     */
+    public boolean isBound() {
+        // Before 1.3 Sockets were always bound during creation
+        return bound || oldImpl;
+    }
+
+    /**
+     * Returns the closed state of the socket.
+     *
+     * @return true if the socket has been closed
+     * @since 1.4
+     * @see #close
+     */
+    public boolean isClosed() {
+        synchronized(closeLock) {
+            return closed;
+        }
+    }
+
+    /**
+     * Returns whether the read-half of the socket connection is closed.
+     *
+     * @return true if the input of the socket has been shutdown
+     * @since 1.4
+     * @see #shutdownInput
+     */
+    public boolean isInputShutdown() {
+        return shutIn;
+    }
+
+    /**
+     * Returns whether the write-half of the socket connection is closed.
+     *
+     * @return true if the output of the socket has been shutdown
+     * @since 1.4
+     * @see #shutdownOutput
+     */
+    public boolean isOutputShutdown() {
+        return shutOut;
+    }
+
+    /**
+     * The factory for all client sockets.
+     */
+    private static SocketImplFactory factory = null;
+
+    /**
+     * Sets the client socket implementation factory for the
+     * application. The factory can be specified only once.
+     * <p>
+     * When an application creates a new client socket, the socket
+     * implementation factory's {@code createSocketImpl} method is
+     * called to create the actual socket implementation.
+     * <p>
+     * Passing {@code null} to the method is a no-op unless the factory
+     * was already set.
+     * <p>If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param      fac   the desired factory.
+     * @exception  IOException  if an I/O error occurs when setting the
+     *               socket factory.
+     * @exception  SocketException  if the factory is already defined.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't allow the operation.
+     * @see        java.net.SocketImplFactory#createSocketImpl()
+     * @see        SecurityManager#checkSetFactory
+     */
+    public static synchronized void setSocketImplFactory(SocketImplFactory fac)
+        throws IOException
+    {
+        if (factory != null) {
+            throw new SocketException("factory already defined");
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSetFactory();
+        }
+        factory = fac;
+    }
+
+    /**
+     * Sets performance preferences for this socket.
+     *
+     * <p> Sockets use the TCP/IP protocol by default.  Some implementations
+     * may offer alternative protocols which have different performance
+     * characteristics than TCP/IP.  This method allows the application to
+     * express its own preferences as to how these tradeoffs should be made
+     * when the implementation chooses from the available protocols.
+     *
+     * <p> Performance preferences are described by three integers
+     * whose values indicate the relative importance of short connection time,
+     * low latency, and high bandwidth.  The absolute values of the integers
+     * are irrelevant; in order to choose a protocol the values are simply
+     * compared, with larger values indicating stronger preferences. Negative
+     * values represent a lower priority than positive values. If the
+     * application prefers short connection time over both low latency and high
+     * bandwidth, for example, then it could invoke this method with the values
+     * {@code (1, 0, 0)}.  If the application prefers high bandwidth above low
+     * latency, and low latency above short connection time, then it could
+     * invoke this method with the values {@code (0, 1, 2)}.
+     *
+     * <p> Invoking this method after this socket has been connected
+     * will have no effect.
+     *
+     * @param  connectionTime
+     *         An {@code int} expressing the relative importance of a short
+     *         connection time
+     *
+     * @param  latency
+     *         An {@code int} expressing the relative importance of low
+     *         latency
+     *
+     * @param  bandwidth
+     *         An {@code int} expressing the relative importance of high
+     *         bandwidth
+     *
+     * @since 1.5
+     */
+    public void setPerformancePreferences(int connectionTime,
+                                          int latency,
+                                          int bandwidth)
+    {
+        /* Not implemented yet */
+    }
+
+    // Android-added: getFileDescriptor$() method for testing and internal use.
+    /**
+     * @hide internal use only
+     */
+    public FileDescriptor getFileDescriptor$() {
+        return impl.getFileDescriptor();
+    }
+}
diff --git a/java/net/SocketAddress.java b/java/net/SocketAddress.java
new file mode 100644
index 0000000..cfb014b
--- /dev/null
+++ b/java/net/SocketAddress.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+
+/**
+ *
+ * This class represents a Socket Address with no protocol attachment.
+ * As an abstract class, it is meant to be subclassed with a specific,
+ * protocol dependent, implementation.
+ * <p>
+ * It provides an immutable object used by sockets for binding, connecting, or
+ * as returned values.
+ *
+ * @see java.net.Socket
+ * @see java.net.ServerSocket
+ * @since 1.4
+ */
+public abstract class SocketAddress implements java.io.Serializable {
+
+    static final long serialVersionUID = 5215720748342549866L;
+
+}
diff --git a/java/net/SocketException.java b/java/net/SocketException.java
new file mode 100644
index 0000000..64ae771
--- /dev/null
+++ b/java/net/SocketException.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Thrown to indicate that there is an error creating or accessing a Socket.
+ *
+ * @author  Jonathan Payne
+ * @since   JDK1.0
+ */
+public
+class SocketException extends IOException {
+    private static final long serialVersionUID = -5935874303556886934L;
+
+    /**
+     * Constructs a new {@code SocketException} with the
+     * specified detail message.
+     *
+     * @param msg the detail message.
+     */
+    public SocketException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Constructs a new {@code SocketException} with no detail message.
+     */
+    public SocketException() {
+    }
+
+    // BEGIN Android-added: SocketException ctor with cause for internal use.
+    /** @hide */
+    public SocketException(Throwable cause) {
+        super(cause);
+    }
+
+    /** @hide */
+    public SocketException(String msg, Throwable cause) {
+        super(msg, cause);
+    }
+    // END Android-added: SocketException ctor with cause for internal use.
+}
diff --git a/java/net/SocketImpl.annotated.java b/java/net/SocketImpl.annotated.java
new file mode 100644
index 0000000..2146d2f
--- /dev/null
+++ b/java/net/SocketImpl.annotated.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+
+package java.net;
+
+import java.io.IOException;
+
+@SuppressWarnings({"unchecked", "deprecation", "all"})
+public abstract class SocketImpl implements java.net.SocketOptions {
+
+public SocketImpl() { throw new RuntimeException("Stub!"); }
+
+protected abstract void create(boolean stream) throws java.io.IOException;
+
+protected abstract void connect(java.lang.String host, int port) throws java.io.IOException;
+
+protected abstract void connect(java.net.InetAddress address, int port) throws java.io.IOException;
+
+protected abstract void connect(java.net.SocketAddress address, int timeout) throws java.io.IOException;
+
+protected abstract void bind(java.net.InetAddress host, int port) throws java.io.IOException;
+
+protected abstract void listen(int backlog) throws java.io.IOException;
+
+protected abstract void accept(java.net.SocketImpl s) throws java.io.IOException;
+
+protected abstract java.io.InputStream getInputStream() throws java.io.IOException;
+
+protected abstract java.io.OutputStream getOutputStream() throws java.io.IOException;
+
+protected abstract int available() throws java.io.IOException;
+
+protected abstract void close() throws java.io.IOException;
+
+protected void shutdownInput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+protected void shutdownOutput() throws java.io.IOException { throw new RuntimeException("Stub!"); }
+
+protected java.io.FileDescriptor getFileDescriptor() { throw new RuntimeException("Stub!"); }
+
+@libcore.api.CorePlatformApi
+public java.io.FileDescriptor getFD$() { throw new RuntimeException("Stub!"); }
+
+protected java.net.InetAddress getInetAddress() { throw new RuntimeException("Stub!"); }
+
+protected int getPort() { throw new RuntimeException("Stub!"); }
+
+protected boolean supportsUrgentData() { throw new RuntimeException("Stub!"); }
+
+protected abstract void sendUrgentData(int data) throws java.io.IOException;
+
+protected int getLocalPort() { throw new RuntimeException("Stub!"); }
+
+public java.lang.String toString() { throw new RuntimeException("Stub!"); }
+
+protected void setPerformancePreferences(int connectionTime, int latency, int bandwidth) { throw new RuntimeException("Stub!"); }
+
+protected java.net.InetAddress address;
+
+protected java.io.FileDescriptor fd;
+
+protected int localport;
+
+protected int port;
+}
+
diff --git a/java/net/SocketImpl.java b/java/net/SocketImpl.java
new file mode 100644
index 0000000..ade2630
--- /dev/null
+++ b/java/net/SocketImpl.java
@@ -0,0 +1,407 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileDescriptor;
+
+/**
+ * The abstract class {@code SocketImpl} is a common superclass
+ * of all classes that actually implement sockets. It is used to
+ * create both client and server sockets.
+ * <p>
+ * A "plain" socket implements these methods exactly as
+ * described, without attempting to go through a firewall or proxy.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public abstract class SocketImpl implements SocketOptions {
+    /**
+     * The actual Socket object.
+     */
+    Socket socket = null;
+    ServerSocket serverSocket = null;
+
+    /**
+     * The file descriptor object for this socket.
+     */
+    protected FileDescriptor fd;
+
+    /**
+     * The IP address of the remote end of this socket.
+     */
+    protected InetAddress address;
+
+    /**
+     * The port number on the remote host to which this socket is connected.
+     */
+    protected int port;
+
+    /**
+     * The local port number to which this socket is connected.
+     */
+    protected int localport;
+
+    /**
+     * Creates either a stream or a datagram socket.
+     *
+     * @param      stream   if {@code true}, create a stream socket;
+     *                      otherwise, create a datagram socket.
+     * @exception  IOException  if an I/O error occurs while creating the
+     *               socket.
+     */
+    protected abstract void create(boolean stream) throws IOException;
+
+    /**
+     * Connects this socket to the specified port on the named host.
+     *
+     * @param      host   the name of the remote host.
+     * @param      port   the port number.
+     * @exception  IOException  if an I/O error occurs when connecting to the
+     *               remote host.
+     */
+    protected abstract void connect(String host, int port) throws IOException;
+
+    /**
+     * Connects this socket to the specified port number on the specified host.
+     *
+     * @param      address   the IP address of the remote host.
+     * @param      port      the port number.
+     * @exception  IOException  if an I/O error occurs when attempting a
+     *               connection.
+     */
+    protected abstract void connect(InetAddress address, int port) throws IOException;
+
+    /**
+     * Connects this socket to the specified port number on the specified host.
+     * A timeout of zero is interpreted as an infinite timeout. The connection
+     * will then block until established or an error occurs.
+     *
+     * @param      address   the Socket address of the remote host.
+     * @param     timeout  the timeout value, in milliseconds, or zero for no timeout.
+     * @exception  IOException  if an I/O error occurs when attempting a
+     *               connection.
+     * @since 1.4
+     */
+    protected abstract void connect(SocketAddress address, int timeout) throws IOException;
+
+    /**
+     * Binds this socket to the specified local IP address and port number.
+     *
+     * @param      host   an IP address that belongs to a local interface.
+     * @param      port   the port number.
+     * @exception  IOException  if an I/O error occurs when binding this socket.
+     */
+    protected abstract void bind(InetAddress host, int port) throws IOException;
+
+    /**
+     * Sets the maximum queue length for incoming connection indications
+     * (a request to connect) to the {@code count} argument. If a
+     * connection indication arrives when the queue is full, the
+     * connection is refused.
+     *
+     * @param      backlog   the maximum length of the queue.
+     * @exception  IOException  if an I/O error occurs when creating the queue.
+     */
+    protected abstract void listen(int backlog) throws IOException;
+
+    /**
+     * Accepts a connection.
+     *
+     * @param      s   the accepted connection.
+     * @exception  IOException  if an I/O error occurs when accepting the
+     *               connection.
+     */
+    protected abstract void accept(SocketImpl s) throws IOException;
+
+    /**
+     * Returns an input stream for this socket.
+     *
+     * @return     a stream for reading from this socket.
+     * @exception  IOException  if an I/O error occurs when creating the
+     *               input stream.
+    */
+    protected abstract InputStream getInputStream() throws IOException;
+
+    /**
+     * Returns an output stream for this socket.
+     *
+     * @return     an output stream for writing to this socket.
+     * @exception  IOException  if an I/O error occurs when creating the
+     *               output stream.
+     */
+    protected abstract OutputStream getOutputStream() throws IOException;
+
+    /**
+     * Returns the number of bytes that can be read from this socket
+     * without blocking.
+     *
+     * @return     the number of bytes that can be read from this socket
+     *             without blocking.
+     * @exception  IOException  if an I/O error occurs when determining the
+     *               number of bytes available.
+     */
+    protected abstract int available() throws IOException;
+
+    /**
+     * Closes this socket.
+     *
+     * @exception  IOException  if an I/O error occurs when closing this socket.
+     */
+    protected abstract void close() throws IOException;
+
+    /**
+     * Places the input stream for this socket at "end of stream".
+     * Any data sent to this socket is acknowledged and then
+     * silently discarded.
+     *
+     * If you read from a socket input stream after invoking this method on the
+     * socket, the stream's {@code available} method will return 0, and its
+     * {@code read} methods will return {@code -1} (end of stream).
+     *
+     * @exception IOException if an I/O error occurs when shutting down this
+     * socket.
+     * @see java.net.Socket#shutdownOutput()
+     * @see java.net.Socket#close()
+     * @see java.net.Socket#setSoLinger(boolean, int)
+     * @since 1.3
+     */
+    protected void shutdownInput() throws IOException {
+      throw new IOException("Method not implemented!");
+    }
+
+    /**
+     * Disables the output stream for this socket.
+     * For a TCP socket, any previously written data will be sent
+     * followed by TCP's normal connection termination sequence.
+     *
+     * If you write to a socket output stream after invoking
+     * shutdownOutput() on the socket, the stream will throw
+     * an IOException.
+     *
+     * @exception IOException if an I/O error occurs when shutting down this
+     * socket.
+     * @see java.net.Socket#shutdownInput()
+     * @see java.net.Socket#close()
+     * @see java.net.Socket#setSoLinger(boolean, int)
+     * @since 1.3
+     */
+    protected void shutdownOutput() throws IOException {
+      throw new IOException("Method not implemented!");
+    }
+
+    /**
+     * Returns the value of this socket's {@code fd} field.
+     *
+     * @return  the value of this socket's {@code fd} field.
+     * @see     java.net.SocketImpl#fd
+     */
+    protected FileDescriptor getFileDescriptor() {
+        return fd;
+    }
+
+    // Android-added: getFD$() for testing.
+    /**
+     * @hide used by java.nio tests
+     */
+    public FileDescriptor getFD$() {
+        return fd;
+    }
+
+    /**
+     * Returns the value of this socket's {@code address} field.
+     *
+     * @return  the value of this socket's {@code address} field.
+     * @see     java.net.SocketImpl#address
+     */
+    protected InetAddress getInetAddress() {
+        return address;
+    }
+
+    /**
+     * Returns the value of this socket's {@code port} field.
+     *
+     * @return  the value of this socket's {@code port} field.
+     * @see     java.net.SocketImpl#port
+     */
+    protected int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns whether or not this SocketImpl supports sending
+     * urgent data. By default, false is returned
+     * unless the method is overridden in a sub-class
+     *
+     * @return  true if urgent data supported
+     * @see     java.net.SocketImpl#address
+     * @since 1.4
+     */
+    protected boolean supportsUrgentData () {
+        return false; // must be overridden in sub-class
+    }
+
+    /**
+     * Send one byte of urgent data on the socket.
+     * The byte to be sent is the low eight bits of the parameter
+     * @param data The byte of data to send
+     * @exception IOException if there is an error
+     *  sending the data.
+     * @since 1.4
+     */
+    protected abstract void sendUrgentData (int data) throws IOException;
+
+    /**
+     * Returns the value of this socket's {@code localport} field.
+     *
+     * @return  the value of this socket's {@code localport} field.
+     * @see     java.net.SocketImpl#localport
+     */
+    protected int getLocalPort() {
+        return localport;
+    }
+
+    void setSocket(Socket soc) {
+        this.socket = soc;
+    }
+
+    Socket getSocket() {
+        return socket;
+    }
+
+    void setServerSocket(ServerSocket soc) {
+        this.serverSocket = soc;
+    }
+
+    ServerSocket getServerSocket() {
+        return serverSocket;
+    }
+
+    /**
+     * Returns the address and port of this socket as a {@code String}.
+     *
+     * @return  a string representation of this socket.
+     */
+    public String toString() {
+        return "Socket[addr=" + getInetAddress() +
+            ",port=" + getPort() + ",localport=" + getLocalPort()  + "]";
+    }
+
+    void reset() throws IOException {
+        address = null;
+        port = 0;
+        localport = 0;
+    }
+
+    /**
+     * Sets performance preferences for this socket.
+     *
+     * <p> Sockets use the TCP/IP protocol by default.  Some implementations
+     * may offer alternative protocols which have different performance
+     * characteristics than TCP/IP.  This method allows the application to
+     * express its own preferences as to how these tradeoffs should be made
+     * when the implementation chooses from the available protocols.
+     *
+     * <p> Performance preferences are described by three integers
+     * whose values indicate the relative importance of short connection time,
+     * low latency, and high bandwidth.  The absolute values of the integers
+     * are irrelevant; in order to choose a protocol the values are simply
+     * compared, with larger values indicating stronger preferences. Negative
+     * values represent a lower priority than positive values. If the
+     * application prefers short connection time over both low latency and high
+     * bandwidth, for example, then it could invoke this method with the values
+     * {@code (1, 0, 0)}.  If the application prefers high bandwidth above low
+     * latency, and low latency above short connection time, then it could
+     * invoke this method with the values {@code (0, 1, 2)}.
+     *
+     * By default, this method does nothing, unless it is overridden in a
+     * a sub-class.
+     *
+     * @param  connectionTime
+     *         An {@code int} expressing the relative importance of a short
+     *         connection time
+     *
+     * @param  latency
+     *         An {@code int} expressing the relative importance of low
+     *         latency
+     *
+     * @param  bandwidth
+     *         An {@code int} expressing the relative importance of high
+     *         bandwidth
+     *
+     * @since 1.5
+     */
+    protected void setPerformancePreferences(int connectionTime,
+                                          int latency,
+                                          int bandwidth)
+    {
+        /* Not implemented yet */
+    }
+
+    <T> void setOption(SocketOption<T> name, T value) throws IOException {
+        if (name == StandardSocketOptions.SO_KEEPALIVE) {
+            setOption(SocketOptions.SO_KEEPALIVE, value);
+        } else if (name == StandardSocketOptions.SO_SNDBUF) {
+            setOption(SocketOptions.SO_SNDBUF, value);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            setOption(SocketOptions.SO_RCVBUF, value);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            setOption(SocketOptions.SO_REUSEADDR, value);
+        } else if (name == StandardSocketOptions.SO_LINGER) {
+            setOption(SocketOptions.SO_LINGER, value);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            setOption(SocketOptions.IP_TOS, value);
+        } else if (name == StandardSocketOptions.TCP_NODELAY) {
+            setOption(SocketOptions.TCP_NODELAY, value);
+        } else {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+    }
+
+    <T> T getOption(SocketOption<T> name) throws IOException {
+        if (name == StandardSocketOptions.SO_KEEPALIVE) {
+            return (T)getOption(SocketOptions.SO_KEEPALIVE);
+        } else if (name == StandardSocketOptions.SO_SNDBUF) {
+            return (T)getOption(SocketOptions.SO_SNDBUF);
+        } else if (name == StandardSocketOptions.SO_RCVBUF) {
+            return (T)getOption(SocketOptions.SO_RCVBUF);
+        } else if (name == StandardSocketOptions.SO_REUSEADDR) {
+            return (T)getOption(SocketOptions.SO_REUSEADDR);
+        } else if (name == StandardSocketOptions.SO_LINGER) {
+            return (T)getOption(SocketOptions.SO_LINGER);
+        } else if (name == StandardSocketOptions.IP_TOS) {
+            return (T)getOption(SocketOptions.IP_TOS);
+        } else if (name == StandardSocketOptions.TCP_NODELAY) {
+            return (T)getOption(SocketOptions.TCP_NODELAY);
+        } else {
+            throw new UnsupportedOperationException("unsupported option");
+        }
+    }
+}
diff --git a/java/net/SocketImplFactory.java b/java/net/SocketImplFactory.java
new file mode 100644
index 0000000..7aa6363
--- /dev/null
+++ b/java/net/SocketImplFactory.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This interface defines a factory for socket implementations. It
+ * is used by the classes {@code Socket} and
+ * {@code ServerSocket} to create actual socket
+ * implementations.
+ *
+ * @author  Arthur van Hoff
+ * @see     java.net.Socket
+ * @see     java.net.ServerSocket
+ * @since   JDK1.0
+ */
+public
+interface SocketImplFactory {
+    /**
+     * Creates a new {@code SocketImpl} instance.
+     *
+     * @return  a new instance of {@code SocketImpl}.
+     * @see     java.net.SocketImpl
+     */
+    SocketImpl createSocketImpl();
+}
diff --git a/java/net/SocketInputStream.java b/java/net/SocketInputStream.java
new file mode 100644
index 0000000..8d0e0c5
--- /dev/null
+++ b/java/net/SocketInputStream.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+import dalvik.system.BlockGuard;
+import sun.net.ConnectionResetException;
+
+/**
+ * This stream extends FileInputStream to implement a
+ * SocketInputStream. Note that this class should <b>NOT</b> be
+ * public.
+ *
+ * @author      Jonathan Payne
+ * @author      Arthur van Hoff
+ */
+class SocketInputStream extends FileInputStream
+{
+    // Android-removed: Android doesn't need to call native init.
+    // static {
+    //    init();
+    //}
+
+    private boolean eof;
+    private AbstractPlainSocketImpl impl = null;
+    private byte temp[];
+    private Socket socket = null;
+
+    /**
+     * Creates a new SocketInputStream. Can only be called
+     * by a Socket. This method needs to hang on to the owner Socket so
+     * that the fd will not be closed.
+     * @param impl the implemented socket input stream
+     */
+    SocketInputStream(AbstractPlainSocketImpl impl) throws IOException {
+        super(impl.getFileDescriptor());
+        this.impl = impl;
+        socket = impl.getSocket();
+    }
+
+    /**
+     * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
+     * object associated with this file input stream.</p>
+     *
+     * The {@code getChannel} method of {@code SocketInputStream}
+     * returns {@code null} since it is a socket based stream.</p>
+     *
+     * @return  the file channel associated with this file input stream
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public final FileChannel getChannel() {
+        return null;
+    }
+
+    /**
+     * Reads into an array of bytes at the specified offset using
+     * the received socket primitive.
+     * @param fd the FileDescriptor
+     * @param b the buffer into which the data is read
+     * @param off the start offset of the data
+     * @param len the maximum number of bytes read
+     * @param timeout the read timeout in ms
+     * @return the actual number of bytes read, -1 is
+     *          returned when the end of the stream is reached.
+     * @exception IOException If an I/O error has occurred.
+     */
+    private native int socketRead0(FileDescriptor fd,
+                                   byte b[], int off, int len,
+                                   int timeout)
+        throws IOException;
+
+    // wrap native call to allow instrumentation
+    /**
+     * Reads into an array of bytes at the specified offset using
+     * the received socket primitive.
+     * @param fd the FileDescriptor
+     * @param b the buffer into which the data is read
+     * @param off the start offset of the data
+     * @param len the maximum number of bytes read
+     * @param timeout the read timeout in ms
+     * @return the actual number of bytes read, -1 is
+     *          returned when the end of the stream is reached.
+     * @exception IOException If an I/O error has occurred.
+     */
+    private int socketRead(FileDescriptor fd,
+                           byte b[], int off, int len,
+                           int timeout)
+        throws IOException {
+        return socketRead0(fd, b, off, len, timeout);
+    }
+
+    /**
+     * Reads into a byte array data from the socket.
+     * @param b the buffer into which the data is read
+     * @return the actual number of bytes read, -1 is
+     *          returned when the end of the stream is reached.
+     * @exception IOException If an I/O error has occurred.
+     */
+    public int read(byte b[]) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    /**
+     * Reads into a byte array <i>b</i> at offset <i>off</i>,
+     * <i>length</i> bytes of data.
+     * @param b the buffer into which the data is read
+     * @param off the start offset of the data
+     * @param length the maximum number of bytes read
+     * @return the actual number of bytes read, -1 is
+     *          returned when the end of the stream is reached.
+     * @exception IOException If an I/O error has occurred.
+     */
+    public int read(byte b[], int off, int length) throws IOException {
+        return read(b, off, length, impl.getTimeout());
+    }
+
+    int read(byte b[], int off, int length, int timeout) throws IOException {
+        int n;
+
+        // EOF already encountered
+        if (eof) {
+            return -1;
+        }
+
+        // connection reset
+        if (impl.isConnectionReset()) {
+            throw new SocketException("Connection reset");
+        }
+
+        // bounds check
+        if (length <= 0 || off < 0 || length > b.length - off) {
+            if (length == 0) {
+                return 0;
+            }
+            throw new ArrayIndexOutOfBoundsException("length == " + length
+                    + " off == " + off + " buffer length == " + b.length);
+        }
+
+        boolean gotReset = false;
+
+        // acquire file descriptor and do the read
+        FileDescriptor fd = impl.acquireFD();
+        try {
+            // Android-added: Check BlockGuard policy in read().
+            BlockGuard.getThreadPolicy().onNetwork();
+            n = socketRead(fd, b, off, length, timeout);
+            if (n > 0) {
+                return n;
+            }
+        } catch (ConnectionResetException rstExc) {
+            gotReset = true;
+        } finally {
+            impl.releaseFD();
+        }
+
+        /*
+         * We receive a "connection reset" but there may be bytes still
+         * buffered on the socket
+         */
+        if (gotReset) {
+            impl.setConnectionResetPending();
+            impl.acquireFD();
+            try {
+                n = socketRead(fd, b, off, length, timeout);
+                if (n > 0) {
+                    return n;
+                }
+            } catch (ConnectionResetException rstExc) {
+            } finally {
+                impl.releaseFD();
+            }
+        }
+
+        /*
+         * If we get here we are at EOF, the socket has been closed,
+         * or the connection has been reset.
+         */
+        if (impl.isClosedOrPending()) {
+            throw new SocketException("Socket closed");
+        }
+        if (impl.isConnectionResetPending()) {
+            impl.setConnectionReset();
+        }
+        if (impl.isConnectionReset()) {
+            throw new SocketException("Connection reset");
+        }
+        eof = true;
+        return -1;
+    }
+
+    /**
+     * Reads a single byte from the socket.
+     */
+    public int read() throws IOException {
+        if (eof) {
+            return -1;
+        }
+        temp = new byte[1];
+        int n = read(temp, 0, 1);
+        if (n <= 0) {
+            return -1;
+        }
+        return temp[0] & 0xff;
+    }
+
+    /**
+     * Skips n bytes of input.
+     * @param numbytes the number of bytes to skip
+     * @return  the actual number of bytes skipped.
+     * @exception IOException If an I/O error has occurred.
+     */
+    public long skip(long numbytes) throws IOException {
+        if (numbytes <= 0) {
+            return 0;
+        }
+        long n = numbytes;
+        int buflen = (int) Math.min(1024, n);
+        byte data[] = new byte[buflen];
+        while (n > 0) {
+            int r = read(data, 0, (int) Math.min((long) buflen, n));
+            if (r < 0) {
+                break;
+            }
+            n -= r;
+        }
+        return numbytes - n;
+    }
+
+    /**
+     * Returns the number of bytes that can be read without blocking.
+     * @return the number of immediately available bytes
+     */
+    public int available() throws IOException {
+        // Android-changed: Bug fix, if eof == true, we must indicate that we
+        // have 0 bytes available.
+        if (eof) {
+            return 0;
+        } else {
+            return impl.available();
+        }
+    }
+
+    /**
+     * Closes the stream.
+     */
+    private boolean closing = false;
+    public void close() throws IOException {
+        // Prevent recursion. See BugId 4484411
+        if (closing)
+            return;
+        closing = true;
+        if (socket != null) {
+            if (!socket.isClosed())
+                socket.close();
+        } else
+            impl.close();
+        closing = false;
+    }
+
+    void setEOF(boolean eof) {
+        this.eof = eof;
+    }
+
+    /**
+     * Overrides finalize, the fd is closed by the Socket.
+     */
+    protected void finalize() {}
+
+    // Android-removed: Android doesn't need native init.
+    /*
+     * Perform class load-time initializations.
+     *
+    private native static void init();
+    */
+}
diff --git a/java/net/SocketOption.java b/java/net/SocketOption.java
new file mode 100644
index 0000000..2ccf57f
--- /dev/null
+++ b/java/net/SocketOption.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * A socket option associated with a socket.
+ *
+ * <p> In the {@link java.nio.channels channels} package, the {@link
+ * java.nio.channels.NetworkChannel} interface defines the {@link
+ * java.nio.channels.NetworkChannel#setOption(SocketOption,Object) setOption}
+ * and {@link java.nio.channels.NetworkChannel#getOption(SocketOption) getOption}
+ * methods to set and query the channel's socket options.
+ *
+ * @param   <T>     The type of the socket option value.
+ *
+ * @since 1.7
+ *
+ * @see StandardSocketOptions
+ */
+
+public interface SocketOption<T> {
+
+    /**
+     * Returns the name of the socket option.
+     *
+     * @return the name of the socket option
+     */
+    String name();
+
+    /**
+     * Returns the type of the socket option value.
+     *
+     * @return the type of the socket option value
+     */
+    Class<T> type();
+}
diff --git a/java/net/SocketOptions.java b/java/net/SocketOptions.java
new file mode 100644
index 0000000..7e1b0fc
--- /dev/null
+++ b/java/net/SocketOptions.java
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.lang.annotation.Native;
+
+/**
+ * Interface of methods to get/set socket options.  This interface is
+ * implemented by: <B>SocketImpl</B> and  <B>DatagramSocketImpl</B>.
+ * Subclasses of these should override the methods
+ * of this interface in order to support their own options.
+ * <P>
+ * The methods and constants which specify options in this interface are
+ * for implementation only.  If you're not subclassing SocketImpl or
+ * DatagramSocketImpl, <B>you won't use these directly.</B> There are
+ * type-safe methods to get/set each of these options in Socket, ServerSocket,
+ * DatagramSocket and MulticastSocket.
+ * <P>
+ * @author David Brown
+ */
+
+
+public interface SocketOptions {
+
+    /**
+     * Enable/disable the option specified by <I>optID</I>.  If the option
+     * is to be enabled, and it takes an option-specific "value",  this is
+     * passed in <I>value</I>.  The actual type of value is option-specific,
+     * and it is an error to pass something that isn't of the expected type:
+     * <BR><PRE>
+     * SocketImpl s;
+     * ...
+     * s.setOption(SO_LINGER, new Integer(10));
+     *    // OK - set SO_LINGER w/ timeout of 10 sec.
+     * s.setOption(SO_LINGER, new Double(10));
+     *    // ERROR - expects java.lang.Integer
+     *</PRE>
+     * If the requested option is binary, it can be set using this method by
+     * a java.lang.Boolean:
+     * <BR><PRE>
+     * s.setOption(TCP_NODELAY, new Boolean(true));
+     *    // OK - enables TCP_NODELAY, a binary option
+     * </PRE>
+     * <BR>
+     * Any option can be disabled using this method with a Boolean(false):
+     * <BR><PRE>
+     * s.setOption(TCP_NODELAY, new Boolean(false));
+     *    // OK - disables TCP_NODELAY
+     * s.setOption(SO_LINGER, new Boolean(false));
+     *    // OK - disables SO_LINGER
+     * </PRE>
+     * <BR>
+     * For an option that has a notion of on and off, and requires
+     * a non-boolean parameter, setting its value to anything other than
+     * <I>Boolean(false)</I> implicitly enables it.
+     * <BR>
+     * Throws SocketException if the option is unrecognized,
+     * the socket is closed, or some low-level error occurred
+     * <BR>
+     * @param optID identifies the option
+     * @param value the parameter of the socket option
+     * @throws SocketException if the option is unrecognized,
+     * the socket is closed, or some low-level error occurred
+     * @see #getOption(int)
+     */
+    public void
+        setOption(int optID, Object value) throws SocketException;
+
+    /**
+     * Fetch the value of an option.
+     * Binary options will return java.lang.Boolean(true)
+     * if enabled, java.lang.Boolean(false) if disabled, e.g.:
+     * <BR><PRE>
+     * SocketImpl s;
+     * ...
+     * Boolean noDelay = (Boolean)(s.getOption(TCP_NODELAY));
+     * if (noDelay.booleanValue()) {
+     *     // true if TCP_NODELAY is enabled...
+     * ...
+     * }
+     * </PRE>
+     * <P>
+     * For options that take a particular type as a parameter,
+     * getOption(int) will return the parameter's value, else
+     * it will return java.lang.Boolean(false):
+     * <PRE>
+     * Object o = s.getOption(SO_LINGER);
+     * if (o instanceof Integer) {
+     *     System.out.print("Linger time is " + ((Integer)o).intValue());
+     * } else {
+     *   // the true type of o is java.lang.Boolean(false);
+     * }
+     * </PRE>
+     *
+     * @param optID an {@code int} identifying the option to fetch
+     * @return the value of the option
+     * @throws SocketException if the socket is closed
+     * @throws SocketException if <I>optID</I> is unknown along the
+     *         protocol stack (including the SocketImpl)
+     * @see #setOption(int, java.lang.Object)
+     */
+    public Object getOption(int optID) throws SocketException;
+
+    /**
+     * The java-supported BSD-style options.
+     */
+
+    /**
+     * Disable Nagle's algorithm for this connection.  Written data
+     * to the network is not buffered pending acknowledgement of
+     * previously written data.
+     *<P>
+     * Valid for TCP only: SocketImpl.
+     *
+     * @see Socket#setTcpNoDelay
+     * @see Socket#getTcpNoDelay
+     */
+
+    @Native public final static int TCP_NODELAY = 0x0001;
+
+    /**
+     * Fetch the local address binding of a socket (this option cannot
+     * be "set" only "gotten", since sockets are bound at creation time,
+     * and so the locally bound address cannot be changed).  The default local
+     * address of a socket is INADDR_ANY, meaning any local address on a
+     * multi-homed host.  A multi-homed host can use this option to accept
+     * connections to only one of its addresses (in the case of a
+     * ServerSocket or DatagramSocket), or to specify its return address
+     * to the peer (for a Socket or DatagramSocket).  The parameter of
+     * this option is an InetAddress.
+     * <P>
+     * This option <B>must</B> be specified in the constructor.
+     * <P>
+     * Valid for: SocketImpl, DatagramSocketImpl
+     *
+     * @see Socket#getLocalAddress
+     * @see DatagramSocket#getLocalAddress
+     */
+
+    @Native public final static int SO_BINDADDR = 0x000F;
+
+    /** Sets SO_REUSEADDR for a socket.  This is used only for MulticastSockets
+     * in java, and it is set by default for MulticastSockets.
+     * <P>
+     * Valid for: DatagramSocketImpl
+     */
+
+    @Native public final static int SO_REUSEADDR = 0x04;
+
+    /**
+     * Sets SO_BROADCAST for a socket. This option enables and disables
+     * the ability of the process to send broadcast messages. It is supported
+     * for only datagram sockets and only on networks that support
+     * the concept of a broadcast message (e.g. Ethernet, token ring, etc.),
+     * and it is set by default for DatagramSockets.
+     * @since 1.4
+     */
+
+    @Native public final static int SO_BROADCAST = 0x0020;
+
+    /** Set which outgoing interface on which to send multicast packets.
+     * Useful on hosts with multiple network interfaces, where applications
+     * want to use other than the system default.  Takes/returns an InetAddress.
+     * <P>
+     * Valid for Multicast: DatagramSocketImpl
+     *
+     * @see MulticastSocket#setInterface(InetAddress)
+     * @see MulticastSocket#getInterface()
+     */
+
+    @Native public final static int IP_MULTICAST_IF = 0x10;
+
+    /** Same as above. This option is introduced so that the behaviour
+     *  with IP_MULTICAST_IF will be kept the same as before, while
+     *  this new option can support setting outgoing interfaces with either
+     *  IPv4 and IPv6 addresses.
+     *
+     *  NOTE: make sure there is no conflict with this
+     * @see MulticastSocket#setNetworkInterface(NetworkInterface)
+     * @see MulticastSocket#getNetworkInterface()
+     * @since 1.4
+     */
+    @Native public final static int IP_MULTICAST_IF2 = 0x1f;
+
+    /**
+     * This option enables or disables local loopback of multicast datagrams.
+     * This option is enabled by default for Multicast Sockets.
+     * @since 1.4
+     */
+
+    @Native public final static int IP_MULTICAST_LOOP = 0x12;
+
+    /**
+     * This option sets the type-of-service or traffic class field
+     * in the IP header for a TCP or UDP socket.
+     * @since 1.4
+     */
+
+    @Native public final static int IP_TOS = 0x3;
+
+    /**
+     * Specify a linger-on-close timeout.  This option disables/enables
+     * immediate return from a <B>close()</B> of a TCP Socket.  Enabling
+     * this option with a non-zero Integer <I>timeout</I> means that a
+     * <B>close()</B> will block pending the transmission and acknowledgement
+     * of all data written to the peer, at which point the socket is closed
+     * <I>gracefully</I>.  Upon reaching the linger timeout, the socket is
+     * closed <I>forcefully</I>, with a TCP RST. Enabling the option with a
+     * timeout of zero does a forceful close immediately. If the specified
+     * timeout value exceeds 65,535 it will be reduced to 65,535.
+     * <P>
+     * Valid only for TCP: SocketImpl
+     *
+     * @see Socket#setSoLinger
+     * @see Socket#getSoLinger
+     */
+    @Native public final static int SO_LINGER = 0x0080;
+
+    /** Set a timeout on blocking Socket operations:
+     * <PRE>
+     * ServerSocket.accept();
+     * SocketInputStream.read();
+     * DatagramSocket.receive();
+     * </PRE>
+     *
+     * <P> The option must be set prior to entering a blocking
+     * operation to take effect.  If the timeout expires and the
+     * operation would continue to block,
+     * <B>java.io.InterruptedIOException</B> is raised.  The Socket is
+     * not closed in this case.
+     *
+     * <P> Valid for all sockets: SocketImpl, DatagramSocketImpl
+     *
+     * @see Socket#setSoTimeout
+     * @see ServerSocket#setSoTimeout
+     * @see DatagramSocket#setSoTimeout
+     */
+    @Native public final static int SO_TIMEOUT = 0x1006;
+
+    /**
+     * Set a hint the size of the underlying buffers used by the
+     * platform for outgoing network I/O. When used in set, this is a
+     * suggestion to the kernel from the application about the size of
+     * buffers to use for the data to be sent over the socket. When
+     * used in get, this must return the size of the buffer actually
+     * used by the platform when sending out data on this socket.
+     *
+     * Valid for all sockets: SocketImpl, DatagramSocketImpl
+     *
+     * @see Socket#setSendBufferSize
+     * @see Socket#getSendBufferSize
+     * @see DatagramSocket#setSendBufferSize
+     * @see DatagramSocket#getSendBufferSize
+     */
+    @Native public final static int SO_SNDBUF = 0x1001;
+
+    /**
+     * Set a hint the size of the underlying buffers used by the
+     * platform for incoming network I/O. When used in set, this is a
+     * suggestion to the kernel from the application about the size of
+     * buffers to use for the data to be received over the
+     * socket. When used in get, this must return the size of the
+     * buffer actually used by the platform when receiving in data on
+     * this socket.
+     *
+     * Valid for all sockets: SocketImpl, DatagramSocketImpl
+     *
+     * @see Socket#setReceiveBufferSize
+     * @see Socket#getReceiveBufferSize
+     * @see DatagramSocket#setReceiveBufferSize
+     * @see DatagramSocket#getReceiveBufferSize
+     */
+    @Native public final static int SO_RCVBUF = 0x1002;
+
+    /**
+     * When the keepalive option is set for a TCP socket and no data
+     * has been exchanged across the socket in either direction for
+     * 2 hours (NOTE: the actual value is implementation dependent),
+     * TCP automatically sends a keepalive probe to the peer. This probe is a
+     * TCP segment to which the peer must respond.
+     * One of three responses is expected:
+     * 1. The peer responds with the expected ACK. The application is not
+     *    notified (since everything is OK). TCP will send another probe
+     *    following another 2 hours of inactivity.
+     * 2. The peer responds with an RST, which tells the local TCP that
+     *    the peer host has crashed and rebooted. The socket is closed.
+     * 3. There is no response from the peer. The socket is closed.
+     *
+     * The purpose of this option is to detect if the peer host crashes.
+     *
+     * Valid only for TCP socket: SocketImpl
+     *
+     * @see Socket#setKeepAlive
+     * @see Socket#getKeepAlive
+     */
+    @Native public final static int SO_KEEPALIVE = 0x0008;
+
+    /**
+     * When the OOBINLINE option is set, any TCP urgent data received on
+     * the socket will be received through the socket input stream.
+     * When the option is disabled (which is the default) urgent data
+     * is silently discarded.
+     *
+     * @see Socket#setOOBInline
+     * @see Socket#getOOBInline
+     */
+    @Native public final static int SO_OOBINLINE = 0x1003;
+}
diff --git a/java/net/SocketOutputStream.java b/java/net/SocketOutputStream.java
new file mode 100644
index 0000000..9e8e792
--- /dev/null
+++ b/java/net/SocketOutputStream.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.channels.FileChannel;
+
+import dalvik.system.BlockGuard;
+
+/**
+ * This stream extends FileOutputStream to implement a
+ * SocketOutputStream. Note that this class should <b>NOT</b> be
+ * public.
+ *
+ * @author      Jonathan Payne
+ * @author      Arthur van Hoff
+ */
+class SocketOutputStream extends FileOutputStream
+{
+    // Android-removed: Android doesn't need to call native init.
+    // static {
+    //    init();
+    //}
+
+    private AbstractPlainSocketImpl impl = null;
+    private byte temp[] = new byte[1];
+    private Socket socket = null;
+
+    /**
+     * Creates a new SocketOutputStream. Can only be called
+     * by a Socket. This method needs to hang on to the owner Socket so
+     * that the fd will not be closed.
+     * @param impl the socket output stream inplemented
+     */
+    SocketOutputStream(AbstractPlainSocketImpl impl) throws IOException {
+        super(impl.getFileDescriptor());
+        this.impl = impl;
+        socket = impl.getSocket();
+    }
+
+    /**
+     * Returns the unique {@link java.nio.channels.FileChannel FileChannel}
+     * object associated with this file output stream. </p>
+     *
+     * The {@code getChannel} method of {@code SocketOutputStream}
+     * returns {@code null} since it is a socket based stream.</p>
+     *
+     * @return  the file channel associated with this file output stream
+     *
+     * @since 1.4
+     * @spec JSR-51
+     */
+    public final FileChannel getChannel() {
+        return null;
+    }
+
+    /**
+     * Writes to the socket.
+     * @param fd the FileDescriptor
+     * @param b the data to be written
+     * @param off the start offset in the data
+     * @param len the number of bytes that are written
+     * @exception IOException If an I/O error has occurred.
+     */
+    private native void socketWrite0(FileDescriptor fd, byte[] b, int off,
+                                     int len) throws IOException;
+
+    /**
+     * Writes to the socket with appropriate locking of the
+     * FileDescriptor.
+     * @param b the data to be written
+     * @param off the start offset in the data
+     * @param len the number of bytes that are written
+     * @exception IOException If an I/O error has occurred.
+     */
+    private void socketWrite(byte b[], int off, int len) throws IOException {
+
+
+        if (len <= 0 || off < 0 || len > b.length - off) {
+            if (len == 0) {
+                return;
+            }
+            throw new ArrayIndexOutOfBoundsException("len == " + len
+                    + " off == " + off + " buffer length == " + b.length);
+        }
+
+        FileDescriptor fd = impl.acquireFD();
+        try {
+            // Android-added: Check BlockGuard policy in socketWrite.
+            BlockGuard.getThreadPolicy().onNetwork();
+            socketWrite0(fd, b, off, len);
+        } catch (SocketException se) {
+            if (se instanceof sun.net.ConnectionResetException) {
+                impl.setConnectionResetPending();
+                se = new SocketException("Connection reset");
+            }
+            if (impl.isClosedOrPending()) {
+                throw new SocketException("Socket closed");
+            } else {
+                throw se;
+            }
+        } finally {
+            impl.releaseFD();
+        }
+    }
+
+    /**
+     * Writes a byte to the socket.
+     * @param b the data to be written
+     * @exception IOException If an I/O error has occurred.
+     */
+    public void write(int b) throws IOException {
+        temp[0] = (byte)b;
+        socketWrite(temp, 0, 1);
+    }
+
+    /**
+     * Writes the contents of the buffer <i>b</i> to the socket.
+     * @param b the data to be written
+     * @exception SocketException If an I/O error has occurred.
+     */
+    public void write(byte b[]) throws IOException {
+        socketWrite(b, 0, b.length);
+    }
+
+    /**
+     * Writes <i>length</i> bytes from buffer <i>b</i> starting at
+     * offset <i>len</i>.
+     * @param b the data to be written
+     * @param off the start offset in the data
+     * @param len the number of bytes that are written
+     * @exception SocketException If an I/O error has occurred.
+     */
+    public void write(byte b[], int off, int len) throws IOException {
+        socketWrite(b, off, len);
+    }
+
+    /**
+     * Closes the stream.
+     */
+    private boolean closing = false;
+    public void close() throws IOException {
+        // Prevent recursion. See BugId 4484411
+        if (closing)
+            return;
+        closing = true;
+        if (socket != null) {
+            if (!socket.isClosed())
+                socket.close();
+        } else
+            impl.close();
+        closing = false;
+    }
+
+    /**
+     * Overrides finalize, the fd is closed by the Socket.
+     */
+    protected void finalize() {}
+
+    // Android-removed: Android doesn't need native init.
+    /*
+     * Perform class load-time initializations.
+     *
+    private native static void init();
+    */
+}
diff --git a/java/net/SocketPermission.java b/java/net/SocketPermission.java
new file mode 100644
index 0000000..2195ecc
--- /dev/null
+++ b/java/net/SocketPermission.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.security.Permission;
+
+
+// Android-changed: Stubbed the implementation.  Android doesn't support SecurityManager.
+// See comments in java.lang.SecurityManager for details.
+/**
+ * Legacy security code; do not use.
+ */
+
+public final class SocketPermission extends Permission
+implements java.io.Serializable
+{
+
+    public SocketPermission(String host, String action) { super(""); }
+
+    public boolean implies(Permission p) { return true; }
+
+    public String getActions() { return null; }
+}
diff --git a/java/net/SocketSecrets.java b/java/net/SocketSecrets.java
new file mode 100644
index 0000000..9772906
--- /dev/null
+++ b/java/net/SocketSecrets.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+class SocketSecrets {
+
+    /* accessed by reflection from jdk.net.Sockets */
+
+    /* obj must be a Socket or ServerSocket */
+
+    private static <T> void setOption(Object obj, SocketOption<T> name, T value) throws IOException {
+        SocketImpl impl;
+
+        if (obj instanceof Socket) {
+            impl = ((Socket)obj).getImpl();
+        } else if (obj instanceof ServerSocket) {
+            impl = ((ServerSocket)obj).getImpl();
+        } else {
+            throw new IllegalArgumentException();
+        }
+        impl.setOption(name, value);
+    }
+
+    private static <T> T getOption(Object obj, SocketOption<T> name) throws IOException {
+        SocketImpl impl;
+
+        if (obj instanceof Socket) {
+            impl = ((Socket)obj).getImpl();
+        } else if (obj instanceof ServerSocket) {
+            impl = ((ServerSocket)obj).getImpl();
+        } else {
+            throw new IllegalArgumentException();
+        }
+        return impl.getOption(name);
+    }
+
+    private static <T> void setOption(DatagramSocket s, SocketOption<T> name, T value) throws IOException {
+        s.getImpl().setOption(name, value);
+    }
+
+    private static <T> T getOption(DatagramSocket s, SocketOption<T> name) throws IOException {
+        return s.getImpl().getOption(name);
+    }
+
+}
diff --git a/java/net/SocketTimeoutException.java b/java/net/SocketTimeoutException.java
new file mode 100644
index 0000000..5daf600
--- /dev/null
+++ b/java/net/SocketTimeoutException.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Signals that a timeout has occurred on a socket read or accept.
+ *
+ * @since   1.4
+ */
+
+public class SocketTimeoutException extends java.io.InterruptedIOException {
+    private static final long serialVersionUID = -8846654841826352300L;
+
+    /**
+     * Constructs a new SocketTimeoutException with a detail
+     * message.
+     * @param msg the detail message
+     */
+    public SocketTimeoutException(String msg) {
+        super(msg);
+    }
+
+    /**
+     * Construct a new SocketTimeoutException with no detailed message.
+     */
+    public SocketTimeoutException() {}
+}
diff --git a/java/net/SocksConsts.java b/java/net/SocksConsts.java
new file mode 100644
index 0000000..df47aa7
--- /dev/null
+++ b/java/net/SocksConsts.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+
+/**
+ * Constants used by the SOCKS protocol implementation.
+ */
+
+interface SocksConsts {
+    static final int PROTO_VERS4                = 4;
+    static final int PROTO_VERS         = 5;
+    static final int DEFAULT_PORT               = 1080;
+
+    static final int NO_AUTH            = 0;
+    static final int GSSAPI             = 1;
+    static final int USER_PASSW         = 2;
+    static final int NO_METHODS         = -1;
+
+    static final int CONNECT            = 1;
+    static final int BIND                       = 2;
+    static final int UDP_ASSOC          = 3;
+
+    static final int IPV4                       = 1;
+    static final int DOMAIN_NAME                = 3;
+    static final int IPV6                       = 4;
+
+    static final int REQUEST_OK         = 0;
+    static final int GENERAL_FAILURE    = 1;
+    static final int NOT_ALLOWED                = 2;
+    static final int NET_UNREACHABLE    = 3;
+    static final int HOST_UNREACHABLE   = 4;
+    static final int CONN_REFUSED               = 5;
+    static final int TTL_EXPIRED                = 6;
+    static final int CMD_NOT_SUPPORTED  = 7;
+    static final int ADDR_TYPE_NOT_SUP  = 8;
+}
diff --git a/java/net/SocksSocketImpl.java b/java/net/SocksSocketImpl.java
new file mode 100644
index 0000000..0d9d8f5
--- /dev/null
+++ b/java/net/SocksSocketImpl.java
@@ -0,0 +1,1100 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package java.net;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.BufferedOutputStream;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import sun.net.SocksProxy;
+import sun.net.www.ParseUtil;
+/* import org.ietf.jgss.*; */
+
+/**
+ * SOCKS (V4 & V5) TCP socket implementation (RFC 1928).
+ * This is a subclass of PlainSocketImpl.
+ * Note this class should <b>NOT</b> be public.
+ */
+
+class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
+    private String server = null;
+    private int serverPort = DEFAULT_PORT;
+    private InetSocketAddress external_address;
+    private boolean useV4 = false;
+    private Socket cmdsock = null;
+    private InputStream cmdIn = null;
+    private OutputStream cmdOut = null;
+    /* true if the Proxy has been set programatically */
+    private boolean applicationSetProxy;  /* false */
+
+
+    SocksSocketImpl() {
+        // Nothing needed
+    }
+
+    SocksSocketImpl(String server, int port) {
+        this.server = server;
+        this.serverPort = (port == -1 ? DEFAULT_PORT : port);
+    }
+
+    SocksSocketImpl(Proxy proxy) {
+        SocketAddress a = proxy.address();
+        if (a instanceof InetSocketAddress) {
+            InetSocketAddress ad = (InetSocketAddress) a;
+            // Use getHostString() to avoid reverse lookups
+            server = ad.getHostString();
+            serverPort = ad.getPort();
+        }
+    }
+
+    void setV4() {
+        useV4 = true;
+    }
+
+    private synchronized void privilegedConnect(final String host,
+                                              final int port,
+                                              final int timeout)
+         throws IOException
+    {
+        try {
+            AccessController.doPrivileged(
+                new java.security.PrivilegedExceptionAction<Void>() {
+                    public Void run() throws IOException {
+                              superConnectServer(host, port, timeout);
+                              cmdIn = getInputStream();
+                              cmdOut = getOutputStream();
+                              return null;
+                          }
+                      });
+        } catch (java.security.PrivilegedActionException pae) {
+            throw (IOException) pae.getException();
+        }
+    }
+
+    private void superConnectServer(String host, int port,
+                                    int timeout) throws IOException {
+        super.connect(new InetSocketAddress(host, port), timeout);
+    }
+
+    private static int remainingMillis(long deadlineMillis) throws IOException {
+        if (deadlineMillis == 0L)
+            return 0;
+
+        final long remaining = deadlineMillis - System.currentTimeMillis();
+        if (remaining > 0)
+            return (int) remaining;
+
+        throw new SocketTimeoutException();
+    }
+
+    private int readSocksReply(InputStream in, byte[] data) throws IOException {
+        return readSocksReply(in, data, 0L);
+    }
+
+    private int readSocksReply(InputStream in, byte[] data, long deadlineMillis) throws IOException {
+        int len = data.length;
+        int received = 0;
+        for (int attempts = 0; received < len && attempts < 3; attempts++) {
+            int count;
+            try {
+                count = ((SocketInputStream)in).read(data, received, len - received, remainingMillis(deadlineMillis));
+            } catch (SocketTimeoutException e) {
+                throw new SocketTimeoutException("Connect timed out");
+            }
+            if (count < 0)
+                throw new SocketException("Malformed reply from SOCKS server");
+            received += count;
+        }
+        return received;
+    }
+
+    /**
+     * Provides the authentication machanism required by the proxy.
+     */
+    private boolean authenticate(byte method, InputStream in,
+                                 BufferedOutputStream out) throws IOException {
+        return authenticate(method, in, out, 0L);
+    }
+
+    private boolean authenticate(byte method, InputStream in,
+                                 BufferedOutputStream out,
+                                 long deadlineMillis) throws IOException {
+        // No Authentication required. We're done then!
+        if (method == NO_AUTH)
+            return true;
+        /**
+         * User/Password authentication. Try, in that order :
+         * - The application provided Authenticator, if any
+         * - the user.name & no password (backward compatibility behavior).
+         */
+        if (method == USER_PASSW) {
+            String userName;
+            String password = null;
+            final InetAddress addr = InetAddress.getByName(server);
+            PasswordAuthentication pw =
+                java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction<PasswordAuthentication>() {
+                        public PasswordAuthentication run() {
+                                return Authenticator.requestPasswordAuthentication(
+                                       server, addr, serverPort, "SOCKS5", "SOCKS authentication", null);
+                            }
+                        });
+            if (pw != null) {
+                userName = pw.getUserName();
+                password = new String(pw.getPassword());
+            } else {
+                userName = java.security.AccessController.doPrivileged(
+                        new sun.security.action.GetPropertyAction("user.name"));
+            }
+            if (userName == null)
+                return false;
+            out.write(1);
+            out.write(userName.length());
+            try {
+                out.write(userName.getBytes("ISO-8859-1"));
+            } catch (java.io.UnsupportedEncodingException uee) {
+                assert false;
+            }
+            if (password != null) {
+                out.write(password.length());
+                try {
+                    out.write(password.getBytes("ISO-8859-1"));
+                } catch (java.io.UnsupportedEncodingException uee) {
+                    assert false;
+                }
+            } else
+                out.write(0);
+            out.flush();
+            byte[] data = new byte[2];
+            int i = readSocksReply(in, data, deadlineMillis);
+            if (i != 2 || data[1] != 0) {
+                /* RFC 1929 specifies that the connection MUST be closed if
+                   authentication fails */
+                out.close();
+                in.close();
+                return false;
+            }
+            /* Authentication succeeded */
+            return true;
+        }
+        /**
+         * GSSAPI authentication mechanism.
+         * Unfortunately the RFC seems out of sync with the Reference
+         * implementation. I'll leave this in for future completion.
+         */
+//      if (method == GSSAPI) {
+//          try {
+//              GSSManager manager = GSSManager.getInstance();
+//              GSSName name = manager.createName("SERVICE:socks@"+server,
+//                                                   null);
+//              GSSContext context = manager.createContext(name, null, null,
+//                                                         GSSContext.DEFAULT_LIFETIME);
+//              context.requestMutualAuth(true);
+//              context.requestReplayDet(true);
+//              context.requestSequenceDet(true);
+//              context.requestCredDeleg(true);
+//              byte []inToken = new byte[0];
+//              while (!context.isEstablished()) {
+//                  byte[] outToken
+//                      = context.initSecContext(inToken, 0, inToken.length);
+//                  // send the output token if generated
+//                  if (outToken != null) {
+//                      out.write(1);
+//                      out.write(1);
+//                      out.writeShort(outToken.length);
+//                      out.write(outToken);
+//                      out.flush();
+//                      data = new byte[2];
+//                      i = readSocksReply(in, data, deadlineMillis);
+//                      if (i != 2 || data[1] == 0xff) {
+//                          in.close();
+//                          out.close();
+//                          return false;
+//                      }
+//                      i = readSocksReply(in, data, deadlineMillis);
+//                      int len = 0;
+//                      len = ((int)data[0] & 0xff) << 8;
+//                      len += data[1];
+//                      data = new byte[len];
+//                      i = readSocksReply(in, data, deadlineMillis);
+//                      if (i == len)
+//                          return true;
+//                      in.close();
+//                      out.close();
+//                  }
+//              }
+//          } catch (GSSException e) {
+//              /* RFC 1961 states that if Context initialisation fails the connection
+//                 MUST be closed */
+//              e.printStackTrace();
+//              in.close();
+//              out.close();
+//          }
+//      }
+        return false;
+    }
+
+    private void connectV4(InputStream in, OutputStream out,
+                           InetSocketAddress endpoint,
+                           long deadlineMillis) throws IOException {
+        if (!(endpoint.getAddress() instanceof Inet4Address)) {
+            throw new SocketException("SOCKS V4 requires IPv4 only addresses");
+        }
+        out.write(PROTO_VERS4);
+        out.write(CONNECT);
+        out.write((endpoint.getPort() >> 8) & 0xff);
+        out.write((endpoint.getPort() >> 0) & 0xff);
+        out.write(endpoint.getAddress().getAddress());
+        String userName = getUserName();
+        try {
+            out.write(userName.getBytes("ISO-8859-1"));
+        } catch (java.io.UnsupportedEncodingException uee) {
+            assert false;
+        }
+        out.write(0);
+        out.flush();
+        byte[] data = new byte[8];
+        int n = readSocksReply(in, data, deadlineMillis);
+        if (n != 8)
+            throw new SocketException("Reply from SOCKS server has bad length: " + n);
+        if (data[0] != 0 && data[0] != 4)
+            throw new SocketException("Reply from SOCKS server has bad version");
+        SocketException ex = null;
+        switch (data[1]) {
+        case 90:
+            // Success!
+            external_address = endpoint;
+            break;
+        case 91:
+            ex = new SocketException("SOCKS request rejected");
+            break;
+        case 92:
+            ex = new SocketException("SOCKS server couldn't reach destination");
+            break;
+        case 93:
+            ex = new SocketException("SOCKS authentication failed");
+            break;
+        default:
+            ex = new SocketException("Reply from SOCKS server contains bad status");
+            break;
+        }
+        if (ex != null) {
+            in.close();
+            out.close();
+            throw ex;
+        }
+    }
+
+    /**
+     * Connects the Socks Socket to the specified endpoint. It will first
+     * connect to the SOCKS proxy and negotiate the access. If the proxy
+     * grants the connections, then the connect is successful and all
+     * further traffic will go to the "real" endpoint.
+     *
+     * @param   endpoint        the {@code SocketAddress} to connect to.
+     * @param   timeout         the timeout value in milliseconds
+     * @throws  IOException     if the connection can't be established.
+     * @throws  SecurityException if there is a security manager and it
+     *                          doesn't allow the connection
+     * @throws  IllegalArgumentException if endpoint is null or a
+     *          SocketAddress subclass not supported by this socket
+     */
+    @Override
+    protected void connect(SocketAddress endpoint, int timeout) throws IOException {
+        final long deadlineMillis;
+
+        if (timeout == 0) {
+            deadlineMillis = 0L;
+        } else {
+            long finish = System.currentTimeMillis() + timeout;
+            deadlineMillis = finish < 0 ? Long.MAX_VALUE : finish;
+        }
+
+        SecurityManager security = System.getSecurityManager();
+        if (endpoint == null || !(endpoint instanceof InetSocketAddress))
+            throw new IllegalArgumentException("Unsupported address type");
+        InetSocketAddress epoint = (InetSocketAddress) endpoint;
+        if (security != null) {
+            if (epoint.isUnresolved())
+                security.checkConnect(epoint.getHostName(),
+                                      epoint.getPort());
+            else
+                security.checkConnect(epoint.getAddress().getHostAddress(),
+                                      epoint.getPort());
+        }
+        if (server == null) {
+            // Android-removed: Logic to establish proxy connection based on default ProxySelector.
+            // Removed code that tried to establish proxy connection if ProxySelector#getDefault()
+            // is not null. This was never the case in previous Android releases, was causing
+            // issues and therefore was removed.
+            /*
+            // This is the general case
+            // server is not null only when the socket was created with a
+            // specified proxy in which case it does bypass the ProxySelector
+            ProxySelector sel = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ProxySelector>() {
+                    public ProxySelector run() {
+                            return ProxySelector.getDefault();
+                        }
+                    });
+            if (sel == null) {
+                /*
+                 * No default proxySelector --> direct connection
+                 *
+                super.connect(epoint, remainingMillis(deadlineMillis));
+                return;
+            }
+            URI uri;
+            // Use getHostString() to avoid reverse lookups
+            String host = epoint.getHostString();
+            // IPv6 litteral?
+            if (epoint.getAddress() instanceof Inet6Address &&
+                (!host.startsWith("[")) && (host.indexOf(":") >= 0)) {
+                host = "[" + host + "]";
+            }
+            try {
+                uri = new URI("socket://" + ParseUtil.encodePath(host) + ":"+ epoint.getPort());
+            } catch (URISyntaxException e) {
+                // This shouldn't happen
+                assert false : e;
+                uri = null;
+            }
+            Proxy p = null;
+            IOException savedExc = null;
+            java.util.Iterator<Proxy> iProxy = null;
+            iProxy = sel.select(uri).iterator();
+            if (iProxy == null || !(iProxy.hasNext())) {
+                super.connect(epoint, remainingMillis(deadlineMillis));
+                return;
+            }
+            while (iProxy.hasNext()) {
+                p = iProxy.next();
+                if (p == null || p.type() != Proxy.Type.SOCKS) {
+                    super.connect(epoint, remainingMillis(deadlineMillis));
+                    return;
+                }
+
+                if (!(p.address() instanceof InetSocketAddress))
+                    throw new SocketException("Unknown address type for proxy: " + p);
+                // Use getHostString() to avoid reverse lookups
+                server = ((InetSocketAddress) p.address()).getHostString();
+                serverPort = ((InetSocketAddress) p.address()).getPort();
+                if (p instanceof SocksProxy) {
+                    if (((SocksProxy)p).protocolVersion() == 4) {
+                        useV4 = true;
+                    }
+                }
+
+                // Connects to the SOCKS server
+                try {
+                    privilegedConnect(server, serverPort, remainingMillis(deadlineMillis));
+                    // Worked, let's get outta here
+                    break;
+                } catch (IOException e) {
+                    // Ooops, let's notify the ProxySelector
+                    sel.connectFailed(uri,p.address(),e);
+                    server = null;
+                    serverPort = -1;
+                    savedExc = e;
+                    // Will continue the while loop and try the next proxy
+                }
+            }
+
+            /*
+             * If server is still null at this point, none of the proxy
+             * worked
+             *
+            if (server == null) {
+                throw new SocketException("Can't connect to SOCKS proxy:"
+                                          + savedExc.getMessage());
+            }
+             */
+            super.connect(epoint, remainingMillis(deadlineMillis));
+            return;
+        } else {
+            // Connects to the SOCKS server
+            try {
+                privilegedConnect(server, serverPort, remainingMillis(deadlineMillis));
+            } catch (IOException e) {
+                throw new SocketException(e.getMessage());
+            }
+        }
+
+        // cmdIn & cmdOut were initialized during the privilegedConnect() call
+        BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
+        InputStream in = cmdIn;
+
+        if (useV4) {
+            // SOCKS Protocol version 4 doesn't know how to deal with
+            // DOMAIN type of addresses (unresolved addresses here)
+            if (epoint.isUnresolved())
+                throw new UnknownHostException(epoint.toString());
+            connectV4(in, out, epoint, deadlineMillis);
+            return;
+        }
+
+        // This is SOCKS V5
+        out.write(PROTO_VERS);
+        out.write(2);
+        out.write(NO_AUTH);
+        out.write(USER_PASSW);
+        out.flush();
+        byte[] data = new byte[2];
+        int i = readSocksReply(in, data, deadlineMillis);
+        if (i != 2 || ((int)data[0]) != PROTO_VERS) {
+            // Maybe it's not a V5 sever after all
+            // Let's try V4 before we give up
+            // SOCKS Protocol version 4 doesn't know how to deal with
+            // DOMAIN type of addresses (unresolved addresses here)
+            if (epoint.isUnresolved())
+                throw new UnknownHostException(epoint.toString());
+            connectV4(in, out, epoint, deadlineMillis);
+            return;
+        }
+        if (((int)data[1]) == NO_METHODS)
+            throw new SocketException("SOCKS : No acceptable methods");
+        if (!authenticate(data[1], in, out, deadlineMillis)) {
+            throw new SocketException("SOCKS : authentication failed");
+        }
+        out.write(PROTO_VERS);
+        out.write(CONNECT);
+        out.write(0);
+        /* Test for IPV4/IPV6/Unresolved */
+        if (epoint.isUnresolved()) {
+            out.write(DOMAIN_NAME);
+            out.write(epoint.getHostName().length());
+            try {
+                out.write(epoint.getHostName().getBytes("ISO-8859-1"));
+            } catch (java.io.UnsupportedEncodingException uee) {
+                assert false;
+            }
+            out.write((epoint.getPort() >> 8) & 0xff);
+            out.write((epoint.getPort() >> 0) & 0xff);
+        } else if (epoint.getAddress() instanceof Inet6Address) {
+            out.write(IPV6);
+            out.write(epoint.getAddress().getAddress());
+            out.write((epoint.getPort() >> 8) & 0xff);
+            out.write((epoint.getPort() >> 0) & 0xff);
+        } else {
+            out.write(IPV4);
+            out.write(epoint.getAddress().getAddress());
+            out.write((epoint.getPort() >> 8) & 0xff);
+            out.write((epoint.getPort() >> 0) & 0xff);
+        }
+        out.flush();
+        data = new byte[4];
+        i = readSocksReply(in, data, deadlineMillis);
+        if (i != 4)
+            throw new SocketException("Reply from SOCKS server has bad length");
+        SocketException ex = null;
+        int len;
+        byte[] addr;
+        switch (data[1]) {
+        case REQUEST_OK:
+            // success!
+            switch(data[3]) {
+            case IPV4:
+                addr = new byte[4];
+                i = readSocksReply(in, addr, deadlineMillis);
+                if (i != 4)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                data = new byte[2];
+                i = readSocksReply(in, data, deadlineMillis);
+                if (i != 2)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                break;
+            case DOMAIN_NAME:
+                len = data[1];
+                byte[] host = new byte[len];
+                i = readSocksReply(in, host, deadlineMillis);
+                if (i != len)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                data = new byte[2];
+                i = readSocksReply(in, data, deadlineMillis);
+                if (i != 2)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                break;
+            case IPV6:
+                len = data[1];
+                addr = new byte[len];
+                i = readSocksReply(in, addr, deadlineMillis);
+                if (i != len)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                data = new byte[2];
+                i = readSocksReply(in, data, deadlineMillis);
+                if (i != 2)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                break;
+            default:
+                ex = new SocketException("Reply from SOCKS server contains wrong code");
+                break;
+            }
+            break;
+        case GENERAL_FAILURE:
+            ex = new SocketException("SOCKS server general failure");
+            break;
+        case NOT_ALLOWED:
+            ex = new SocketException("SOCKS: Connection not allowed by ruleset");
+            break;
+        case NET_UNREACHABLE:
+            ex = new SocketException("SOCKS: Network unreachable");
+            break;
+        case HOST_UNREACHABLE:
+            ex = new SocketException("SOCKS: Host unreachable");
+            break;
+        case CONN_REFUSED:
+            ex = new SocketException("SOCKS: Connection refused");
+            break;
+        case TTL_EXPIRED:
+            ex =  new SocketException("SOCKS: TTL expired");
+            break;
+        case CMD_NOT_SUPPORTED:
+            ex = new SocketException("SOCKS: Command not supported");
+            break;
+        case ADDR_TYPE_NOT_SUP:
+            ex = new SocketException("SOCKS: address type not supported");
+            break;
+        }
+        if (ex != null) {
+            in.close();
+            out.close();
+            throw ex;
+        }
+        external_address = epoint;
+    }
+
+    // Android-removed: Dead code. bindV4, socksBind, acceptFrom methods.
+    /*
+    private void bindV4(InputStream in, OutputStream out,
+                        InetAddress baddr,
+                        int lport) throws IOException {
+        if (!(baddr instanceof Inet4Address)) {
+            throw new SocketException("SOCKS V4 requires IPv4 only addresses");
+        }
+        super.bind(baddr, lport);
+        byte[] addr1 = baddr.getAddress();
+        /* Test for AnyLocal *
+        InetAddress naddr = baddr;
+        if (naddr.isAnyLocalAddress()) {
+            naddr = AccessController.doPrivileged(
+                        new PrivilegedAction<InetAddress>() {
+                            public InetAddress run() {
+                                return cmdsock.getLocalAddress();
+
+                            }
+                        });
+            addr1 = naddr.getAddress();
+        }
+        out.write(PROTO_VERS4);
+        out.write(BIND);
+        out.write((super.getLocalPort() >> 8) & 0xff);
+        out.write((super.getLocalPort() >> 0) & 0xff);
+        out.write(addr1);
+        String userName = getUserName();
+        try {
+            out.write(userName.getBytes("ISO-8859-1"));
+        } catch (java.io.UnsupportedEncodingException uee) {
+            assert false;
+        }
+        out.write(0);
+        out.flush();
+        byte[] data = new byte[8];
+        int n = readSocksReply(in, data);
+        if (n != 8)
+            throw new SocketException("Reply from SOCKS server has bad length: " + n);
+        if (data[0] != 0 && data[0] != 4)
+            throw new SocketException("Reply from SOCKS server has bad version");
+        SocketException ex = null;
+        switch (data[1]) {
+        case 90:
+            // Success!
+            external_address = new InetSocketAddress(baddr, lport);
+            break;
+        case 91:
+            ex = new SocketException("SOCKS request rejected");
+            break;
+        case 92:
+            ex = new SocketException("SOCKS server couldn't reach destination");
+            break;
+        case 93:
+            ex = new SocketException("SOCKS authentication failed");
+            break;
+        default:
+            ex = new SocketException("Reply from SOCKS server contains bad status");
+            break;
+        }
+        if (ex != null) {
+            in.close();
+            out.close();
+            throw ex;
+        }
+
+    }
+
+    /**
+     * Sends the Bind request to the SOCKS proxy. In the SOCKS protocol, bind
+     * means "accept incoming connection from", so the SocketAddress is the
+     * the one of the host we do accept connection from.
+     *
+     * @param      saddr   the Socket address of the remote host.
+     * @exception  IOException  if an I/O error occurs when binding this socket.
+     *
+    protected synchronized void socksBind(InetSocketAddress saddr) throws IOException {
+        if (socket != null) {
+            // this is a client socket, not a server socket, don't
+            // call the SOCKS proxy for a bind!
+            return;
+        }
+
+        // Connects to the SOCKS server
+
+        if (server == null) {
+            // This is the general case
+            // server is not null only when the socket was created with a
+            // specified proxy in which case it does bypass the ProxySelector
+            ProxySelector sel = java.security.AccessController.doPrivileged(
+                new java.security.PrivilegedAction<ProxySelector>() {
+                    public ProxySelector run() {
+                            return ProxySelector.getDefault();
+                        }
+                    });
+            if (sel == null) {
+                /*
+                 * No default proxySelector --> direct connection
+                 *
+                return;
+            }
+            URI uri;
+            // Use getHostString() to avoid reverse lookups
+            String host = saddr.getHostString();
+            // IPv6 litteral?
+            if (saddr.getAddress() instanceof Inet6Address &&
+                (!host.startsWith("[")) && (host.indexOf(":") >= 0)) {
+                host = "[" + host + "]";
+            }
+            try {
+                uri = new URI("serversocket://" + ParseUtil.encodePath(host) + ":"+ saddr.getPort());
+            } catch (URISyntaxException e) {
+                // This shouldn't happen
+                assert false : e;
+                uri = null;
+            }
+            Proxy p = null;
+            Exception savedExc = null;
+            java.util.Iterator<Proxy> iProxy = null;
+            iProxy = sel.select(uri).iterator();
+            if (iProxy == null || !(iProxy.hasNext())) {
+                return;
+            }
+            while (iProxy.hasNext()) {
+                p = iProxy.next();
+                if (p == null || p.type() != Proxy.Type.SOCKS) {
+                    return;
+                }
+
+                if (!(p.address() instanceof InetSocketAddress))
+                    throw new SocketException("Unknown address type for proxy: " + p);
+                // Use getHostString() to avoid reverse lookups
+                server = ((InetSocketAddress) p.address()).getHostString();
+                serverPort = ((InetSocketAddress) p.address()).getPort();
+                if (p instanceof SocksProxy) {
+                    if (((SocksProxy)p).protocolVersion() == 4) {
+                        useV4 = true;
+                    }
+                }
+
+                // Connects to the SOCKS server
+                try {
+                    AccessController.doPrivileged(
+                        new PrivilegedExceptionAction<Void>() {
+                            public Void run() throws Exception {
+                                cmdsock = new Socket(new PlainSocketImpl());
+                                cmdsock.connect(new InetSocketAddress(server, serverPort));
+                                cmdIn = cmdsock.getInputStream();
+                                cmdOut = cmdsock.getOutputStream();
+                                return null;
+                            }
+                        });
+                } catch (Exception e) {
+                    // Ooops, let's notify the ProxySelector
+                    sel.connectFailed(uri,p.address(),new SocketException(e.getMessage()));
+                    server = null;
+                    serverPort = -1;
+                    cmdsock = null;
+                    savedExc = e;
+                    // Will continue the while loop and try the next proxy
+                }
+            }
+
+            /*
+             * If server is still null at this point, none of the proxy
+             * worked
+             *
+            if (server == null || cmdsock == null) {
+                throw new SocketException("Can't connect to SOCKS proxy:"
+                                          + savedExc.getMessage());
+            }
+        } else {
+            try {
+                AccessController.doPrivileged(
+                    new PrivilegedExceptionAction<Void>() {
+                        public Void run() throws Exception {
+                            cmdsock = new Socket(new PlainSocketImpl());
+                            cmdsock.connect(new InetSocketAddress(server, serverPort));
+                            cmdIn = cmdsock.getInputStream();
+                            cmdOut = cmdsock.getOutputStream();
+                            return null;
+                        }
+                    });
+            } catch (Exception e) {
+                throw new SocketException(e.getMessage());
+            }
+        }
+        BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512);
+        InputStream in = cmdIn;
+        if (useV4) {
+            bindV4(in, out, saddr.getAddress(), saddr.getPort());
+            return;
+        }
+        out.write(PROTO_VERS);
+        out.write(2);
+        out.write(NO_AUTH);
+        out.write(USER_PASSW);
+        out.flush();
+        byte[] data = new byte[2];
+        int i = readSocksReply(in, data);
+        if (i != 2 || ((int)data[0]) != PROTO_VERS) {
+            // Maybe it's not a V5 sever after all
+            // Let's try V4 before we give up
+            bindV4(in, out, saddr.getAddress(), saddr.getPort());
+            return;
+        }
+        if (((int)data[1]) == NO_METHODS)
+            throw new SocketException("SOCKS : No acceptable methods");
+        if (!authenticate(data[1], in, out)) {
+            throw new SocketException("SOCKS : authentication failed");
+        }
+        // We're OK. Let's issue the BIND command.
+        out.write(PROTO_VERS);
+        out.write(BIND);
+        out.write(0);
+        int lport = saddr.getPort();
+        if (saddr.isUnresolved()) {
+            out.write(DOMAIN_NAME);
+            out.write(saddr.getHostName().length());
+            try {
+                out.write(saddr.getHostName().getBytes("ISO-8859-1"));
+            } catch (java.io.UnsupportedEncodingException uee) {
+                assert false;
+            }
+            out.write((lport >> 8) & 0xff);
+            out.write((lport >> 0) & 0xff);
+        } else if (saddr.getAddress() instanceof Inet4Address) {
+            byte[] addr1 = saddr.getAddress().getAddress();
+            out.write(IPV4);
+            out.write(addr1);
+            out.write((lport >> 8) & 0xff);
+            out.write((lport >> 0) & 0xff);
+            out.flush();
+        } else if (saddr.getAddress() instanceof Inet6Address) {
+            byte[] addr1 = saddr.getAddress().getAddress();
+            out.write(IPV6);
+            out.write(addr1);
+            out.write((lport >> 8) & 0xff);
+            out.write((lport >> 0) & 0xff);
+            out.flush();
+        } else {
+            cmdsock.close();
+            throw new SocketException("unsupported address type : " + saddr);
+        }
+        data = new byte[4];
+        i = readSocksReply(in, data);
+        SocketException ex = null;
+        int len, nport;
+        byte[] addr;
+        switch (data[1]) {
+        case REQUEST_OK:
+            // success!
+            switch(data[3]) {
+            case IPV4:
+                addr = new byte[4];
+                i = readSocksReply(in, addr);
+                if (i != 4)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                data = new byte[2];
+                i = readSocksReply(in, data);
+                if (i != 2)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                nport = ((int)data[0] & 0xff) << 8;
+                nport += ((int)data[1] & 0xff);
+                external_address =
+                    new InetSocketAddress(new Inet4Address("", addr) , nport);
+                break;
+            case DOMAIN_NAME:
+                len = data[1];
+                byte[] host = new byte[len];
+                i = readSocksReply(in, host);
+                if (i != len)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                data = new byte[2];
+                i = readSocksReply(in, data);
+                if (i != 2)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                nport = ((int)data[0] & 0xff) << 8;
+                nport += ((int)data[1] & 0xff);
+                external_address = new InetSocketAddress(new String(host), nport);
+                break;
+            case IPV6:
+                len = data[1];
+                addr = new byte[len];
+                i = readSocksReply(in, addr);
+                if (i != len)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                data = new byte[2];
+                i = readSocksReply(in, data);
+                if (i != 2)
+                    throw new SocketException("Reply from SOCKS server badly formatted");
+                nport = ((int)data[0] & 0xff) << 8;
+                nport += ((int)data[1] & 0xff);
+                external_address =
+                    new InetSocketAddress(new Inet6Address("", addr), nport);
+                break;
+            }
+            break;
+        case GENERAL_FAILURE:
+            ex = new SocketException("SOCKS server general failure");
+            break;
+        case NOT_ALLOWED:
+            ex = new SocketException("SOCKS: Bind not allowed by ruleset");
+            break;
+        case NET_UNREACHABLE:
+            ex = new SocketException("SOCKS: Network unreachable");
+            break;
+        case HOST_UNREACHABLE:
+            ex = new SocketException("SOCKS: Host unreachable");
+            break;
+        case CONN_REFUSED:
+            ex = new SocketException("SOCKS: Connection refused");
+            break;
+        case TTL_EXPIRED:
+            ex =  new SocketException("SOCKS: TTL expired");
+            break;
+        case CMD_NOT_SUPPORTED:
+            ex = new SocketException("SOCKS: Command not supported");
+            break;
+        case ADDR_TYPE_NOT_SUP:
+            ex = new SocketException("SOCKS: address type not supported");
+            break;
+        }
+        if (ex != null) {
+            in.close();
+            out.close();
+            cmdsock.close();
+            cmdsock = null;
+            throw ex;
+        }
+        cmdIn = in;
+        cmdOut = out;
+    }
+
+    /**
+     * Accepts a connection from a specific host.
+     *
+     * @param      s   the accepted connection.
+     * @param      saddr the socket address of the host we do accept
+     *               connection from
+     * @exception  IOException  if an I/O error occurs when accepting the
+     *               connection.
+     *
+    protected void acceptFrom(SocketImpl s, InetSocketAddress saddr) throws IOException {
+        if (cmdsock == null) {
+            // Not a Socks ServerSocket.
+            return;
+        }
+        InputStream in = cmdIn;
+        // Sends the "SOCKS BIND" request.
+        socksBind(saddr);
+        in.read();
+        int i = in.read();
+        in.read();
+        SocketException ex = null;
+        int nport;
+        byte[] addr;
+        InetSocketAddress real_end = null;
+        switch (i) {
+        case REQUEST_OK:
+            // success!
+            i = in.read();
+            switch(i) {
+            case IPV4:
+                addr = new byte[4];
+                readSocksReply(in, addr);
+                nport = in.read() << 8;
+                nport += in.read();
+                real_end =
+                    new InetSocketAddress(new Inet4Address("", addr) , nport);
+                break;
+            case DOMAIN_NAME:
+                int len = in.read();
+                addr = new byte[len];
+                readSocksReply(in, addr);
+                nport = in.read() << 8;
+                nport += in.read();
+                real_end = new InetSocketAddress(new String(addr), nport);
+                break;
+            case IPV6:
+                addr = new byte[16];
+                readSocksReply(in, addr);
+                nport = in.read() << 8;
+                nport += in.read();
+                real_end =
+                    new InetSocketAddress(new Inet6Address("", addr), nport);
+                break;
+            }
+            break;
+        case GENERAL_FAILURE:
+            ex = new SocketException("SOCKS server general failure");
+            break;
+        case NOT_ALLOWED:
+            ex = new SocketException("SOCKS: Accept not allowed by ruleset");
+            break;
+        case NET_UNREACHABLE:
+            ex = new SocketException("SOCKS: Network unreachable");
+            break;
+        case HOST_UNREACHABLE:
+            ex = new SocketException("SOCKS: Host unreachable");
+            break;
+        case CONN_REFUSED:
+            ex = new SocketException("SOCKS: Connection refused");
+            break;
+        case TTL_EXPIRED:
+            ex =  new SocketException("SOCKS: TTL expired");
+            break;
+        case CMD_NOT_SUPPORTED:
+            ex = new SocketException("SOCKS: Command not supported");
+            break;
+        case ADDR_TYPE_NOT_SUP:
+            ex = new SocketException("SOCKS: address type not supported");
+            break;
+        }
+        if (ex != null) {
+            cmdIn.close();
+            cmdOut.close();
+            cmdsock.close();
+            cmdsock = null;
+            throw ex;
+        }
+
+        /**
+         * This is where we have to do some fancy stuff.
+         * The datastream from the socket "accepted" by the proxy will
+         * come through the cmdSocket. So we have to swap the socketImpls
+         *
+        if (s instanceof SocksSocketImpl) {
+            ((SocksSocketImpl)s).external_address = real_end;
+        }
+        if (s instanceof PlainSocketImpl) {
+            PlainSocketImpl psi = (PlainSocketImpl) s;
+            psi.setInputStream((SocketInputStream) in);
+            psi.setFileDescriptor(cmdsock.getImpl().getFileDescriptor());
+            psi.setAddress(cmdsock.getImpl().getInetAddress());
+            psi.setPort(cmdsock.getImpl().getPort());
+            psi.setLocalPort(cmdsock.getImpl().getLocalPort());
+        } else {
+            s.fd = cmdsock.getImpl().fd;
+            s.address = cmdsock.getImpl().address;
+            s.port = cmdsock.getImpl().port;
+            s.localport = cmdsock.getImpl().localport;
+        }
+
+        // Need to do that so that the socket won't be closed
+        // when the ServerSocket is closed by the user.
+        // It kinds of detaches the Socket because it is now
+        // used elsewhere.
+        cmdsock = null;
+    }
+    */
+
+    /**
+     * Returns the value of this socket's {@code address} field.
+     *
+     * @return  the value of this socket's {@code address} field.
+     * @see     java.net.SocketImpl#address
+     */
+    @Override
+    protected InetAddress getInetAddress() {
+        if (external_address != null)
+            return external_address.getAddress();
+        else
+            return super.getInetAddress();
+    }
+
+    /**
+     * Returns the value of this socket's {@code port} field.
+     *
+     * @return  the value of this socket's {@code port} field.
+     * @see     java.net.SocketImpl#port
+     */
+    @Override
+    protected int getPort() {
+        if (external_address != null)
+            return external_address.getPort();
+        else
+            return super.getPort();
+    }
+
+    @Override
+    protected int getLocalPort() {
+        if (socket != null)
+            return super.getLocalPort();
+        if (external_address != null)
+            return external_address.getPort();
+        else
+            return super.getLocalPort();
+    }
+
+    @Override
+    protected void close() throws IOException {
+        if (cmdsock != null)
+            cmdsock.close();
+        cmdsock = null;
+        super.close();
+    }
+
+    private String getUserName() {
+        String userName = "";
+        if (applicationSetProxy) {
+            try {
+                userName = System.getProperty("user.name");
+            } catch (SecurityException se) { /* swallow Exception */ }
+        } else {
+            userName = java.security.AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction("user.name"));
+        }
+        return userName;
+    }
+}
diff --git a/java/net/StandardProtocolFamily.java b/java/net/StandardProtocolFamily.java
new file mode 100644
index 0000000..25aaed4
--- /dev/null
+++ b/java/net/StandardProtocolFamily.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2007, 2009, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Defines the standard families of communication protocols.
+ *
+ * @since 1.7
+ */
+
+public enum StandardProtocolFamily implements ProtocolFamily {
+
+    /**
+     * Internet Protocol Version 4 (IPv4)
+     */
+    INET,
+
+    /**
+     * Internet Protocol Version 6 (IPv6)
+     */
+    INET6
+}
diff --git a/java/net/StandardSocketOptions.java b/java/net/StandardSocketOptions.java
new file mode 100644
index 0000000..7fdd5f0
--- /dev/null
+++ b/java/net/StandardSocketOptions.java
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * Defines the <em>standard</em> socket options.
+ *
+ * <p> The {@link SocketOption#name name} of each socket option defined by this
+ * class is its field name.
+ *
+ * <p> In this release, the socket options defined here are used by {@link
+ * java.nio.channels.NetworkChannel network} channels in the {@link
+ * java.nio.channels channels} package.
+ *
+ * @since 1.7
+ */
+
+public final class StandardSocketOptions {
+    private StandardSocketOptions() { }
+
+    // -- SOL_SOCKET --
+
+    /**
+     * Allow transmission of broadcast datagrams.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The option is specific to
+     * datagram-oriented sockets sending to {@link java.net.Inet4Address IPv4}
+     * broadcast addresses. When the socket option is enabled then the socket
+     * can be used to send <em>broadcast datagrams</em>.
+     *
+     * <p> The initial value of this socket option is {@code FALSE}. The socket
+     * option may be enabled or disabled at any time. Some operating systems may
+     * require that the Java virtual machine be started with implementation
+     * specific privileges to enable this option or send broadcast datagrams.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc919.txt">RFC&nbsp;929:
+     * Broadcasting Internet Datagrams</a>
+     * @see DatagramSocket#setBroadcast
+     */
+    public static final SocketOption<Boolean> SO_BROADCAST =
+        new StdSocketOption<Boolean>("SO_BROADCAST", Boolean.class);
+
+    /**
+     * Keep connection alive.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. When the {@code SO_KEEPALIVE}
+     * option is enabled the operating system may use a <em>keep-alive</em>
+     * mechanism to periodically probe the other end of a connection when the
+     * connection is otherwise idle. The exact semantics of the keep alive
+     * mechanism is system dependent and therefore unspecified.
+     *
+     * <p> The initial value of this socket option is {@code FALSE}. The socket
+     * option may be enabled or disabled at any time.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122
+     * Requirements for Internet Hosts -- Communication Layers</a>
+     * @see Socket#setKeepAlive
+     */
+    public static final SocketOption<Boolean> SO_KEEPALIVE =
+        new StdSocketOption<Boolean>("SO_KEEPALIVE", Boolean.class);
+
+    /**
+     * The size of the socket send buffer.
+     *
+     * <p> The value of this socket option is an {@code Integer} that is the
+     * size of the socket send buffer in bytes. The socket send buffer is an
+     * output buffer used by the networking implementation. It may need to be
+     * increased for high-volume connections. The value of the socket option is
+     * a <em>hint</em> to the implementation to size the buffer and the actual
+     * size may differ. The socket option can be queried to retrieve the actual
+     * size.
+     *
+     * <p> For datagram-oriented sockets, the size of the send buffer may limit
+     * the size of the datagrams that may be sent by the socket. Whether
+     * datagrams larger than the buffer size are sent or discarded is system
+     * dependent.
+     *
+     * <p> The initial/default size of the socket send buffer and the range of
+     * allowable values is system dependent although a negative size is not
+     * allowed. An attempt to set the socket send buffer to larger than its
+     * maximum size causes it to be set to its maximum size.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Whether an implementation allows the
+     * socket send buffer to be changed after the socket is bound is system
+     * dependent.
+     *
+     * @see Socket#setSendBufferSize
+     */
+    public static final SocketOption<Integer> SO_SNDBUF =
+        new StdSocketOption<Integer>("SO_SNDBUF", Integer.class);
+
+
+    /**
+     * The size of the socket receive buffer.
+     *
+     * <p> The value of this socket option is an {@code Integer} that is the
+     * size of the socket receive buffer in bytes. The socket receive buffer is
+     * an input buffer used by the networking implementation. It may need to be
+     * increased for high-volume connections or decreased to limit the possible
+     * backlog of incoming data. The value of the socket option is a
+     * <em>hint</em> to the implementation to size the buffer and the actual
+     * size may differ.
+     *
+     * <p> For datagram-oriented sockets, the size of the receive buffer may
+     * limit the size of the datagrams that can be received. Whether datagrams
+     * larger than the buffer size can be received is system dependent.
+     * Increasing the socket receive buffer may be important for cases where
+     * datagrams arrive in bursts faster than they can be processed.
+     *
+     * <p> In the case of stream-oriented sockets and the TCP/IP protocol, the
+     * size of the socket receive buffer may be used when advertising the size
+     * of the TCP receive window to the remote peer.
+     *
+     * <p> The initial/default size of the socket receive buffer and the range
+     * of allowable values is system dependent although a negative size is not
+     * allowed. An attempt to set the socket receive buffer to larger than its
+     * maximum size causes it to be set to its maximum size.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Whether an implementation allows the
+     * socket receive buffer to be changed after the socket is bound is system
+     * dependent.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc1323.txt">RFC&nbsp;1323: TCP
+     * Extensions for High Performance</a>
+     * @see Socket#setReceiveBufferSize
+     * @see ServerSocket#setReceiveBufferSize
+     */
+    public static final SocketOption<Integer> SO_RCVBUF =
+        new StdSocketOption<Integer>("SO_RCVBUF", Integer.class);
+
+    /**
+     * Re-use address.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The exact semantics of this
+     * socket option are socket type and system dependent.
+     *
+     * <p> In the case of stream-oriented sockets, this socket option will
+     * usually determine whether the socket can be bound to a socket address
+     * when a previous connection involving that socket address is in the
+     * <em>TIME_WAIT</em> state. On implementations where the semantics differ,
+     * and the socket option is not required to be enabled in order to bind the
+     * socket when a previous connection is in this state, then the
+     * implementation may choose to ignore this option.
+     *
+     * <p> For datagram-oriented sockets the socket option is used to allow
+     * multiple programs bind to the same address. This option should be enabled
+     * when the socket is to be used for Internet Protocol (IP) multicasting.
+     *
+     * <p> An implementation allows this socket option to be set before the
+     * socket is bound or connected. Changing the value of this socket option
+     * after the socket is bound has no effect. The default value of this
+     * socket option is system dependent.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc793.txt">RFC&nbsp;793: Transmission
+     * Control Protocol</a>
+     * @see ServerSocket#setReuseAddress
+     */
+    public static final SocketOption<Boolean> SO_REUSEADDR =
+        new StdSocketOption<Boolean>("SO_REUSEADDR", Boolean.class);
+
+    /**
+     * Linger on close if data is present.
+     *
+     * <p> The value of this socket option is an {@code Integer} that controls
+     * the action taken when unsent data is queued on the socket and a method
+     * to close the socket is invoked. If the value of the socket option is zero
+     * or greater, then it represents a timeout value, in seconds, known as the
+     * <em>linger interval</em>. The linger interval is the timeout for the
+     * {@code close} method to block while the operating system attempts to
+     * transmit the unsent data or it decides that it is unable to transmit the
+     * data. If the value of the socket option is less than zero then the option
+     * is disabled. In that case the {@code close} method does not wait until
+     * unsent data is transmitted; if possible the operating system will transmit
+     * any unsent data before the connection is closed.
+     *
+     * <p> This socket option is intended for use with sockets that are configured
+     * in {@link java.nio.channels.SelectableChannel#isBlocking() blocking} mode
+     * only. The behavior of the {@code close} method when this option is
+     * enabled on a non-blocking socket is not defined.
+     *
+     * <p> The initial value of this socket option is a negative value, meaning
+     * that the option is disabled. The option may be enabled, or the linger
+     * interval changed, at any time. The maximum value of the linger interval
+     * is system dependent. Setting the linger interval to a value that is
+     * greater than its maximum value causes the linger interval to be set to
+     * its maximum value.
+     *
+     * @see Socket#setSoLinger
+     */
+    public static final SocketOption<Integer> SO_LINGER =
+        new StdSocketOption<Integer>("SO_LINGER", Integer.class);
+
+
+    // -- IPPROTO_IP --
+
+    /**
+     * The Type of Service (ToS) octet in the Internet Protocol (IP) header.
+     *
+     * <p> The value of this socket option is an {@code Integer} representing
+     * the value of the ToS octet in IP packets sent by sockets to an {@link
+     * StandardProtocolFamily#INET IPv4} socket. The interpretation of the ToS
+     * octet is network specific and is not defined by this class. Further
+     * information on the ToS octet can be found in <a
+     * href="http://www.ietf.org/rfc/rfc1349.txt">RFC&nbsp;1349</a> and <a
+     * href="http://www.ietf.org/rfc/rfc2474.txt">RFC&nbsp;2474</a>. The value
+     * of the socket option is a <em>hint</em>. An implementation may ignore the
+     * value, or ignore specific values.
+     *
+     * <p> The initial/default value of the TOS field in the ToS octet is
+     * implementation specific but will typically be {@code 0}. For
+     * datagram-oriented sockets the option may be configured at any time after
+     * the socket has been bound. The new value of the octet is used when sending
+     * subsequent datagrams. It is system dependent whether this option can be
+     * queried or changed prior to binding the socket.
+     *
+     * <p> The behavior of this socket option on a stream-oriented socket, or an
+     * {@link StandardProtocolFamily#INET6 IPv6} socket, is not defined in this
+     * release.
+     *
+     * @see DatagramSocket#setTrafficClass
+     */
+    public static final SocketOption<Integer> IP_TOS =
+        new StdSocketOption<Integer>("IP_TOS", Integer.class);
+
+    /**
+     * The network interface for Internet Protocol (IP) multicast datagrams.
+     *
+     * <p> The value of this socket option is a {@link NetworkInterface} that
+     * represents the outgoing interface for multicast datagrams sent by the
+     * datagram-oriented socket. For {@link StandardProtocolFamily#INET6 IPv6}
+     * sockets then it is system dependent whether setting this option also
+     * sets the outgoing interface for multicast datagrams sent to IPv4
+     * addresses.
+     *
+     * <p> The initial/default value of this socket option may be {@code null}
+     * to indicate that outgoing interface will be selected by the operating
+     * system, typically based on the network routing tables. An implementation
+     * allows this socket option to be set after the socket is bound. Whether
+     * the socket option can be queried or changed prior to binding the socket
+     * is system dependent.
+     *
+     * @see java.nio.channels.MulticastChannel
+     * @see MulticastSocket#setInterface
+     */
+    public static final SocketOption<NetworkInterface> IP_MULTICAST_IF =
+        new StdSocketOption<NetworkInterface>("IP_MULTICAST_IF", NetworkInterface.class);
+
+    /**
+     * The <em>time-to-live</em> for Internet Protocol (IP) multicast datagrams.
+     *
+     * <p> The value of this socket option is an {@code Integer} in the range
+     * {@code 0 <= value <= 255}. It is used to control the scope of multicast
+     * datagrams sent by the datagram-oriented socket.
+     * In the case of an {@link StandardProtocolFamily#INET IPv4} socket
+     * the option is the time-to-live (TTL) on multicast datagrams sent by the
+     * socket. Datagrams with a TTL of zero are not transmitted on the network
+     * but may be delivered locally. In the case of an {@link
+     * StandardProtocolFamily#INET6 IPv6} socket the option is the
+     * <em>hop limit</em> which is number of <em>hops</em> that the datagram can
+     * pass through before expiring on the network. For IPv6 sockets it is
+     * system dependent whether the option also sets the <em>time-to-live</em>
+     * on multicast datagrams sent to IPv4 addresses.
+     *
+     * <p> The initial/default value of the time-to-live setting is typically
+     * {@code 1}. An implementation allows this socket option to be set after
+     * the socket is bound. Whether the socket option can be queried or changed
+     * prior to binding the socket is system dependent.
+     *
+     * @see java.nio.channels.MulticastChannel
+     * @see MulticastSocket#setTimeToLive
+     */
+    public static final SocketOption<Integer> IP_MULTICAST_TTL =
+        new StdSocketOption<Integer>("IP_MULTICAST_TTL", Integer.class);
+
+    /**
+     * Loopback for Internet Protocol (IP) multicast datagrams.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that controls
+     * the <em>loopback</em> of multicast datagrams. The value of the socket
+     * option represents if the option is enabled or disabled.
+     *
+     * <p> The exact semantics of this socket options are system dependent.
+     * In particular, it is system dependent whether the loopback applies to
+     * multicast datagrams sent from the socket or received by the socket.
+     * For {@link StandardProtocolFamily#INET6 IPv6} sockets then it is
+     * system dependent whether the option also applies to multicast datagrams
+     * sent to IPv4 addresses.
+     *
+     * <p> The initial/default value of this socket option is {@code TRUE}. An
+     * implementation allows this socket option to be set after the socket is
+     * bound. Whether the socket option can be queried or changed prior to
+     * binding the socket is system dependent.
+     *
+     * @see java.nio.channels.MulticastChannel
+     *  @see MulticastSocket#setLoopbackMode
+     */
+    public static final SocketOption<Boolean> IP_MULTICAST_LOOP =
+        new StdSocketOption<Boolean>("IP_MULTICAST_LOOP", Boolean.class);
+
+
+    // -- IPPROTO_TCP --
+
+    /**
+     * Disable the Nagle algorithm.
+     *
+     * <p> The value of this socket option is a {@code Boolean} that represents
+     * whether the option is enabled or disabled. The socket option is specific to
+     * stream-oriented sockets using the TCP/IP protocol. TCP/IP uses an algorithm
+     * known as <em>The Nagle Algorithm</em> to coalesce short segments and
+     * improve network efficiency.
+     *
+     * <p> The default value of this socket option is {@code FALSE}. The
+     * socket option should only be enabled in cases where it is known that the
+     * coalescing impacts performance. The socket option may be enabled at any
+     * time. In other words, the Nagle Algorithm can be disabled. Once the option
+     * is enabled, it is system dependent whether it can be subsequently
+     * disabled. If it cannot, then invoking the {@code setOption} method to
+     * disable the option has no effect.
+     *
+     * @see <a href="http://www.ietf.org/rfc/rfc1122.txt">RFC&nbsp;1122:
+     * Requirements for Internet Hosts -- Communication Layers</a>
+     * @see Socket#setTcpNoDelay
+     */
+    public static final SocketOption<Boolean> TCP_NODELAY =
+        new StdSocketOption<Boolean>("TCP_NODELAY", Boolean.class);
+
+
+    private static class StdSocketOption<T> implements SocketOption<T> {
+        private final String name;
+        private final Class<T> type;
+        StdSocketOption(String name, Class<T> type) {
+            this.name = name;
+            this.type = type;
+        }
+        @Override public String name() { return name; }
+        @Override public Class<T> type() { return type; }
+        @Override public String toString() { return name; }
+    }
+}
diff --git a/java/net/URI.java b/java/net/URI.java
new file mode 100644
index 0000000..ebba41b
--- /dev/null
+++ b/java/net/URI.java
@@ -0,0 +1,3602 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.nio.ByteBuffer;
+import java.nio.CharBuffer;
+import java.nio.charset.CharsetDecoder;
+import java.nio.charset.CoderResult;
+import java.nio.charset.CodingErrorAction;
+import java.nio.charset.CharacterCodingException;
+import java.text.Normalizer;
+import sun.nio.cs.ThreadLocalCoders;
+
+import java.lang.Character;             // for javadoc
+import java.lang.NullPointerException;  // for javadoc
+
+
+// Android-changed: Reformat @see links.
+/**
+ * Represents a Uniform Resource Identifier (URI) reference.
+ *
+ * <p> Aside from some minor deviations noted below, an instance of this
+ * class represents a URI reference as defined by
+ * <a href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform
+ * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a
+ * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for
+ * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format
+ * also supports scope_ids. The syntax and usage of scope_ids is described
+ * <a href="Inet6Address.html#scoped">here</a>.
+ * This class provides constructors for creating URI instances from
+ * their components or by parsing their string forms, methods for accessing the
+ * various components of an instance, and methods for normalizing, resolving,
+ * and relativizing URI instances.  Instances of this class are immutable.
+ *
+ *
+ * <h3> URI syntax and components </h3>
+ *
+ * At the highest level a URI reference (hereinafter simply "URI") in string
+ * form has the syntax
+ *
+ * <blockquote>
+ * [<i>scheme</i><b>{@code :}</b>]<i>scheme-specific-part</i>[<b>{@code #}</b><i>fragment</i>]
+ * </blockquote>
+ *
+ * where square brackets [...] delineate optional components and the characters
+ * <b>{@code :}</b> and <b>{@code #}</b> stand for themselves.
+ *
+ * <p> An <i>absolute</i> URI specifies a scheme; a URI that is not absolute is
+ * said to be <i>relative</i>.  URIs are also classified according to whether
+ * they are <i>opaque</i> or <i>hierarchical</i>.
+ *
+ * <p> An <i>opaque</i> URI is an absolute URI whose scheme-specific part does
+ * not begin with a slash character ({@code '/'}).  Opaque URIs are not
+ * subject to further parsing.  Some examples of opaque URIs are:
+ *
+ * <blockquote><table cellpadding=0 cellspacing=0 summary="layout">
+ * <tr><td>{@code mailto:java-net@java.sun.com}<td></tr>
+ * <tr><td>{@code news:comp.lang.java}<td></tr>
+ * <tr><td>{@code urn:isbn:096139210x}</td></tr>
+ * </table></blockquote>
+ *
+ * <p> A <i>hierarchical</i> URI is either an absolute URI whose
+ * scheme-specific part begins with a slash character, or a relative URI, that
+ * is, a URI that does not specify a scheme.  Some examples of hierarchical
+ * URIs are:
+ *
+ * <blockquote>
+ * {@code http://java.sun.com/j2se/1.3/}<br>
+ * {@code docs/guide/collections/designfaq.html#28}<br>
+ * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java}<br>
+ * {@code file:///~/calendar}
+ * </blockquote>
+ *
+ * <p> A hierarchical URI is subject to further parsing according to the syntax
+ *
+ * <blockquote>
+ * [<i>scheme</i><b>{@code :}</b>][<b>{@code //}</b><i>authority</i>][<i>path</i>][<b>{@code ?}</b><i>query</i>][<b>{@code #}</b><i>fragment</i>]
+ * </blockquote>
+ *
+ * where the characters <b>{@code :}</b>, <b>{@code /}</b>,
+ * <b>{@code ?}</b>, and <b>{@code #}</b> stand for themselves.  The
+ * scheme-specific part of a hierarchical URI consists of the characters
+ * between the scheme and fragment components.
+ *
+ * <p> The authority component of a hierarchical URI is, if specified, either
+ * <i>server-based</i> or <i>registry-based</i>.  A server-based authority
+ * parses according to the familiar syntax
+ *
+ * <blockquote>
+ * [<i>user-info</i><b>{@code @}</b>]<i>host</i>[<b>{@code :}</b><i>port</i>]
+ * </blockquote>
+ *
+ * where the characters <b>{@code @}</b> and <b>{@code :}</b> stand for
+ * themselves.  Nearly all URI schemes currently in use are server-based.  An
+ * authority component that does not parse in this way is considered to be
+ * registry-based.
+ *
+ * <p> The path component of a hierarchical URI is itself said to be absolute
+ * if it begins with a slash character ({@code '/'}); otherwise it is
+ * relative.  The path of a hierarchical URI that is either absolute or
+ * specifies an authority is always absolute.
+ *
+ * <p> All told, then, a URI instance has the following nine components:
+ *
+ * <blockquote><table summary="Describes the components of a URI:scheme,scheme-specific-part,authority,user-info,host,port,path,query,fragment">
+ * <tr><th><i>Component</i></th><th><i>Type</i></th></tr>
+ * <tr><td>scheme</td><td>{@code String}</td></tr>
+ * <tr><td>scheme-specific-part&nbsp;&nbsp;&nbsp;&nbsp;</td><td>{@code String}</td></tr>
+ * <tr><td>authority</td><td>{@code String}</td></tr>
+ * <tr><td>user-info</td><td>{@code String}</td></tr>
+ * <tr><td>host</td><td>{@code String}</td></tr>
+ * <tr><td>port</td><td>{@code int}</td></tr>
+ * <tr><td>path</td><td>{@code String}</td></tr>
+ * <tr><td>query</td><td>{@code String}</td></tr>
+ * <tr><td>fragment</td><td>{@code String}</td></tr>
+ * </table></blockquote>
+ *
+ * In a given instance any particular component is either <i>undefined</i> or
+ * <i>defined</i> with a distinct value.  Undefined string components are
+ * represented by {@code null}, while undefined integer components are
+ * represented by {@code -1}.  A string component may be defined to have the
+ * empty string as its value; this is not equivalent to that component being
+ * undefined.
+ *
+ * <p> Whether a particular component is or is not defined in an instance
+ * depends upon the type of the URI being represented.  An absolute URI has a
+ * scheme component.  An opaque URI has a scheme, a scheme-specific part, and
+ * possibly a fragment, but has no other components.  A hierarchical URI always
+ * has a path (though it may be empty) and a scheme-specific-part (which at
+ * least contains the path), and may have any of the other components.  If the
+ * authority component is present and is server-based then the host component
+ * will be defined and the user-information and port components may be defined.
+ *
+ *
+ * <h4> Operations on URI instances </h4>
+ *
+ * The key operations supported by this class are those of
+ * <i>normalization</i>, <i>resolution</i>, and <i>relativization</i>.
+ *
+ * <p> <i>Normalization</i> is the process of removing unnecessary {@code "."}
+ * and {@code ".."} segments from the path component of a hierarchical URI.
+ * Each {@code "."} segment is simply removed.  A {@code ".."} segment is
+ * removed only if it is preceded by a non-{@code ".."} segment.
+ * Normalization has no effect upon opaque URIs.
+ *
+ * <p> <i>Resolution</i> is the process of resolving one URI against another,
+ * <i>base</i> URI.  The resulting URI is constructed from components of both
+ * URIs in the manner specified by RFC&nbsp;2396, taking components from the
+ * base URI for those not specified in the original.  For hierarchical URIs,
+ * the path of the original is resolved against the path of the base and then
+ * normalized.  The result, for example, of resolving
+ *
+ * <blockquote>
+ * {@code docs/guide/collections/designfaq.html#28}
+ * &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+ * &nbsp;&nbsp;&nbsp;&nbsp;(1)
+ * </blockquote>
+ *
+ * against the base URI {@code http://java.sun.com/j2se/1.3/} is the result
+ * URI
+ *
+ * <blockquote>
+ * {@code http://java.sun.com/j2se/1.3/docs/guide/collections/designfaq.html#28}
+ * </blockquote>
+ *
+ * Resolving the relative URI
+ *
+ * <blockquote>
+ * {@code ../../../demo/jfc/SwingSet2/src/SwingSet2.java}&nbsp;&nbsp;&nbsp;&nbsp;(2)
+ * </blockquote>
+ *
+ * against this result yields, in turn,
+ *
+ * <blockquote>
+ * {@code http://java.sun.com/j2se/1.3/demo/jfc/SwingSet2/src/SwingSet2.java}
+ * </blockquote>
+ *
+ * Resolution of both absolute and relative URIs, and of both absolute and
+ * relative paths in the case of hierarchical URIs, is supported.  Resolving
+ * the URI {@code file:///~calendar} against any other URI simply yields the
+ * original URI, since it is absolute.  Resolving the relative URI (2) above
+ * against the relative base URI (1) yields the normalized, but still relative,
+ * URI
+ *
+ * <blockquote>
+ * {@code demo/jfc/SwingSet2/src/SwingSet2.java}
+ * </blockquote>
+ *
+ * <p> <i>Relativization</i>, finally, is the inverse of resolution: For any
+ * two normalized URIs <i>u</i> and&nbsp;<i>v</i>,
+ *
+ * <blockquote>
+ *   <i>u</i>{@code .relativize(}<i>u</i>{@code .resolve(}<i>v</i>{@code )).equals(}<i>v</i>{@code )}&nbsp;&nbsp;and<br>
+ *   <i>u</i>{@code .resolve(}<i>u</i>{@code .relativize(}<i>v</i>{@code )).equals(}<i>v</i>{@code )}&nbsp;&nbsp;.<br>
+ * </blockquote>
+ *
+ * This operation is often useful when constructing a document containing URIs
+ * that must be made relative to the base URI of the document wherever
+ * possible.  For example, relativizing the URI
+ *
+ * <blockquote>
+ * {@code http://java.sun.com/j2se/1.3/docs/guide/index.html}
+ * </blockquote>
+ *
+ * against the base URI
+ *
+ * <blockquote>
+ * {@code http://java.sun.com/j2se/1.3}
+ * </blockquote>
+ *
+ * yields the relative URI {@code docs/guide/index.html}.
+ *
+ *
+ * <h4> Character categories </h4>
+ *
+ * RFC&nbsp;2396 specifies precisely which characters are permitted in the
+ * various components of a URI reference.  The following categories, most of
+ * which are taken from that specification, are used below to describe these
+ * constraints:
+ *
+ * <blockquote><table cellspacing=2 summary="Describes categories alpha,digit,alphanum,unreserved,punct,reserved,escaped,and other">
+ *   <tr><th valign=top><i>alpha</i></th>
+ *       <td>The US-ASCII alphabetic characters,
+ *        {@code 'A'}&nbsp;through&nbsp;{@code 'Z'}
+ *        and {@code 'a'}&nbsp;through&nbsp;{@code 'z'}</td></tr>
+ *   <tr><th valign=top><i>digit</i></th>
+ *       <td>The US-ASCII decimal digit characters,
+ *       {@code '0'}&nbsp;through&nbsp;{@code '9'}</td></tr>
+ *   <tr><th valign=top><i>alphanum</i></th>
+ *       <td>All <i>alpha</i> and <i>digit</i> characters</td></tr>
+ *   <tr><th valign=top><i>unreserved</i>&nbsp;&nbsp;&nbsp;&nbsp;</th>
+ *       <td>All <i>alphanum</i> characters together with those in the string
+ *        {@code "_-!.~'()*"}</td></tr>
+ *   <tr><th valign=top><i>punct</i></th>
+ *       <td>The characters in the string {@code ",;:$&+="}</td></tr>
+ *   <tr><th valign=top><i>reserved</i></th>
+ *       <td>All <i>punct</i> characters together with those in the string
+ *        {@code "?/[]@"}</td></tr>
+ *   <tr><th valign=top><i>escaped</i></th>
+ *       <td>Escaped octets, that is, triplets consisting of the percent
+ *           character ({@code '%'}) followed by two hexadecimal digits
+ *           ({@code '0'}-{@code '9'}, {@code 'A'}-{@code 'F'}, and
+ *           {@code 'a'}-{@code 'f'})</td></tr>
+ *   <tr><th valign=top><i>other</i></th>
+ *       <td>The Unicode characters that are not in the US-ASCII character set,
+ *           are not control characters (according to the {@link
+ *           java.lang.Character#isISOControl(char) Character.isISOControl}
+ *           method), and are not space characters (according to the {@link
+ *           java.lang.Character#isSpaceChar(char) Character.isSpaceChar}
+ *           method)&nbsp;&nbsp;<i>(<b>Deviation from RFC 2396</b>, which is
+ *           limited to US-ASCII)</i></td></tr>
+ * </table></blockquote>
+ *
+ * <p><a name="legal-chars"></a> The set of all legal URI characters consists of
+ * the <i>unreserved</i>, <i>reserved</i>, <i>escaped</i>, and <i>other</i>
+ * characters.
+ *
+ *
+ * <h4> Escaped octets, quotation, encoding, and decoding </h4>
+ *
+ * RFC 2396 allows escaped octets to appear in the user-info, path, query, and
+ * fragment components.  Escaping serves two purposes in URIs:
+ *
+ * <ul>
+ *
+ *   <li><p> To <i>encode</i> non-US-ASCII characters when a URI is required to
+ *   conform strictly to RFC&nbsp;2396 by not containing any <i>other</i>
+ *   characters.  </p></li>
+ *
+ *   <li><p> To <i>quote</i> characters that are otherwise illegal in a
+ *   component.  The user-info, path, query, and fragment components differ
+ *   slightly in terms of which characters are considered legal and illegal.
+ *   </p></li>
+ *
+ * </ul>
+ *
+ * These purposes are served in this class by three related operations:
+ *
+ * <ul>
+ *
+ *   <li><p><a name="encode"></a> A character is <i>encoded</i> by replacing it
+ *   with the sequence of escaped octets that represent that character in the
+ *   UTF-8 character set.  The Euro currency symbol ({@code '\u005Cu20AC'}),
+ *   for example, is encoded as {@code "%E2%82%AC"}.  <i>(<b>Deviation from
+ *   RFC&nbsp;2396</b>, which does not specify any particular character
+ *   set.)</i> </p></li>
+ *
+ *   <li><p><a name="quote"></a> An illegal character is <i>quoted</i> simply by
+ *   encoding it.  The space character, for example, is quoted by replacing it
+ *   with {@code "%20"}.  UTF-8 contains US-ASCII, hence for US-ASCII
+ *   characters this transformation has exactly the effect required by
+ *   RFC&nbsp;2396. </p></li>
+ *
+ *   <li><p><a name="decode"></a>
+ *   A sequence of escaped octets is <i>decoded</i> by
+ *   replacing it with the sequence of characters that it represents in the
+ *   UTF-8 character set.  UTF-8 contains US-ASCII, hence decoding has the
+ *   effect of de-quoting any quoted US-ASCII characters as well as that of
+ *   decoding any encoded non-US-ASCII characters.  If a <a
+ *   href="../nio/charset/CharsetDecoder.html#ce">decoding error</a> occurs
+ *   when decoding the escaped octets then the erroneous octets are replaced by
+ *   {@code '\u005CuFFFD'}, the Unicode replacement character.  </p></li>
+ *
+ * </ul>
+ *
+ * These operations are exposed in the constructors and methods of this class
+ * as follows:
+ *
+ * <ul>
+ *
+ *   <li><p> The {@linkplain #URI(java.lang.String) single-argument
+ *   constructor} requires any illegal characters in its argument to be
+ *   quoted and preserves any escaped octets and <i>other</i> characters that
+ *   are present.  </p></li>
+ *
+ *   <li><p> The {@linkplain
+ *   #URI(java.lang.String,java.lang.String,java.lang.String,int,java.lang.String,java.lang.String,java.lang.String)
+ *   multi-argument constructors} quote illegal characters as
+ *   required by the components in which they appear.  The percent character
+ *   ({@code '%'}) is always quoted by these constructors.  Any <i>other</i>
+ *   characters are preserved.  </p></li>
+ *
+ *   <li><p> The {@link #getRawUserInfo() getRawUserInfo}, {@link #getRawPath()
+ *   getRawPath}, {@link #getRawQuery() getRawQuery}, {@link #getRawFragment()
+ *   getRawFragment}, {@link #getRawAuthority() getRawAuthority}, and {@link
+ *   #getRawSchemeSpecificPart() getRawSchemeSpecificPart} methods return the
+ *   values of their corresponding components in raw form, without interpreting
+ *   any escaped octets.  The strings returned by these methods may contain
+ *   both escaped octets and <i>other</i> characters, and will not contain any
+ *   illegal characters.  </p></li>
+ *
+ *   <li><p> The {@link #getUserInfo() getUserInfo}, {@link #getPath()
+ *   getPath}, {@link #getQuery() getQuery}, {@link #getFragment()
+ *   getFragment}, {@link #getAuthority() getAuthority}, and {@link
+ *   #getSchemeSpecificPart() getSchemeSpecificPart} methods decode any escaped
+ *   octets in their corresponding components.  The strings returned by these
+ *   methods may contain both <i>other</i> characters and illegal characters,
+ *   and will not contain any escaped octets.  </p></li>
+ *
+ *   <li><p> The {@link #toString() toString} method returns a URI string with
+ *   all necessary quotation but which may contain <i>other</i> characters.
+ *   </p></li>
+ *
+ *   <li><p> The {@link #toASCIIString() toASCIIString} method returns a fully
+ *   quoted and encoded URI string that does not contain any <i>other</i>
+ *   characters.  </p></li>
+ *
+ * </ul>
+ *
+ *
+ * <h4> Identities </h4>
+ *
+ * For any URI <i>u</i>, it is always the case that
+ *
+ * <blockquote>
+ * {@code new URI(}<i>u</i>{@code .toString()).equals(}<i>u</i>{@code )}&nbsp;.
+ * </blockquote>
+ *
+ * For any URI <i>u</i> that does not contain redundant syntax such as two
+ * slashes before an empty authority (as in {@code file:///tmp/}&nbsp;) or a
+ * colon following a host name but no port (as in
+ * {@code http://java.sun.com:}&nbsp;), and that does not encode characters
+ * except those that must be quoted, the following identities also hold:
+ * <pre>
+ *     new URI(<i>u</i>.getScheme(),
+ *             <i>u</i>.getSchemeSpecificPart(),
+ *             <i>u</i>.getFragment())
+ *     .equals(<i>u</i>)</pre>
+ * in all cases,
+ * <pre>
+ *     new URI(<i>u</i>.getScheme(),
+ *             <i>u</i>.getUserInfo(), <i>u</i>.getAuthority(),
+ *             <i>u</i>.getPath(), <i>u</i>.getQuery(),
+ *             <i>u</i>.getFragment())
+ *     .equals(<i>u</i>)</pre>
+ * if <i>u</i> is hierarchical, and
+ * <pre>
+ *     new URI(<i>u</i>.getScheme(),
+ *             <i>u</i>.getUserInfo(), <i>u</i>.getHost(), <i>u</i>.getPort(),
+ *             <i>u</i>.getPath(), <i>u</i>.getQuery(),
+ *             <i>u</i>.getFragment())
+ *     .equals(<i>u</i>)</pre>
+ * if <i>u</i> is hierarchical and has either no authority or a server-based
+ * authority.
+ *
+ *
+ * <h4> URIs, URLs, and URNs </h4>
+ *
+ * A URI is a uniform resource <i>identifier</i> while a URL is a uniform
+ * resource <i>locator</i>.  Hence every URL is a URI, abstractly speaking, but
+ * not every URI is a URL.  This is because there is another subcategory of
+ * URIs, uniform resource <i>names</i> (URNs), which name resources but do not
+ * specify how to locate them.  The {@code mailto}, {@code news}, and
+ * {@code isbn} URIs shown above are examples of URNs.
+ *
+ * <p> The conceptual distinction between URIs and URLs is reflected in the
+ * differences between this class and the {@link URL} class.
+ *
+ * <p> An instance of this class represents a URI reference in the syntactic
+ * sense defined by RFC&nbsp;2396.  A URI may be either absolute or relative.
+ * A URI string is parsed according to the generic syntax without regard to the
+ * scheme, if any, that it specifies.  No lookup of the host, if any, is
+ * performed, and no scheme-dependent stream handler is constructed.  Equality,
+ * hashing, and comparison are defined strictly in terms of the character
+ * content of the instance.  In other words, a URI instance is little more than
+ * a structured string that supports the syntactic, scheme-independent
+ * operations of comparison, normalization, resolution, and relativization.
+ *
+ * <p> An instance of the {@link URL} class, by contrast, represents the
+ * syntactic components of a URL together with some of the information required
+ * to access the resource that it describes.  A URL must be absolute, that is,
+ * it must always specify a scheme.  A URL string is parsed according to its
+ * scheme.  A stream handler is always established for a URL, and in fact it is
+ * impossible to create a URL instance for a scheme for which no handler is
+ * available.  Equality and hashing depend upon both the scheme and the
+ * Internet address of the host, if any; comparison is not defined.  In other
+ * words, a URL is a structured string that supports the syntactic operation of
+ * resolution as well as the network I/O operations of looking up the host and
+ * opening a connection to the specified resource.
+ *
+ *
+ * @author Mark Reinhold
+ * @since 1.4
+ *
+ * @see <a href="http://www.ietf.org/rfc/rfc2279.txt">RFC&nbsp;2279: UTF-8, a transformation format of ISO 10646</a>
+ * @see <a href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373: IPv6 Addressing Architecture</a>
+ * @see <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396: Uniform Resource Identifiers (URI): Generic Syntax</a>
+ * @see <a href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732: Format for Literal IPv6 Addresses in URLs</a>
+ */
+
+public final class URI
+    implements Comparable<URI>, Serializable
+{
+
+    // Note: Comments containing the word "ASSERT" indicate places where a
+    // throw of an InternalError should be replaced by an appropriate assertion
+    // statement once asserts are enabled in the build.
+
+    static final long serialVersionUID = -6052424284110960213L;
+
+
+    // -- Properties and components of this instance --
+
+    // Components of all URIs: [<scheme>:]<scheme-specific-part>[#<fragment>]
+    private transient String scheme;            // null ==> relative URI
+    private transient String fragment;
+
+    // Hierarchical URI components: [//<authority>]<path>[?<query>]
+    private transient String authority;         // Registry or server
+
+    // Server-based authority: [<userInfo>@]<host>[:<port>]
+    private transient String userInfo;
+    private transient String host;              // null ==> registry-based
+    private transient int port = -1;            // -1 ==> undefined
+
+    // Remaining components of hierarchical URIs
+    private transient String path;              // null ==> opaque
+    private transient String query;
+
+    // The remaining fields may be computed on demand
+
+    private volatile transient String schemeSpecificPart;
+    private volatile transient int hash;        // Zero ==> undefined
+
+    private volatile transient String decodedUserInfo = null;
+    private volatile transient String decodedAuthority = null;
+    private volatile transient String decodedPath = null;
+    private volatile transient String decodedQuery = null;
+    private volatile transient String decodedFragment = null;
+    private volatile transient String decodedSchemeSpecificPart = null;
+
+    /**
+     * The string form of this URI.
+     *
+     * @serial
+     */
+    private volatile String string;             // The only serializable field
+
+
+
+    // -- Constructors and factories --
+
+    private URI() { }                           // Used internally
+
+    /**
+     * Constructs a URI by parsing the given string.
+     *
+     * <p> This constructor parses the given string exactly as specified by the
+     * grammar in <a
+     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
+     * Appendix&nbsp;A, <b><i>except for the following deviations:</i></b> </p>
+     *
+     * <ul>
+     *
+     *   <li><p> An empty authority component is permitted as long as it is
+     *   followed by a non-empty path, a query component, or a fragment
+     *   component.  This allows the parsing of URIs such as
+     *   {@code "file:///foo/bar"}, which seems to be the intent of
+     *   RFC&nbsp;2396 although the grammar does not permit it.  If the
+     *   authority component is empty then the user-information, host, and port
+     *   components are undefined. </p></li>
+     *
+     *   <li><p> Empty relative paths are permitted; this seems to be the
+     *   intent of RFC&nbsp;2396 although the grammar does not permit it.  The
+     *   primary consequence of this deviation is that a standalone fragment
+     *   such as {@code "#foo"} parses as a relative URI with an empty path
+     *   and the given fragment, and can be usefully <a
+     *   href="#resolve-frag">resolved</a> against a base URI.
+     *
+     *   <li><p> IPv4 addresses in host components are parsed rigorously, as
+     *   specified by <a
+     *   href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>: Each
+     *   element of a dotted-quad address must contain no more than three
+     *   decimal digits.  Each element is further constrained to have a value
+     *   no greater than 255. </p></li>
+     *
+     *   <li> <p> Hostnames in host components that comprise only a single
+     *   domain label are permitted to start with an <i>alphanum</i>
+     *   character. This seems to be the intent of <a
+     *   href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>
+     *   section&nbsp;3.2.2 although the grammar does not permit it. The
+     *   consequence of this deviation is that the authority component of a
+     *   hierarchical URI such as {@code s://123}, will parse as a server-based
+     *   authority. </p></li>
+     *
+     *   <li><p> IPv6 addresses are permitted for the host component.  An IPv6
+     *   address must be enclosed in square brackets ({@code '['} and
+     *   {@code ']'}) as specified by <a
+     *   href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>.  The
+     *   IPv6 address itself must parse according to <a
+     *   href="http://www.ietf.org/rfc/rfc2373.txt">RFC&nbsp;2373</a>.  IPv6
+     *   addresses are further constrained to describe no more than sixteen
+     *   bytes of address information, a constraint implicit in RFC&nbsp;2373
+     *   but not expressible in the grammar. </p></li>
+     *
+     *   <li><p> Characters in the <i>other</i> category are permitted wherever
+     *   RFC&nbsp;2396 permits <i>escaped</i> octets, that is, in the
+     *   user-information, path, query, and fragment components, as well as in
+     *   the authority component if the authority is registry-based.  This
+     *   allows URIs to contain Unicode characters beyond those in the US-ASCII
+     *   character set. </p></li>
+     *
+     * </ul>
+     *
+     * @param  str   The string to be parsed into a URI
+     *
+     * @throws  NullPointerException
+     *          If {@code str} is {@code null}
+     *
+     * @throws  URISyntaxException
+     *          If the given string violates RFC&nbsp;2396, as augmented
+     *          by the above deviations
+     */
+    public URI(String str) throws URISyntaxException {
+        new Parser(str).parse(false);
+    }
+
+    /**
+     * Constructs a hierarchical URI from the given components.
+     *
+     * <p> If a scheme is given then the path, if also given, must either be
+     * empty or begin with a slash character ({@code '/'}).  Otherwise a
+     * component of the new URI may be left undefined by passing {@code null}
+     * for the corresponding parameter or, in the case of the {@code port}
+     * parameter, by passing {@code -1}.
+     *
+     * <p> This constructor first builds a URI string from the given components
+     * according to the rules specified in <a
+     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
+     * section&nbsp;5.2, step&nbsp;7: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> Initially, the result string is empty. </p></li>
+     *
+     *   <li><p> If a scheme is given then it is appended to the result,
+     *   followed by a colon character ({@code ':'}).  </p></li>
+     *
+     *   <li><p> If user information, a host, or a port are given then the
+     *   string {@code "//"} is appended.  </p></li>
+     *
+     *   <li><p> If user information is given then it is appended, followed by
+     *   a commercial-at character ({@code '@'}).  Any character not in the
+     *   <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
+     *   categories is <a href="#quote">quoted</a>.  </p></li>
+     *
+     *   <li><p> If a host is given then it is appended.  If the host is a
+     *   literal IPv6 address but is not enclosed in square brackets
+     *   ({@code '['} and {@code ']'}) then the square brackets are added.
+     *   </p></li>
+     *
+     *   <li><p> If a port number is given then a colon character
+     *   ({@code ':'}) is appended, followed by the port number in decimal.
+     *   </p></li>
+     *
+     *   <li><p> If a path is given then it is appended.  Any character not in
+     *   the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
+     *   categories, and not equal to the slash character ({@code '/'}) or the
+     *   commercial-at character ({@code '@'}), is quoted.  </p></li>
+     *
+     *   <li><p> If a query is given then a question-mark character
+     *   ({@code '?'}) is appended, followed by the query.  Any character that
+     *   is not a <a href="#legal-chars">legal URI character</a> is quoted.
+     *   </p></li>
+     *
+     *   <li><p> Finally, if a fragment is given then a hash character
+     *   ({@code '#'}) is appended, followed by the fragment.  Any character
+     *   that is not a legal URI character is quoted.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> The resulting URI string is then parsed as if by invoking the {@link
+     * #URI(String)} constructor and then invoking the {@link
+     * #parseServerAuthority()} method upon the result; this may cause a {@link
+     * URISyntaxException} to be thrown.  </p>
+     *
+     * @param   scheme    Scheme name
+     * @param   userInfo  User name and authorization information
+     * @param   host      Host name
+     * @param   port      Port number
+     * @param   path      Path
+     * @param   query     Query
+     * @param   fragment  Fragment
+     *
+     * @throws URISyntaxException
+     *         If both a scheme and a path are given but the path is relative,
+     *         if the URI string constructed from the given components violates
+     *         RFC&nbsp;2396, or if the authority component of the string is
+     *         present but cannot be parsed as a server-based authority
+     */
+    public URI(String scheme,
+               String userInfo, String host, int port,
+               String path, String query, String fragment)
+        throws URISyntaxException
+    {
+        String s = toString(scheme, null,
+                            null, userInfo, host, port,
+                            path, query, fragment);
+        checkPath(s, scheme, path);
+        new Parser(s).parse(true);
+    }
+
+    /**
+     * Constructs a hierarchical URI from the given components.
+     *
+     * <p> If a scheme is given then the path, if also given, must either be
+     * empty or begin with a slash character ({@code '/'}).  Otherwise a
+     * component of the new URI may be left undefined by passing {@code null}
+     * for the corresponding parameter.
+     *
+     * <p> This constructor first builds a URI string from the given components
+     * according to the rules specified in <a
+     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
+     * section&nbsp;5.2, step&nbsp;7: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> Initially, the result string is empty.  </p></li>
+     *
+     *   <li><p> If a scheme is given then it is appended to the result,
+     *   followed by a colon character ({@code ':'}).  </p></li>
+     *
+     *   <li><p> If an authority is given then the string {@code "//"} is
+     *   appended, followed by the authority.  If the authority contains a
+     *   literal IPv6 address then the address must be enclosed in square
+     *   brackets ({@code '['} and {@code ']'}).  Any character not in the
+     *   <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
+     *   categories, and not equal to the commercial-at character
+     *   ({@code '@'}), is <a href="#quote">quoted</a>.  </p></li>
+     *
+     *   <li><p> If a path is given then it is appended.  Any character not in
+     *   the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, or <i>other</i>
+     *   categories, and not equal to the slash character ({@code '/'}) or the
+     *   commercial-at character ({@code '@'}), is quoted.  </p></li>
+     *
+     *   <li><p> If a query is given then a question-mark character
+     *   ({@code '?'}) is appended, followed by the query.  Any character that
+     *   is not a <a href="#legal-chars">legal URI character</a> is quoted.
+     *   </p></li>
+     *
+     *   <li><p> Finally, if a fragment is given then a hash character
+     *   ({@code '#'}) is appended, followed by the fragment.  Any character
+     *   that is not a legal URI character is quoted.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> The resulting URI string is then parsed as if by invoking the {@link
+     * #URI(String)} constructor and then invoking the {@link
+     * #parseServerAuthority()} method upon the result; this may cause a {@link
+     * URISyntaxException} to be thrown.  </p>
+     *
+     * @param   scheme     Scheme name
+     * @param   authority  Authority
+     * @param   path       Path
+     * @param   query      Query
+     * @param   fragment   Fragment
+     *
+     * @throws URISyntaxException
+     *         If both a scheme and a path are given but the path is relative,
+     *         if the URI string constructed from the given components violates
+     *         RFC&nbsp;2396, or if the authority component of the string is
+     *         present but cannot be parsed as a server-based authority
+     */
+    public URI(String scheme,
+               String authority,
+               String path, String query, String fragment)
+        throws URISyntaxException
+    {
+        String s = toString(scheme, null,
+                            authority, null, null, -1,
+                            path, query, fragment);
+        checkPath(s, scheme, path);
+        new Parser(s).parse(false);
+    }
+
+    /**
+     * Constructs a hierarchical URI from the given components.
+     *
+     * <p> A component may be left undefined by passing {@code null}.
+     *
+     * <p> This convenience constructor works as if by invoking the
+     * seven-argument constructor as follows:
+     *
+     * <blockquote>
+     * {@code new} {@link #URI(String, String, String, int, String, String, String)
+     * URI}{@code (scheme, null, host, -1, path, null, fragment);}
+     * </blockquote>
+     *
+     * @param   scheme    Scheme name
+     * @param   host      Host name
+     * @param   path      Path
+     * @param   fragment  Fragment
+     *
+     * @throws  URISyntaxException
+     *          If the URI string constructed from the given components
+     *          violates RFC&nbsp;2396
+     */
+    public URI(String scheme, String host, String path, String fragment)
+        throws URISyntaxException
+    {
+        this(scheme, null, host, -1, path, null, fragment);
+    }
+
+    /**
+     * Constructs a URI from the given components.
+     *
+     * <p> A component may be left undefined by passing {@code null}.
+     *
+     * <p> This constructor first builds a URI in string form using the given
+     * components as follows:  </p>
+     *
+     * <ol>
+     *
+     *   <li><p> Initially, the result string is empty.  </p></li>
+     *
+     *   <li><p> If a scheme is given then it is appended to the result,
+     *   followed by a colon character ({@code ':'}).  </p></li>
+     *
+     *   <li><p> If a scheme-specific part is given then it is appended.  Any
+     *   character that is not a <a href="#legal-chars">legal URI character</a>
+     *   is <a href="#quote">quoted</a>.  </p></li>
+     *
+     *   <li><p> Finally, if a fragment is given then a hash character
+     *   ({@code '#'}) is appended to the string, followed by the fragment.
+     *   Any character that is not a legal URI character is quoted.  </p></li>
+     *
+     * </ol>
+     *
+     * <p> The resulting URI string is then parsed in order to create the new
+     * URI instance as if by invoking the {@link #URI(String)} constructor;
+     * this may cause a {@link URISyntaxException} to be thrown.  </p>
+     *
+     * @param   scheme    Scheme name
+     * @param   ssp       Scheme-specific part
+     * @param   fragment  Fragment
+     *
+     * @throws  URISyntaxException
+     *          If the URI string constructed from the given components
+     *          violates RFC&nbsp;2396
+     */
+    public URI(String scheme, String ssp, String fragment)
+        throws URISyntaxException
+    {
+        new Parser(toString(scheme, ssp,
+                            null, null, null, -1,
+                            null, null, fragment))
+            .parse(false);
+    }
+
+    /**
+     * Creates a URI by parsing the given string.
+     *
+     * <p> This convenience factory method works as if by invoking the {@link
+     * #URI(String)} constructor; any {@link URISyntaxException} thrown by the
+     * constructor is caught and wrapped in a new {@link
+     * IllegalArgumentException} object, which is then thrown.
+     *
+     * <p> This method is provided for use in situations where it is known that
+     * the given string is a legal URI, for example for URI constants declared
+     * within in a program, and so it would be considered a programming error
+     * for the string not to parse as such.  The constructors, which throw
+     * {@link URISyntaxException} directly, should be used situations where a
+     * URI is being constructed from user input or from some other source that
+     * may be prone to errors.  </p>
+     *
+     * @param  str   The string to be parsed into a URI
+     * @return The new URI
+     *
+     * @throws  NullPointerException
+     *          If {@code str} is {@code null}
+     *
+     * @throws  IllegalArgumentException
+     *          If the given string violates RFC&nbsp;2396
+     */
+    public static URI create(String str) {
+        try {
+            return new URI(str);
+        } catch (URISyntaxException x) {
+            throw new IllegalArgumentException(x.getMessage(), x);
+        }
+    }
+
+
+    // -- Operations --
+
+    /**
+     * Attempts to parse this URI's authority component, if defined, into
+     * user-information, host, and port components.
+     *
+     * <p> If this URI's authority component has already been recognized as
+     * being server-based then it will already have been parsed into
+     * user-information, host, and port components.  In this case, or if this
+     * URI has no authority component, this method simply returns this URI.
+     *
+     * <p> Otherwise this method attempts once more to parse the authority
+     * component into user-information, host, and port components, and throws
+     * an exception describing why the authority component could not be parsed
+     * in that way.
+     *
+     * <p> This method is provided because the generic URI syntax specified in
+     * <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>
+     * cannot always distinguish a malformed server-based authority from a
+     * legitimate registry-based authority.  It must therefore treat some
+     * instances of the former as instances of the latter.  The authority
+     * component in the URI string {@code "//foo:bar"}, for example, is not a
+     * legal server-based authority but it is legal as a registry-based
+     * authority.
+     *
+     * <p> In many common situations, for example when working URIs that are
+     * known to be either URNs or URLs, the hierarchical URIs being used will
+     * always be server-based.  They therefore must either be parsed as such or
+     * treated as an error.  In these cases a statement such as
+     *
+     * <blockquote>
+     * {@code URI }<i>u</i>{@code  = new URI(str).parseServerAuthority();}
+     * </blockquote>
+     *
+     * <p> can be used to ensure that <i>u</i> always refers to a URI that, if
+     * it has an authority component, has a server-based authority with proper
+     * user-information, host, and port components.  Invoking this method also
+     * ensures that if the authority could not be parsed in that way then an
+     * appropriate diagnostic message can be issued based upon the exception
+     * that is thrown. </p>
+     *
+     * @return  A URI whose authority field has been parsed
+     *          as a server-based authority
+     *
+     * @throws  URISyntaxException
+     *          If the authority component of this URI is defined
+     *          but cannot be parsed as a server-based authority
+     *          according to RFC&nbsp;2396
+     */
+    public URI parseServerAuthority()
+        throws URISyntaxException
+    {
+        // We could be clever and cache the error message and index from the
+        // exception thrown during the original parse, but that would require
+        // either more fields or a more-obscure representation.
+        if ((host != null) || (authority == null))
+            return this;
+        defineString();
+        new Parser(string).parse(true);
+        return this;
+    }
+
+    /**
+     * Normalizes this URI's path.
+     *
+     * <p> If this URI is opaque, or if its path is already in normal form,
+     * then this URI is returned.  Otherwise a new URI is constructed that is
+     * identical to this URI except that its path is computed by normalizing
+     * this URI's path in a manner consistent with <a
+     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
+     * section&nbsp;5.2, step&nbsp;6, sub-steps&nbsp;c through&nbsp;f; that is:
+     * </p>
+     *
+     * <ol>
+     *
+     *   <li><p> All {@code "."} segments are removed. </p></li>
+     *
+     *   <li><p> If a {@code ".."} segment is preceded by a non-{@code ".."}
+     *   segment then both of these segments are removed.  This step is
+     *   repeated until it is no longer applicable. </p></li>
+     *
+     *   <li><p> If the path is relative, and if its first segment contains a
+     *   colon character ({@code ':'}), then a {@code "."} segment is
+     *   prepended.  This prevents a relative URI with a path such as
+     *   {@code "a:b/c/d"} from later being re-parsed as an opaque URI with a
+     *   scheme of {@code "a"} and a scheme-specific part of {@code "b/c/d"}.
+     *   <b><i>(Deviation from RFC&nbsp;2396)</i></b> </p></li>
+     *
+     * </ol>
+     *
+     * <p> A normalized path will begin with one or more {@code ".."} segments
+     * if there were insufficient non-{@code ".."} segments preceding them to
+     * allow their removal.  A normalized path will begin with a {@code "."}
+     * segment if one was inserted by step 3 above.  Otherwise, a normalized
+     * path will not contain any {@code "."} or {@code ".."} segments. </p>
+     *
+     * @return  A URI equivalent to this URI,
+     *          but whose path is in normal form
+     */
+    public URI normalize() {
+        return normalize(this);
+    }
+
+    /**
+     * Resolves the given URI against this URI.
+     *
+     * <p> If the given URI is already absolute, or if this URI is opaque, then
+     * the given URI is returned.
+     *
+     * <p><a name="resolve-frag"></a> If the given URI's fragment component is
+     * defined, its path component is empty, and its scheme, authority, and
+     * query components are undefined, then a URI with the given fragment but
+     * with all other components equal to those of this URI is returned.  This
+     * allows a URI representing a standalone fragment reference, such as
+     * {@code "#foo"}, to be usefully resolved against a base URI.
+     *
+     * <p> Otherwise this method constructs a new hierarchical URI in a manner
+     * consistent with <a
+     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
+     * section&nbsp;5.2; that is: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> A new URI is constructed with this URI's scheme and the given
+     *   URI's query and fragment components. </p></li>
+     *
+     *   <li><p> If the given URI has an authority component then the new URI's
+     *   authority and path are taken from the given URI. </p></li>
+     *
+     *   <li><p> Otherwise the new URI's authority component is copied from
+     *   this URI, and its path is computed as follows: </p>
+     *
+     *   <ol>
+     *
+     *     <li><p> If the given URI's path is absolute then the new URI's path
+     *     is taken from the given URI. </p></li>
+     *
+     *     <li><p> Otherwise the given URI's path is relative, and so the new
+     *     URI's path is computed by resolving the path of the given URI
+     *     against the path of this URI.  This is done by concatenating all but
+     *     the last segment of this URI's path, if any, with the given URI's
+     *     path and then normalizing the result as if by invoking the {@link
+     *     #normalize() normalize} method. </p></li>
+     *
+     *   </ol></li>
+     *
+     * </ol>
+     *
+     * <p> The result of this method is absolute if, and only if, either this
+     * URI is absolute or the given URI is absolute.  </p>
+     *
+     * @param  uri  The URI to be resolved against this URI
+     * @return The resulting URI
+     *
+     * @throws  NullPointerException
+     *          If {@code uri} is {@code null}
+     */
+    public URI resolve(URI uri) {
+        return resolve(this, uri);
+    }
+
+    /**
+     * Constructs a new URI by parsing the given string and then resolving it
+     * against this URI.
+     *
+     * <p> This convenience method works as if invoking it were equivalent to
+     * evaluating the expression {@link #resolve(java.net.URI)
+     * resolve}{@code (URI.}{@link #create(String) create}{@code (str))}. </p>
+     *
+     * @param  str   The string to be parsed into a URI
+     * @return The resulting URI
+     *
+     * @throws  NullPointerException
+     *          If {@code str} is {@code null}
+     *
+     * @throws  IllegalArgumentException
+     *          If the given string violates RFC&nbsp;2396
+     */
+    public URI resolve(String str) {
+        return resolve(URI.create(str));
+    }
+
+    /**
+     * Relativizes the given URI against this URI.
+     *
+     * <p> The relativization of the given URI against this URI is computed as
+     * follows: </p>
+     *
+     * <ol>
+     *
+     *   <li><p> If either this URI or the given URI are opaque, or if the
+     *   scheme and authority components of the two URIs are not identical, or
+     *   if the path of this URI is not a prefix of the path of the given URI,
+     *   then the given URI is returned. </p></li>
+     *
+     *   <li><p> Otherwise a new relative hierarchical URI is constructed with
+     *   query and fragment components taken from the given URI and with a path
+     *   component computed by removing this URI's path from the beginning of
+     *   the given URI's path. </p></li>
+     *
+     * </ol>
+     *
+     * @param  uri  The URI to be relativized against this URI
+     * @return The resulting URI
+     *
+     * @throws  NullPointerException
+     *          If {@code uri} is {@code null}
+     */
+    public URI relativize(URI uri) {
+        return relativize(this, uri);
+    }
+
+    /**
+     * Constructs a URL from this URI.
+     *
+     * <p> This convenience method works as if invoking it were equivalent to
+     * evaluating the expression {@code new URL(this.toString())} after
+     * first checking that this URI is absolute. </p>
+     *
+     * @return  A URL constructed from this URI
+     *
+     * @throws  IllegalArgumentException
+     *          If this URL is not absolute
+     *
+     * @throws  MalformedURLException
+     *          If a protocol handler for the URL could not be found,
+     *          or if some other error occurred while constructing the URL
+     */
+    public URL toURL()
+        throws MalformedURLException {
+        if (!isAbsolute())
+            throw new IllegalArgumentException("URI is not absolute");
+        return new URL(toString());
+    }
+
+    // -- Component access methods --
+
+    /**
+     * Returns the scheme component of this URI.
+     *
+     * <p> The scheme component of a URI, if defined, only contains characters
+     * in the <i>alphanum</i> category and in the string {@code "-.+"}.  A
+     * scheme always starts with an <i>alpha</i> character. <p>
+     *
+     * The scheme component of a URI cannot contain escaped octets, hence this
+     * method does not perform any decoding.
+     *
+     * @return  The scheme component of this URI,
+     *          or {@code null} if the scheme is undefined
+     */
+    public String getScheme() {
+        return scheme;
+    }
+
+    /**
+     * Tells whether or not this URI is absolute.
+     *
+     * <p> A URI is absolute if, and only if, it has a scheme component. </p>
+     *
+     * @return  {@code true} if, and only if, this URI is absolute
+     */
+    public boolean isAbsolute() {
+        return scheme != null;
+    }
+
+    /**
+     * Tells whether or not this URI is opaque.
+     *
+     * <p> A URI is opaque if, and only if, it is absolute and its
+     * scheme-specific part does not begin with a slash character ('/').
+     * An opaque URI has a scheme, a scheme-specific part, and possibly
+     * a fragment; all other components are undefined. </p>
+     *
+     * @return  {@code true} if, and only if, this URI is opaque
+     */
+    public boolean isOpaque() {
+        return path == null;
+    }
+
+    /**
+     * Returns the raw scheme-specific part of this URI.  The scheme-specific
+     * part is never undefined, though it may be empty.
+     *
+     * <p> The scheme-specific part of a URI only contains legal URI
+     * characters. </p>
+     *
+     * @return  The raw scheme-specific part of this URI
+     *          (never {@code null})
+     */
+    public String getRawSchemeSpecificPart() {
+        defineSchemeSpecificPart();
+        return schemeSpecificPart;
+    }
+
+    /**
+     * Returns the decoded scheme-specific part of this URI.
+     *
+     * <p> The string returned by this method is equal to that returned by the
+     * {@link #getRawSchemeSpecificPart() getRawSchemeSpecificPart} method
+     * except that all sequences of escaped octets are <a
+     * href="#decode">decoded</a>.  </p>
+     *
+     * @return  The decoded scheme-specific part of this URI
+     *          (never {@code null})
+     */
+    public String getSchemeSpecificPart() {
+        if (decodedSchemeSpecificPart == null)
+            decodedSchemeSpecificPart = decode(getRawSchemeSpecificPart());
+        return decodedSchemeSpecificPart;
+    }
+
+    /**
+     * Returns the raw authority component of this URI.
+     *
+     * <p> The authority component of a URI, if defined, only contains the
+     * commercial-at character ({@code '@'}) and characters in the
+     * <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, and <i>other</i>
+     * categories.  If the authority is server-based then it is further
+     * constrained to have valid user-information, host, and port
+     * components. </p>
+     *
+     * @return  The raw authority component of this URI,
+     *          or {@code null} if the authority is undefined
+     */
+    public String getRawAuthority() {
+        return authority;
+    }
+
+    /**
+     * Returns the decoded authority component of this URI.
+     *
+     * <p> The string returned by this method is equal to that returned by the
+     * {@link #getRawAuthority() getRawAuthority} method except that all
+     * sequences of escaped octets are <a href="#decode">decoded</a>.  </p>
+     *
+     * @return  The decoded authority component of this URI,
+     *          or {@code null} if the authority is undefined
+     */
+    public String getAuthority() {
+        if (decodedAuthority == null)
+            decodedAuthority = decode(authority);
+        return decodedAuthority;
+    }
+
+    /**
+     * Returns the raw user-information component of this URI.
+     *
+     * <p> The user-information component of a URI, if defined, only contains
+     * characters in the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>, and
+     * <i>other</i> categories. </p>
+     *
+     * @return  The raw user-information component of this URI,
+     *          or {@code null} if the user information is undefined
+     */
+    public String getRawUserInfo() {
+        return userInfo;
+    }
+
+    /**
+     * Returns the decoded user-information component of this URI.
+     *
+     * <p> The string returned by this method is equal to that returned by the
+     * {@link #getRawUserInfo() getRawUserInfo} method except that all
+     * sequences of escaped octets are <a href="#decode">decoded</a>.  </p>
+     *
+     * @return  The decoded user-information component of this URI,
+     *          or {@code null} if the user information is undefined
+     */
+    public String getUserInfo() {
+        if ((decodedUserInfo == null) && (userInfo != null))
+            decodedUserInfo = decode(userInfo);
+        return decodedUserInfo;
+    }
+
+    /**
+     * Returns the host component of this URI.
+     *
+     * <p> The host component of a URI, if defined, will have one of the
+     * following forms: </p>
+     *
+     * <ul>
+     *
+     *   <li><p> A domain name consisting of one or more <i>labels</i>
+     *   separated by period characters ({@code '.'}), optionally followed by
+     *   a period character.  Each label consists of <i>alphanum</i> characters
+     *   as well as hyphen characters ({@code '-'}), though hyphens never
+     *   occur as the first or last characters in a label. The rightmost
+     *   label of a domain name consisting of two or more labels, begins
+     *   with an <i>alpha</i> character. </li>
+     *
+     *   <li><p> A dotted-quad IPv4 address of the form
+     *   <i>digit</i>{@code +.}<i>digit</i>{@code +.}<i>digit</i>{@code +.}<i>digit</i>{@code +},
+     *   where no <i>digit</i> sequence is longer than three characters and no
+     *   sequence has a value larger than 255. </p></li>
+     *
+     *   <li><p> An IPv6 address enclosed in square brackets ({@code '['} and
+     *   {@code ']'}) and consisting of hexadecimal digits, colon characters
+     *   ({@code ':'}), and possibly an embedded IPv4 address.  The full
+     *   syntax of IPv6 addresses is specified in <a
+     *   href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IPv6
+     *   Addressing Architecture</i></a>.  </p></li>
+     *
+     * </ul>
+     *
+     * The host component of a URI cannot contain escaped octets, hence this
+     * method does not perform any decoding.
+     *
+     * @return  The host component of this URI,
+     *          or {@code null} if the host is undefined
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Returns the port number of this URI.
+     *
+     * <p> The port component of a URI, if defined, is a non-negative
+     * integer. </p>
+     *
+     * @return  The port component of this URI,
+     *          or {@code -1} if the port is undefined
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Returns the raw path component of this URI.
+     *
+     * <p> The path component of a URI, if defined, only contains the slash
+     * character ({@code '/'}), the commercial-at character ({@code '@'}),
+     * and characters in the <i>unreserved</i>, <i>punct</i>, <i>escaped</i>,
+     * and <i>other</i> categories. </p>
+     *
+     * @return  The path component of this URI,
+     *          or {@code null} if the path is undefined
+     */
+    public String getRawPath() {
+        return path;
+    }
+
+    /**
+     * Returns the decoded path component of this URI.
+     *
+     * <p> The string returned by this method is equal to that returned by the
+     * {@link #getRawPath() getRawPath} method except that all sequences of
+     * escaped octets are <a href="#decode">decoded</a>.  </p>
+     *
+     * @return  The decoded path component of this URI,
+     *          or {@code null} if the path is undefined
+     */
+    public String getPath() {
+        if ((decodedPath == null) && (path != null))
+            decodedPath = decode(path);
+        return decodedPath;
+    }
+
+    /**
+     * Returns the raw query component of this URI.
+     *
+     * <p> The query component of a URI, if defined, only contains legal URI
+     * characters. </p>
+     *
+     * @return  The raw query component of this URI,
+     *          or {@code null} if the query is undefined
+     */
+    public String getRawQuery() {
+        return query;
+    }
+
+    /**
+     * Returns the decoded query component of this URI.
+     *
+     * <p> The string returned by this method is equal to that returned by the
+     * {@link #getRawQuery() getRawQuery} method except that all sequences of
+     * escaped octets are <a href="#decode">decoded</a>.  </p>
+     *
+     * @return  The decoded query component of this URI,
+     *          or {@code null} if the query is undefined
+     */
+    public String getQuery() {
+        if ((decodedQuery == null) && (query != null))
+            decodedQuery = decode(query);
+        return decodedQuery;
+    }
+
+    /**
+     * Returns the raw fragment component of this URI.
+     *
+     * <p> The fragment component of a URI, if defined, only contains legal URI
+     * characters. </p>
+     *
+     * @return  The raw fragment component of this URI,
+     *          or {@code null} if the fragment is undefined
+     */
+    public String getRawFragment() {
+        return fragment;
+    }
+
+    /**
+     * Returns the decoded fragment component of this URI.
+     *
+     * <p> The string returned by this method is equal to that returned by the
+     * {@link #getRawFragment() getRawFragment} method except that all
+     * sequences of escaped octets are <a href="#decode">decoded</a>.  </p>
+     *
+     * @return  The decoded fragment component of this URI,
+     *          or {@code null} if the fragment is undefined
+     */
+    public String getFragment() {
+        if ((decodedFragment == null) && (fragment != null))
+            decodedFragment = decode(fragment);
+        return decodedFragment;
+    }
+
+
+    // -- Equality, comparison, hash code, toString, and serialization --
+
+    /**
+     * Tests this URI for equality with another object.
+     *
+     * <p> If the given object is not a URI then this method immediately
+     * returns {@code false}.
+     *
+     * <p> For two URIs to be considered equal requires that either both are
+     * opaque or both are hierarchical.  Their schemes must either both be
+     * undefined or else be equal without regard to case. Their fragments
+     * must either both be undefined or else be equal.
+     *
+     * <p> For two opaque URIs to be considered equal, their scheme-specific
+     * parts must be equal.
+     *
+     * <p> For two hierarchical URIs to be considered equal, their paths must
+     * be equal and their queries must either both be undefined or else be
+     * equal.  Their authorities must either both be undefined, or both be
+     * registry-based, or both be server-based.  If their authorities are
+     * defined and are registry-based, then they must be equal.  If their
+     * authorities are defined and are server-based, then their hosts must be
+     * equal without regard to case, their port numbers must be equal, and
+     * their user-information components must be equal.
+     *
+     * <p> When testing the user-information, path, query, fragment, authority,
+     * or scheme-specific parts of two URIs for equality, the raw forms rather
+     * than the encoded forms of these components are compared and the
+     * hexadecimal digits of escaped octets are compared without regard to
+     * case.
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Object#equals(Object) Object.equals} method. </p>
+     *
+     * @param   ob   The object to which this object is to be compared
+     *
+     * @return  {@code true} if, and only if, the given object is a URI that
+     *          is identical to this URI
+     */
+    public boolean equals(Object ob) {
+        if (ob == this)
+            return true;
+        if (!(ob instanceof URI))
+            return false;
+        URI that = (URI)ob;
+        if (this.isOpaque() != that.isOpaque()) return false;
+        if (!equalIgnoringCase(this.scheme, that.scheme)) return false;
+        if (!equal(this.fragment, that.fragment)) return false;
+
+        // Opaque
+        if (this.isOpaque())
+            return equal(this.schemeSpecificPart, that.schemeSpecificPart);
+
+        // Hierarchical
+        if (!equal(this.path, that.path)) return false;
+        if (!equal(this.query, that.query)) return false;
+
+        // Authorities
+        if (this.authority == that.authority) return true;
+        if (this.host != null) {
+            // Server-based
+            if (!equal(this.userInfo, that.userInfo)) return false;
+            if (!equalIgnoringCase(this.host, that.host)) return false;
+            if (this.port != that.port) return false;
+        } else if (this.authority != null) {
+            // Registry-based
+            if (!equal(this.authority, that.authority)) return false;
+        } else if (this.authority != that.authority) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns a hash-code value for this URI.  The hash code is based upon all
+     * of the URI's components, and satisfies the general contract of the
+     * {@link java.lang.Object#hashCode() Object.hashCode} method.
+     *
+     * @return  A hash-code value for this URI
+     */
+    public int hashCode() {
+        if (hash != 0)
+            return hash;
+        int h = hashIgnoringCase(0, scheme);
+        h = hash(h, fragment);
+        if (isOpaque()) {
+            h = hash(h, schemeSpecificPart);
+        } else {
+            h = hash(h, path);
+            h = hash(h, query);
+            if (host != null) {
+                h = hash(h, userInfo);
+                h = hashIgnoringCase(h, host);
+                h += 1949 * port;
+            } else {
+                h = hash(h, authority);
+            }
+        }
+        hash = h;
+        return h;
+    }
+
+    /**
+     * Compares this URI to another object, which must be a URI.
+     *
+     * <p> When comparing corresponding components of two URIs, if one
+     * component is undefined but the other is defined then the first is
+     * considered to be less than the second.  Unless otherwise noted, string
+     * components are ordered according to their natural, case-sensitive
+     * ordering as defined by the {@link java.lang.String#compareTo(Object)
+     * String.compareTo} method.  String components that are subject to
+     * encoding are compared by comparing their raw forms rather than their
+     * encoded forms.
+     *
+     * <p> The ordering of URIs is defined as follows: </p>
+     *
+     * <ul>
+     *
+     *   <li><p> Two URIs with different schemes are ordered according the
+     *   ordering of their schemes, without regard to case. </p></li>
+     *
+     *   <li><p> A hierarchical URI is considered to be less than an opaque URI
+     *   with an identical scheme. </p></li>
+     *
+     *   <li><p> Two opaque URIs with identical schemes are ordered according
+     *   to the ordering of their scheme-specific parts. </p></li>
+     *
+     *   <li><p> Two opaque URIs with identical schemes and scheme-specific
+     *   parts are ordered according to the ordering of their
+     *   fragments. </p></li>
+     *
+     *   <li><p> Two hierarchical URIs with identical schemes are ordered
+     *   according to the ordering of their authority components: </p>
+     *
+     *   <ul>
+     *
+     *     <li><p> If both authority components are server-based then the URIs
+     *     are ordered according to their user-information components; if these
+     *     components are identical then the URIs are ordered according to the
+     *     ordering of their hosts, without regard to case; if the hosts are
+     *     identical then the URIs are ordered according to the ordering of
+     *     their ports. </p></li>
+     *
+     *     <li><p> If one or both authority components are registry-based then
+     *     the URIs are ordered according to the ordering of their authority
+     *     components. </p></li>
+     *
+     *   </ul></li>
+     *
+     *   <li><p> Finally, two hierarchical URIs with identical schemes and
+     *   authority components are ordered according to the ordering of their
+     *   paths; if their paths are identical then they are ordered according to
+     *   the ordering of their queries; if the queries are identical then they
+     *   are ordered according to the order of their fragments. </p></li>
+     *
+     * </ul>
+     *
+     * <p> This method satisfies the general contract of the {@link
+     * java.lang.Comparable#compareTo(Object) Comparable.compareTo}
+     * method. </p>
+     *
+     * @param   that
+     *          The object to which this URI is to be compared
+     *
+     * @return  A negative integer, zero, or a positive integer as this URI is
+     *          less than, equal to, or greater than the given URI
+     *
+     * @throws  ClassCastException
+     *          If the given object is not a URI
+     */
+    public int compareTo(URI that) {
+        int c;
+
+        if ((c = compareIgnoringCase(this.scheme, that.scheme)) != 0)
+            return c;
+
+        if (this.isOpaque()) {
+            if (that.isOpaque()) {
+                // Both opaque
+                if ((c = compare(this.schemeSpecificPart,
+                                 that.schemeSpecificPart)) != 0)
+                    return c;
+                return compare(this.fragment, that.fragment);
+            }
+            return +1;                  // Opaque > hierarchical
+        } else if (that.isOpaque()) {
+            return -1;                  // Hierarchical < opaque
+        }
+
+        // Hierarchical
+        if ((this.host != null) && (that.host != null)) {
+            // Both server-based
+            if ((c = compare(this.userInfo, that.userInfo)) != 0)
+                return c;
+            if ((c = compareIgnoringCase(this.host, that.host)) != 0)
+                return c;
+            if ((c = this.port - that.port) != 0)
+                return c;
+        } else {
+            // If one or both authorities are registry-based then we simply
+            // compare them in the usual, case-sensitive way.  If one is
+            // registry-based and one is server-based then the strings are
+            // guaranteed to be unequal, hence the comparison will never return
+            // zero and the compareTo and equals methods will remain
+            // consistent.
+            if ((c = compare(this.authority, that.authority)) != 0) return c;
+        }
+
+        if ((c = compare(this.path, that.path)) != 0) return c;
+        if ((c = compare(this.query, that.query)) != 0) return c;
+        return compare(this.fragment, that.fragment);
+    }
+
+    /**
+     * Returns the content of this URI as a string.
+     *
+     * <p> If this URI was created by invoking one of the constructors in this
+     * class then a string equivalent to the original input string, or to the
+     * string computed from the originally-given components, as appropriate, is
+     * returned.  Otherwise this URI was created by normalization, resolution,
+     * or relativization, and so a string is constructed from this URI's
+     * components according to the rules specified in <a
+     * href="http://www.ietf.org/rfc/rfc2396.txt">RFC&nbsp;2396</a>,
+     * section&nbsp;5.2, step&nbsp;7. </p>
+     *
+     * @return  The string form of this URI
+     */
+    public String toString() {
+        defineString();
+        return string;
+    }
+
+    /**
+     * Returns the content of this URI as a US-ASCII string.
+     *
+     * <p> If this URI does not contain any characters in the <i>other</i>
+     * category then an invocation of this method will return the same value as
+     * an invocation of the {@link #toString() toString} method.  Otherwise
+     * this method works as if by invoking that method and then <a
+     * href="#encode">encoding</a> the result.  </p>
+     *
+     * @return  The string form of this URI, encoded as needed
+     *          so that it only contains characters in the US-ASCII
+     *          charset
+     */
+    public String toASCIIString() {
+        defineString();
+        return encode(string);
+    }
+
+
+    // -- Serialization support --
+
+    /**
+     * Saves the content of this URI to the given serial stream.
+     *
+     * <p> The only serializable field of a URI instance is its {@code string}
+     * field.  That field is given a value, if it does not have one already,
+     * and then the {@link java.io.ObjectOutputStream#defaultWriteObject()}
+     * method of the given object-output stream is invoked. </p>
+     *
+     * @param  os  The object-output stream to which this object
+     *             is to be written
+     */
+    private void writeObject(ObjectOutputStream os)
+        throws IOException
+    {
+        defineString();
+        os.defaultWriteObject();        // Writes the string field only
+    }
+
+    /**
+     * Reconstitutes a URI from the given serial stream.
+     *
+     * <p> The {@link java.io.ObjectInputStream#defaultReadObject()} method is
+     * invoked to read the value of the {@code string} field.  The result is
+     * then parsed in the usual way.
+     *
+     * @param  is  The object-input stream from which this object
+     *             is being read
+     */
+    private void readObject(ObjectInputStream is)
+        throws ClassNotFoundException, IOException
+    {
+        port = -1;                      // Argh
+        is.defaultReadObject();
+        try {
+            new Parser(string).parse(false);
+        } catch (URISyntaxException x) {
+            IOException y = new InvalidObjectException("Invalid URI");
+            y.initCause(x);
+            throw y;
+        }
+    }
+
+
+    // -- End of public methods --
+
+
+    // -- Utility methods for string-field comparison and hashing --
+
+    // These methods return appropriate values for null string arguments,
+    // thereby simplifying the equals, hashCode, and compareTo methods.
+    //
+    // The case-ignoring methods should only be applied to strings whose
+    // characters are all known to be US-ASCII.  Because of this restriction,
+    // these methods are faster than the similar methods in the String class.
+
+    // US-ASCII only
+    private static int toLower(char c) {
+        if ((c >= 'A') && (c <= 'Z'))
+            return c + ('a' - 'A');
+        return c;
+    }
+
+    // US-ASCII only
+    private static int toUpper(char c) {
+        if ((c >= 'a') && (c <= 'z'))
+            return c - ('a' - 'A');
+        return c;
+    }
+
+    private static boolean equal(String s, String t) {
+        if (s == t) return true;
+        if ((s != null) && (t != null)) {
+            if (s.length() != t.length())
+                return false;
+            if (s.indexOf('%') < 0)
+                return s.equals(t);
+            int n = s.length();
+            for (int i = 0; i < n;) {
+                char c = s.charAt(i);
+                char d = t.charAt(i);
+                if (c != '%') {
+                    if (c != d)
+                        return false;
+                    i++;
+                    continue;
+                }
+                if (d != '%')
+                    return false;
+                i++;
+                if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
+                    return false;
+                i++;
+                if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
+                    return false;
+                i++;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    // US-ASCII only
+    private static boolean equalIgnoringCase(String s, String t) {
+        if (s == t) return true;
+        if ((s != null) && (t != null)) {
+            int n = s.length();
+            if (t.length() != n)
+                return false;
+            for (int i = 0; i < n; i++) {
+                if (toLower(s.charAt(i)) != toLower(t.charAt(i)))
+                    return false;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    private static int hash(int hash, String s) {
+        if (s == null) return hash;
+        return s.indexOf('%') < 0 ? hash * 127 + s.hashCode()
+                                  : normalizedHash(hash, s);
+    }
+
+
+    private static int normalizedHash(int hash, String s) {
+        int h = 0;
+        for (int index = 0; index < s.length(); index++) {
+            char ch = s.charAt(index);
+            h = 31 * h + ch;
+            if (ch == '%') {
+                /*
+                 * Process the next two encoded characters
+                 */
+                for (int i = index + 1; i < index + 3; i++)
+                    h = 31 * h + toUpper(s.charAt(i));
+                index += 2;
+            }
+        }
+        return hash * 127 + h;
+    }
+
+    // US-ASCII only
+    private static int hashIgnoringCase(int hash, String s) {
+        if (s == null) return hash;
+        int h = hash;
+        int n = s.length();
+        for (int i = 0; i < n; i++)
+            h = 31 * h + toLower(s.charAt(i));
+        return h;
+    }
+
+    private static int compare(String s, String t) {
+        if (s == t) return 0;
+        if (s != null) {
+            if (t != null)
+                return s.compareTo(t);
+            else
+                return +1;
+        } else {
+            return -1;
+        }
+    }
+
+    // US-ASCII only
+    private static int compareIgnoringCase(String s, String t) {
+        if (s == t) return 0;
+        if (s != null) {
+            if (t != null) {
+                int sn = s.length();
+                int tn = t.length();
+                int n = sn < tn ? sn : tn;
+                for (int i = 0; i < n; i++) {
+                    int c = toLower(s.charAt(i)) - toLower(t.charAt(i));
+                    if (c != 0)
+                        return c;
+                }
+                return sn - tn;
+            }
+            return +1;
+        } else {
+            return -1;
+        }
+    }
+
+
+    // -- String construction --
+
+    // If a scheme is given then the path, if given, must be absolute
+    //
+    private static void checkPath(String s, String scheme, String path)
+        throws URISyntaxException
+    {
+        if (scheme != null) {
+            if ((path != null)
+                && ((path.length() > 0) && (path.charAt(0) != '/')))
+                throw new URISyntaxException(s,
+                                             "Relative path in absolute URI");
+        }
+    }
+
+    private void appendAuthority(StringBuffer sb,
+                                 String authority,
+                                 String userInfo,
+                                 String host,
+                                 int port)
+    {
+        if (host != null) {
+            sb.append("//");
+            if (userInfo != null) {
+                sb.append(quote(userInfo, L_USERINFO, H_USERINFO));
+                sb.append('@');
+            }
+            boolean needBrackets = ((host.indexOf(':') >= 0)
+                                    && !host.startsWith("[")
+                                    && !host.endsWith("]"));
+            if (needBrackets) sb.append('[');
+            sb.append(host);
+            if (needBrackets) sb.append(']');
+            if (port != -1) {
+                sb.append(':');
+                sb.append(port);
+            }
+        } else if (authority != null) {
+            sb.append("//");
+            if (authority.startsWith("[")) {
+                // authority should (but may not) contain an embedded IPv6 address
+                int end = authority.indexOf("]");
+                String doquote = authority, dontquote = "";
+                if (end != -1 && authority.indexOf(":") != -1) {
+                    // the authority contains an IPv6 address
+                    if (end == authority.length()) {
+                        dontquote = authority;
+                        doquote = "";
+                    } else {
+                        dontquote = authority.substring(0 , end + 1);
+                        doquote = authority.substring(end + 1);
+                    }
+                }
+                sb.append(dontquote);
+                sb.append(quote(doquote,
+                            L_REG_NAME | L_SERVER,
+                            H_REG_NAME | H_SERVER));
+            } else {
+                sb.append(quote(authority,
+                            L_REG_NAME | L_SERVER,
+                            H_REG_NAME | H_SERVER));
+            }
+        }
+    }
+
+    private void appendSchemeSpecificPart(StringBuffer sb,
+                                          String opaquePart,
+                                          String authority,
+                                          String userInfo,
+                                          String host,
+                                          int port,
+                                          String path,
+                                          String query)
+    {
+        if (opaquePart != null) {
+            /* check if SSP begins with an IPv6 address
+             * because we must not quote a literal IPv6 address
+             */
+            if (opaquePart.startsWith("//[")) {
+                int end =  opaquePart.indexOf("]");
+                if (end != -1 && opaquePart.indexOf(":")!=-1) {
+                    String doquote, dontquote;
+                    if (end == opaquePart.length()) {
+                        dontquote = opaquePart;
+                        doquote = "";
+                    } else {
+                        dontquote = opaquePart.substring(0,end+1);
+                        doquote = opaquePart.substring(end+1);
+                    }
+                    sb.append (dontquote);
+                    sb.append(quote(doquote, L_URIC, H_URIC));
+                }
+            } else {
+                sb.append(quote(opaquePart, L_URIC, H_URIC));
+            }
+        } else {
+            appendAuthority(sb, authority, userInfo, host, port);
+            if (path != null)
+                sb.append(quote(path, L_PATH, H_PATH));
+            if (query != null) {
+                sb.append('?');
+                sb.append(quote(query, L_URIC, H_URIC));
+            }
+        }
+    }
+
+    private void appendFragment(StringBuffer sb, String fragment) {
+        if (fragment != null) {
+            sb.append('#');
+            sb.append(quote(fragment, L_URIC, H_URIC));
+        }
+    }
+
+    private String toString(String scheme,
+                            String opaquePart,
+                            String authority,
+                            String userInfo,
+                            String host,
+                            int port,
+                            String path,
+                            String query,
+                            String fragment)
+    {
+        StringBuffer sb = new StringBuffer();
+        if (scheme != null) {
+            sb.append(scheme);
+            sb.append(':');
+        }
+        appendSchemeSpecificPart(sb, opaquePart,
+                                 authority, userInfo, host, port,
+                                 path, query);
+        appendFragment(sb, fragment);
+        return sb.toString();
+    }
+
+    private void defineSchemeSpecificPart() {
+        if (schemeSpecificPart != null) return;
+        StringBuffer sb = new StringBuffer();
+        appendSchemeSpecificPart(sb, null, getAuthority(), getUserInfo(),
+                                 host, port, getPath(), getQuery());
+        if (sb.length() == 0) return;
+        schemeSpecificPart = sb.toString();
+    }
+
+    private void defineString() {
+        if (string != null) return;
+
+        StringBuffer sb = new StringBuffer();
+        if (scheme != null) {
+            sb.append(scheme);
+            sb.append(':');
+        }
+        if (isOpaque()) {
+            sb.append(schemeSpecificPart);
+        } else {
+            if (host != null) {
+                sb.append("//");
+                if (userInfo != null) {
+                    sb.append(userInfo);
+                    sb.append('@');
+                }
+                boolean needBrackets = ((host.indexOf(':') >= 0)
+                                    && !host.startsWith("[")
+                                    && !host.endsWith("]"));
+                if (needBrackets) sb.append('[');
+                sb.append(host);
+                if (needBrackets) sb.append(']');
+                if (port != -1) {
+                    sb.append(':');
+                    sb.append(port);
+                }
+            } else if (authority != null) {
+                sb.append("//");
+                sb.append(authority);
+            }
+            if (path != null)
+                sb.append(path);
+            if (query != null) {
+                sb.append('?');
+                sb.append(query);
+            }
+        }
+        if (fragment != null) {
+            sb.append('#');
+            sb.append(fragment);
+        }
+        string = sb.toString();
+    }
+
+
+    // -- Normalization, resolution, and relativization --
+
+    // RFC2396 5.2 (6)
+    private static String resolvePath(String base, String child,
+                                      boolean absolute)
+    {
+        int i = base.lastIndexOf('/');
+        int cn = child.length();
+        String path = "";
+
+        if (cn == 0) {
+            // 5.2 (6a)
+            if (i >= 0)
+                path = base.substring(0, i + 1);
+        } else {
+            StringBuffer sb = new StringBuffer(base.length() + cn);
+            // 5.2 (6a)
+            if (i >= 0)
+                sb.append(base.substring(0, i + 1));
+            // 5.2 (6b)
+            sb.append(child);
+            path = sb.toString();
+        }
+
+        // 5.2 (6c-f)
+        // Android-changed: App compat. Remove leading dots when resolving path. http://b/25897693
+        // String np = normalize(path);
+        String np = normalize(path, true);
+
+        // 5.2 (6g): If the result is absolute but the path begins with "../",
+        // then we simply leave the path as-is
+
+        return np;
+    }
+
+    // RFC2396 5.2
+    private static URI resolve(URI base, URI child) {
+        // check if child if opaque first so that NPE is thrown
+        // if child is null.
+        if (child.isOpaque() || base.isOpaque())
+            return child;
+
+        // 5.2 (2): Reference to current document (lone fragment)
+        if ((child.scheme == null) && (child.authority == null)
+            && child.path.equals("") && (child.fragment != null)
+            && (child.query == null)) {
+            if ((base.fragment != null)
+                && child.fragment.equals(base.fragment)) {
+                return base;
+            }
+            URI ru = new URI();
+            ru.scheme = base.scheme;
+            ru.authority = base.authority;
+            ru.userInfo = base.userInfo;
+            ru.host = base.host;
+            ru.port = base.port;
+            ru.path = base.path;
+            ru.fragment = child.fragment;
+            ru.query = base.query;
+            return ru;
+        }
+
+        // 5.2 (3): Child is absolute
+        if (child.scheme != null)
+            return child;
+
+        URI ru = new URI();             // Resolved URI
+        ru.scheme = base.scheme;
+        ru.query = child.query;
+        ru.fragment = child.fragment;
+
+        // 5.2 (4): Authority
+        if (child.authority == null) {
+            ru.authority = base.authority;
+            ru.host = base.host;
+            ru.userInfo = base.userInfo;
+            ru.port = base.port;
+
+            // BEGIN Android-changed: App Compat. Handle null and empty path using RFC 3986 logic
+            // http://b/25897693
+            if (child.path == null || child.path.isEmpty()) {
+                // This is an additional path from RFC 3986 RI, which fixes following RFC 2396
+                // "normal" examples:
+                // Base: http://a/b/c/d;p?q
+                //   "?y" = "http://a/b/c/d;p?y"
+                //   ""   = "http://a/b/c/d;p?q"
+                // http://b/25897693
+                ru.path = base.path;
+                ru.query = child.query != null ? child.query : base.query;
+            // END Android-changed: App Compat. Handle null and empty path using RFC 3986 logic
+            } else if ((child.path.length() > 0) && (child.path.charAt(0) == '/')) {
+                // 5.2 (5): Child path is absolute
+                //
+                // Android-changed: App Compat. Remove leading dots in path.
+                // There is an additional step from RFC 3986 RI, requiring to remove dots for
+                // absolute path as well.
+                // http://b/25897693
+                // ru.path = child.path;
+                ru.path = normalize(child.path, true);
+            } else {
+                // 5.2 (6): Resolve relative path
+                ru.path = resolvePath(base.path, child.path, base.isAbsolute());
+            }
+        } else {
+            ru.authority = child.authority;
+            ru.host = child.host;
+            ru.userInfo = child.userInfo;
+            ru.host = child.host;
+            ru.port = child.port;
+            ru.path = child.path;
+        }
+
+        // 5.2 (7): Recombine (nothing to do here)
+        return ru;
+    }
+
+    // If the given URI's path is normal then return the URI;
+    // o.w., return a new URI containing the normalized path.
+    //
+    private static URI normalize(URI u) {
+        if (u.isOpaque() || (u.path == null) || (u.path.length() == 0))
+            return u;
+
+        String np = normalize(u.path);
+        if (np == u.path)
+            return u;
+
+        URI v = new URI();
+        v.scheme = u.scheme;
+        v.fragment = u.fragment;
+        v.authority = u.authority;
+        v.userInfo = u.userInfo;
+        v.host = u.host;
+        v.port = u.port;
+        v.path = np;
+        v.query = u.query;
+        return v;
+    }
+
+    // If both URIs are hierarchical, their scheme and authority components are
+    // identical, and the base path is a prefix of the child's path, then
+    // return a relative URI that, when resolved against the base, yields the
+    // child; otherwise, return the child.
+    //
+    private static URI relativize(URI base, URI child) {
+        // check if child if opaque first so that NPE is thrown
+        // if child is null.
+        if (child.isOpaque() || base.isOpaque())
+            return child;
+        if (!equalIgnoringCase(base.scheme, child.scheme)
+            || !equal(base.authority, child.authority))
+            return child;
+
+        String bp = normalize(base.path);
+        String cp = normalize(child.path);
+        if (!bp.equals(cp)) {
+            // Android-changed: App Compat. Interpret ambiguous base path as a file, not a directory
+            // Upstream would append '/' to bp if not present, interpreting it as a directory; thus,
+            // /a/b/c relative to /a/b would become /c, whereas Android would relativize to /b/c.
+            // The spec is pretty vague about this but the Android behavior is kept because several
+            // tests enforce it.
+            // if (!bp.endsWith("/"))
+            //     bp = bp + "/";
+            if (bp.indexOf('/') != -1) {
+                bp = bp.substring(0, bp.lastIndexOf('/') + 1);
+            }
+
+            if (!cp.startsWith(bp))
+                return child;
+        }
+
+        URI v = new URI();
+        v.path = cp.substring(bp.length());
+        v.query = child.query;
+        v.fragment = child.fragment;
+        return v;
+    }
+
+
+
+    // -- Path normalization --
+
+    // The following algorithm for path normalization avoids the creation of a
+    // string object for each segment, as well as the use of a string buffer to
+    // compute the final result, by using a single char array and editing it in
+    // place.  The array is first split into segments, replacing each slash
+    // with '\0' and creating a segment-index array, each element of which is
+    // the index of the first char in the corresponding segment.  We then walk
+    // through both arrays, removing ".", "..", and other segments as necessary
+    // by setting their entries in the index array to -1.  Finally, the two
+    // arrays are used to rejoin the segments and compute the final result.
+    //
+    // This code is based upon src/solaris/native/java/io/canonicalize_md.c
+
+
+    // Check the given path to see if it might need normalization.  A path
+    // might need normalization if it contains duplicate slashes, a "."
+    // segment, or a ".." segment.  Return -1 if no further normalization is
+    // possible, otherwise return the number of segments found.
+    //
+    // This method takes a string argument rather than a char array so that
+    // this test can be performed without invoking path.toCharArray().
+    //
+    static private int needsNormalization(String path) {
+        boolean normal = true;
+        int ns = 0;                     // Number of segments
+        int end = path.length() - 1;    // Index of last char in path
+        int p = 0;                      // Index of next char in path
+
+        // Skip initial slashes
+        while (p <= end) {
+            if (path.charAt(p) != '/') break;
+            p++;
+        }
+        if (p > 1) normal = false;
+
+        // Scan segments
+        while (p <= end) {
+
+            // Looking at "." or ".." ?
+            if ((path.charAt(p) == '.')
+                && ((p == end)
+                    || ((path.charAt(p + 1) == '/')
+                        || ((path.charAt(p + 1) == '.')
+                            && ((p + 1 == end)
+                                || (path.charAt(p + 2) == '/')))))) {
+                normal = false;
+            }
+            ns++;
+
+            // Find beginning of next segment
+            while (p <= end) {
+                if (path.charAt(p++) != '/')
+                    continue;
+
+                // Skip redundant slashes
+                while (p <= end) {
+                    if (path.charAt(p) != '/') break;
+                    normal = false;
+                    p++;
+                }
+
+                break;
+            }
+        }
+
+        return normal ? -1 : ns;
+    }
+
+
+    // Split the given path into segments, replacing slashes with nulls and
+    // filling in the given segment-index array.
+    //
+    // Preconditions:
+    //   segs.length == Number of segments in path
+    //
+    // Postconditions:
+    //   All slashes in path replaced by '\0'
+    //   segs[i] == Index of first char in segment i (0 <= i < segs.length)
+    //
+    static private void split(char[] path, int[] segs) {
+        int end = path.length - 1;      // Index of last char in path
+        int p = 0;                      // Index of next char in path
+        int i = 0;                      // Index of current segment
+
+        // Skip initial slashes
+        while (p <= end) {
+            if (path[p] != '/') break;
+            path[p] = '\0';
+            p++;
+        }
+
+        while (p <= end) {
+
+            // Note start of segment
+            segs[i++] = p++;
+
+            // Find beginning of next segment
+            while (p <= end) {
+                if (path[p++] != '/')
+                    continue;
+                path[p - 1] = '\0';
+
+                // Skip redundant slashes
+                while (p <= end) {
+                    if (path[p] != '/') break;
+                    path[p++] = '\0';
+                }
+                break;
+            }
+        }
+
+        if (i != segs.length)
+            throw new InternalError();  // ASSERT
+    }
+
+
+    // Join the segments in the given path according to the given segment-index
+    // array, ignoring those segments whose index entries have been set to -1,
+    // and inserting slashes as needed.  Return the length of the resulting
+    // path.
+    //
+    // Preconditions:
+    //   segs[i] == -1 implies segment i is to be ignored
+    //   path computed by split, as above, with '\0' having replaced '/'
+    //
+    // Postconditions:
+    //   path[0] .. path[return value] == Resulting path
+    //
+    static private int join(char[] path, int[] segs) {
+        int ns = segs.length;           // Number of segments
+        int end = path.length - 1;      // Index of last char in path
+        int p = 0;                      // Index of next path char to write
+
+        if (path[p] == '\0') {
+            // Restore initial slash for absolute paths
+            path[p++] = '/';
+        }
+
+        for (int i = 0; i < ns; i++) {
+            int q = segs[i];            // Current segment
+            if (q == -1)
+                // Ignore this segment
+                continue;
+
+            if (p == q) {
+                // We're already at this segment, so just skip to its end
+                while ((p <= end) && (path[p] != '\0'))
+                    p++;
+                if (p <= end) {
+                    // Preserve trailing slash
+                    path[p++] = '/';
+                }
+            } else if (p < q) {
+                // Copy q down to p
+                while ((q <= end) && (path[q] != '\0'))
+                    path[p++] = path[q++];
+                if (q <= end) {
+                    // Preserve trailing slash
+                    path[p++] = '/';
+                }
+            } else
+                throw new InternalError(); // ASSERT false
+        }
+
+        return p;
+    }
+
+
+    // Remove "." segments from the given path, and remove segment pairs
+    // consisting of a non-".." segment followed by a ".." segment.
+    //
+    // Android-changed: App compat. Remove leading dots when resolving path. http://b/25897693
+    // private static void removeDots(char[] path, int[] segs) {
+    private static void removeDots(char[] path, int[] segs, boolean removeLeading) {
+        int ns = segs.length;
+        int end = path.length - 1;
+
+        for (int i = 0; i < ns; i++) {
+            int dots = 0;               // Number of dots found (0, 1, or 2)
+
+            // Find next occurrence of "." or ".."
+            do {
+                int p = segs[i];
+                if (path[p] == '.') {
+                    if (p == end) {
+                        dots = 1;
+                        break;
+                    } else if (path[p + 1] == '\0') {
+                        dots = 1;
+                        break;
+                    } else if ((path[p + 1] == '.')
+                               && ((p + 1 == end)
+                                   || (path[p + 2] == '\0'))) {
+                        dots = 2;
+                        break;
+                    }
+                }
+                i++;
+            } while (i < ns);
+            if ((i > ns) || (dots == 0))
+                break;
+
+            if (dots == 1) {
+                // Remove this occurrence of "."
+                segs[i] = -1;
+            } else {
+                // If there is a preceding non-".." segment, remove both that
+                // segment and this occurrence of ".."
+                int j;
+                for (j = i - 1; j >= 0; j--) {
+                    if (segs[j] != -1) break;
+                }
+                if (j >= 0) {
+                    int q = segs[j];
+                    if (!((path[q] == '.')
+                          && (path[q + 1] == '.')
+                          && (path[q + 2] == '\0'))) {
+                        segs[i] = -1;
+                        segs[j] = -1;
+                    }
+                // Android-added: App compat. Remove leading dots when resolving path.
+                // This is a leading ".." segment. Per RFC 3986 RI, this should be removed as
+                // well. This fixes RFC 2396 "abnormal" examples.
+                // http://b/25897693
+                } else if (removeLeading) {
+                    segs[i] = -1;
+                }
+            }
+        }
+    }
+
+
+    // DEVIATION: If the normalized path is relative, and if the first
+    // segment could be parsed as a scheme name, then prepend a "." segment
+    //
+    private static void maybeAddLeadingDot(char[] path, int[] segs) {
+
+        if (path[0] == '\0')
+            // The path is absolute
+            return;
+
+        int ns = segs.length;
+        int f = 0;                      // Index of first segment
+        while (f < ns) {
+            if (segs[f] >= 0)
+                break;
+            f++;
+        }
+        if ((f >= ns) || (f == 0))
+            // The path is empty, or else the original first segment survived,
+            // in which case we already know that no leading "." is needed
+            return;
+
+        int p = segs[f];
+        while ((p < path.length) && (path[p] != ':') && (path[p] != '\0')) p++;
+        if (p >= path.length || path[p] == '\0')
+            // No colon in first segment, so no "." needed
+            return;
+
+        // At this point we know that the first segment is unused,
+        // hence we can insert a "." segment at that position
+        path[0] = '.';
+        path[1] = '\0';
+        segs[0] = 0;
+    }
+
+
+    // Normalize the given path string.  A normal path string has no empty
+    // segments (i.e., occurrences of "//"), no segments equal to ".", and no
+    // segments equal to ".." that are preceded by a segment not equal to "..".
+    // In contrast to Unix-style pathname normalization, for URI paths we
+    // always retain trailing slashes.
+    //
+    private static String normalize(String ps) {
+        // BEGIN Android-changed: App compat. Remove leading dots when resolving path.
+        // Controlled by the "boolean removeLeading" argument added to normalize().
+        return normalize(ps, false);
+    }
+
+    private static String normalize(String ps, boolean removeLeading) {
+        // END Android-changed: App compat. Remove leading dots when resolving path.
+        // Does this path need normalization?
+        int ns = needsNormalization(ps);        // Number of segments
+        if (ns < 0)
+            // Nope -- just return it
+            return ps;
+
+        char[] path = ps.toCharArray();         // Path in char-array form
+
+        // Split path into segments
+        int[] segs = new int[ns];               // Segment-index array
+        split(path, segs);
+
+        // Remove dots
+        // Android-changed: App compat. Remove leading dots when resolving path.
+        // removeDots(path, segs);
+        removeDots(path, segs, removeLeading);
+
+        // Prevent scheme-name confusion
+        maybeAddLeadingDot(path, segs);
+
+        // Join the remaining segments and return the result
+        String s = new String(path, 0, join(path, segs));
+        if (s.equals(ps)) {
+            // string was already normalized
+            return ps;
+        }
+        return s;
+    }
+
+
+
+    // -- Character classes for parsing --
+
+    // RFC2396 precisely specifies which characters in the US-ASCII charset are
+    // permissible in the various components of a URI reference.  We here
+    // define a set of mask pairs to aid in enforcing these restrictions.  Each
+    // mask pair consists of two longs, a low mask and a high mask.  Taken
+    // together they represent a 128-bit mask, where bit i is set iff the
+    // character with value i is permitted.
+    //
+    // This approach is more efficient than sequentially searching arrays of
+    // permitted characters.  It could be made still more efficient by
+    // precompiling the mask information so that a character's presence in a
+    // given mask could be determined by a single table lookup.
+
+    // Compute the low-order mask for the characters in the given string
+    private static long lowMask(String chars) {
+        int n = chars.length();
+        long m = 0;
+        for (int i = 0; i < n; i++) {
+            char c = chars.charAt(i);
+            if (c < 64)
+                m |= (1L << c);
+        }
+        return m;
+    }
+
+    // Compute the high-order mask for the characters in the given string
+    private static long highMask(String chars) {
+        int n = chars.length();
+        long m = 0;
+        for (int i = 0; i < n; i++) {
+            char c = chars.charAt(i);
+            if ((c >= 64) && (c < 128))
+                m |= (1L << (c - 64));
+        }
+        return m;
+    }
+
+    // Compute a low-order mask for the characters
+    // between first and last, inclusive
+    private static long lowMask(char first, char last) {
+        long m = 0;
+        int f = Math.max(Math.min(first, 63), 0);
+        int l = Math.max(Math.min(last, 63), 0);
+        for (int i = f; i <= l; i++)
+            m |= 1L << i;
+        return m;
+    }
+
+    // Compute a high-order mask for the characters
+    // between first and last, inclusive
+    private static long highMask(char first, char last) {
+        long m = 0;
+        int f = Math.max(Math.min(first, 127), 64) - 64;
+        int l = Math.max(Math.min(last, 127), 64) - 64;
+        for (int i = f; i <= l; i++)
+            m |= 1L << i;
+        return m;
+    }
+
+    // Tell whether the given character is permitted by the given mask pair
+    private static boolean match(char c, long lowMask, long highMask) {
+        if (c == 0) // 0 doesn't have a slot in the mask. So, it never matches.
+            return false;
+        if (c < 64)
+            return ((1L << c) & lowMask) != 0;
+        if (c < 128)
+            return ((1L << (c - 64)) & highMask) != 0;
+        return false;
+    }
+
+    // Character-class masks, in reverse order from RFC2396 because
+    // initializers for static fields cannot make forward references.
+
+    // digit    = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+    //            "8" | "9"
+    private static final long L_DIGIT = lowMask('0', '9');
+    private static final long H_DIGIT = 0L;
+
+    // upalpha  = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
+    //            "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
+    //            "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+    private static final long L_UPALPHA = 0L;
+    private static final long H_UPALPHA = highMask('A', 'Z');
+
+    // lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
+    //            "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
+    //            "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
+    private static final long L_LOWALPHA = 0L;
+    private static final long H_LOWALPHA = highMask('a', 'z');
+
+    // alpha         = lowalpha | upalpha
+    private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA;
+    private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA;
+
+    // alphanum      = alpha | digit
+    private static final long L_ALPHANUM = L_DIGIT | L_ALPHA;
+    private static final long H_ALPHANUM = H_DIGIT | H_ALPHA;
+
+    // hex           = digit | "A" | "B" | "C" | "D" | "E" | "F" |
+    //                         "a" | "b" | "c" | "d" | "e" | "f"
+    private static final long L_HEX = L_DIGIT;
+    private static final long H_HEX = highMask('A', 'F') | highMask('a', 'f');
+
+    // mark          = "-" | "_" | "." | "!" | "~" | "*" | "'" |
+    //                 "(" | ")"
+    private static final long L_MARK = lowMask("-_.!~*'()");
+    private static final long H_MARK = highMask("-_.!~*'()");
+
+    // unreserved    = alphanum | mark
+    private static final long L_UNRESERVED = L_ALPHANUM | L_MARK;
+    private static final long H_UNRESERVED = H_ALPHANUM | H_MARK;
+
+    // reserved      = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+    //                 "$" | "," | "[" | "]"
+    // Added per RFC2732: "[", "]"
+    private static final long L_RESERVED = lowMask(";/?:@&=+$,[]");
+    private static final long H_RESERVED = highMask(";/?:@&=+$,[]");
+
+    // The zero'th bit is used to indicate that escape pairs and non-US-ASCII
+    // characters are allowed; this is handled by the scanEscape method below.
+    private static final long L_ESCAPED = 1L;
+    private static final long H_ESCAPED = 0L;
+
+    // uric          = reserved | unreserved | escaped
+    private static final long L_URIC = L_RESERVED | L_UNRESERVED | L_ESCAPED;
+    private static final long H_URIC = H_RESERVED | H_UNRESERVED | H_ESCAPED;
+
+    // pchar         = unreserved | escaped |
+    //                 ":" | "@" | "&" | "=" | "+" | "$" | ","
+    private static final long L_PCHAR
+        = L_UNRESERVED | L_ESCAPED | lowMask(":@&=+$,");
+    private static final long H_PCHAR
+        = H_UNRESERVED | H_ESCAPED | highMask(":@&=+$,");
+
+    // All valid path characters
+    private static final long L_PATH = L_PCHAR | lowMask(";/");
+    private static final long H_PATH = H_PCHAR | highMask(";/");
+
+    // Dash, for use in domainlabel and toplabel
+    private static final long L_DASH = lowMask("-");
+    private static final long H_DASH = highMask("-");
+
+    // BEGIN Android-added: Allow underscore in hostname.
+    // UNDERSCORE, for use in domainlabel and toplabel
+    private static final long L_UNDERSCORE = lowMask("_");
+    private static final long H_UNDERSCORE = highMask("_");
+    // END Android-added: Allow underscore in hostname.
+
+    // Dot, for use in hostnames
+    private static final long L_DOT = lowMask(".");
+    private static final long H_DOT = highMask(".");
+
+    // userinfo      = *( unreserved | escaped |
+    //                    ";" | ":" | "&" | "=" | "+" | "$" | "," )
+    private static final long L_USERINFO
+        = L_UNRESERVED | L_ESCAPED | lowMask(";:&=+$,");
+    private static final long H_USERINFO
+        = H_UNRESERVED | H_ESCAPED | highMask(";:&=+$,");
+
+    // reg_name      = 1*( unreserved | escaped | "$" | "," |
+    //                     ";" | ":" | "@" | "&" | "=" | "+" )
+    private static final long L_REG_NAME
+        = L_UNRESERVED | L_ESCAPED | lowMask("$,;:@&=+");
+    private static final long H_REG_NAME
+        = H_UNRESERVED | H_ESCAPED | highMask("$,;:@&=+");
+
+    // All valid characters for server-based authorities
+    private static final long L_SERVER
+        = L_USERINFO | L_ALPHANUM | L_DASH | lowMask(".:@[]");
+    private static final long H_SERVER
+        = H_USERINFO | H_ALPHANUM | H_DASH | highMask(".:@[]");
+
+    // Special case of server authority that represents an IPv6 address
+    // In this case, a % does not signify an escape sequence
+    private static final long L_SERVER_PERCENT
+        = L_SERVER | lowMask("%");
+    private static final long H_SERVER_PERCENT
+        = H_SERVER | highMask("%");
+    private static final long L_LEFT_BRACKET = lowMask("[");
+    private static final long H_LEFT_BRACKET = highMask("[");
+
+    // scheme        = alpha *( alpha | digit | "+" | "-" | "." )
+    private static final long L_SCHEME = L_ALPHA | L_DIGIT | lowMask("+-.");
+    private static final long H_SCHEME = H_ALPHA | H_DIGIT | highMask("+-.");
+
+    // uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" |
+    //                 "&" | "=" | "+" | "$" | ","
+    private static final long L_URIC_NO_SLASH
+        = L_UNRESERVED | L_ESCAPED | lowMask(";?:@&=+$,");
+    private static final long H_URIC_NO_SLASH
+        = H_UNRESERVED | H_ESCAPED | highMask(";?:@&=+$,");
+
+
+    // -- Escaping and encoding --
+
+    private final static char[] hexDigits = {
+        '0', '1', '2', '3', '4', '5', '6', '7',
+        '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
+    };
+
+    private static void appendEscape(StringBuffer sb, byte b) {
+        sb.append('%');
+        sb.append(hexDigits[(b >> 4) & 0x0f]);
+        sb.append(hexDigits[(b >> 0) & 0x0f]);
+    }
+
+    private static void appendEncoded(StringBuffer sb, char c) {
+        ByteBuffer bb = null;
+        try {
+            bb = ThreadLocalCoders.encoderFor("UTF-8")
+                .encode(CharBuffer.wrap("" + c));
+        } catch (CharacterCodingException x) {
+            assert false;
+        }
+        while (bb.hasRemaining()) {
+            int b = bb.get() & 0xff;
+            if (b >= 0x80)
+                appendEscape(sb, (byte)b);
+            else
+                sb.append((char)b);
+        }
+    }
+
+    // Quote any characters in s that are not permitted
+    // by the given mask pair
+    //
+    private static String quote(String s, long lowMask, long highMask) {
+        int n = s.length();
+        StringBuffer sb = null;
+        boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0);
+        for (int i = 0; i < s.length(); i++) {
+            char c = s.charAt(i);
+            if (c < '\u0080') {
+                if (!match(c, lowMask, highMask)) {
+                    if (sb == null) {
+                        sb = new StringBuffer();
+                        sb.append(s.substring(0, i));
+                    }
+                    appendEscape(sb, (byte)c);
+                } else {
+                    if (sb != null)
+                        sb.append(c);
+                }
+            } else if (allowNonASCII
+                       && (Character.isSpaceChar(c)
+                           || Character.isISOControl(c))) {
+                if (sb == null) {
+                    sb = new StringBuffer();
+                    sb.append(s.substring(0, i));
+                }
+                appendEncoded(sb, c);
+            } else {
+                if (sb != null)
+                    sb.append(c);
+            }
+        }
+        return (sb == null) ? s : sb.toString();
+    }
+
+    // Encodes all characters >= \u0080 into escaped, normalized UTF-8 octets,
+    // assuming that s is otherwise legal
+    //
+    private static String encode(String s) {
+        int n = s.length();
+        if (n == 0)
+            return s;
+
+        // First check whether we actually need to encode
+        for (int i = 0;;) {
+            if (s.charAt(i) >= '\u0080')
+                break;
+            if (++i >= n)
+                return s;
+        }
+
+        String ns = Normalizer.normalize(s, Normalizer.Form.NFC);
+        ByteBuffer bb = null;
+        try {
+            bb = ThreadLocalCoders.encoderFor("UTF-8")
+                .encode(CharBuffer.wrap(ns));
+        } catch (CharacterCodingException x) {
+            assert false;
+        }
+
+        StringBuffer sb = new StringBuffer();
+        while (bb.hasRemaining()) {
+            int b = bb.get() & 0xff;
+            if (b >= 0x80)
+                appendEscape(sb, (byte)b);
+            else
+                sb.append((char)b);
+        }
+        return sb.toString();
+    }
+
+    private static int decode(char c) {
+        if ((c >= '0') && (c <= '9'))
+            return c - '0';
+        if ((c >= 'a') && (c <= 'f'))
+            return c - 'a' + 10;
+        if ((c >= 'A') && (c <= 'F'))
+            return c - 'A' + 10;
+        assert false;
+        return -1;
+    }
+
+    private static byte decode(char c1, char c2) {
+        return (byte)(  ((decode(c1) & 0xf) << 4)
+                      | ((decode(c2) & 0xf) << 0));
+    }
+
+    // Evaluates all escapes in s, applying UTF-8 decoding if needed.  Assumes
+    // that escapes are well-formed syntactically, i.e., of the form %XX.  If a
+    // sequence of escaped octets is not valid UTF-8 then the erroneous octets
+    // are replaced with '\uFFFD'.
+    // Exception: any "%" found between "[]" is left alone. It is an IPv6 literal
+    //            with a scope_id
+    //
+    private static String decode(String s) {
+        if (s == null)
+            return s;
+        int n = s.length();
+        if (n == 0)
+            return s;
+        if (s.indexOf('%') < 0)
+            return s;
+
+        StringBuffer sb = new StringBuffer(n);
+        ByteBuffer bb = ByteBuffer.allocate(n);
+        CharBuffer cb = CharBuffer.allocate(n);
+        CharsetDecoder dec = ThreadLocalCoders.decoderFor("UTF-8")
+            .onMalformedInput(CodingErrorAction.REPLACE)
+            .onUnmappableCharacter(CodingErrorAction.REPLACE);
+
+        // This is not horribly efficient, but it will do for now
+        char c = s.charAt(0);
+        boolean betweenBrackets = false;
+
+        for (int i = 0; i < n;) {
+            assert c == s.charAt(i);    // Loop invariant
+            if (c == '[') {
+                betweenBrackets = true;
+            } else if (betweenBrackets && c == ']') {
+                betweenBrackets = false;
+            }
+            if (c != '%' || betweenBrackets) {
+                sb.append(c);
+                if (++i >= n)
+                    break;
+                c = s.charAt(i);
+                continue;
+            }
+            bb.clear();
+            int ui = i;
+            for (;;) {
+                assert (n - i >= 2);
+                bb.put(decode(s.charAt(++i), s.charAt(++i)));
+                if (++i >= n)
+                    break;
+                c = s.charAt(i);
+                if (c != '%')
+                    break;
+            }
+            bb.flip();
+            cb.clear();
+            dec.reset();
+            CoderResult cr = dec.decode(bb, cb, true);
+            assert cr.isUnderflow();
+            cr = dec.flush(cb);
+            assert cr.isUnderflow();
+            sb.append(cb.flip().toString());
+        }
+
+        return sb.toString();
+    }
+
+
+    // -- Parsing --
+
+    // For convenience we wrap the input URI string in a new instance of the
+    // following internal class.  This saves always having to pass the input
+    // string as an argument to each internal scan/parse method.
+
+    private class Parser {
+
+        private String input;           // URI input string
+        private boolean requireServerAuthority = false;
+
+        Parser(String s) {
+            input = s;
+            string = s;
+        }
+
+        // -- Methods for throwing URISyntaxException in various ways --
+
+        private void fail(String reason) throws URISyntaxException {
+            throw new URISyntaxException(input, reason);
+        }
+
+        private void fail(String reason, int p) throws URISyntaxException {
+            throw new URISyntaxException(input, reason, p);
+        }
+
+        private void failExpecting(String expected, int p)
+            throws URISyntaxException
+        {
+            fail("Expected " + expected, p);
+        }
+
+        private void failExpecting(String expected, String prior, int p)
+            throws URISyntaxException
+        {
+            fail("Expected " + expected + " following " + prior, p);
+        }
+
+
+        // -- Simple access to the input string --
+
+        // Return a substring of the input string
+        //
+        private String substring(int start, int end) {
+            return input.substring(start, end);
+        }
+
+        // Return the char at position p,
+        // assuming that p < input.length()
+        //
+        private char charAt(int p) {
+            return input.charAt(p);
+        }
+
+        // Tells whether start < end and, if so, whether charAt(start) == c
+        //
+        private boolean at(int start, int end, char c) {
+            return (start < end) && (charAt(start) == c);
+        }
+
+        // Tells whether start + s.length() < end and, if so,
+        // whether the chars at the start position match s exactly
+        //
+        private boolean at(int start, int end, String s) {
+            int p = start;
+            int sn = s.length();
+            if (sn > end - p)
+                return false;
+            int i = 0;
+            while (i < sn) {
+                if (charAt(p++) != s.charAt(i)) {
+                    break;
+                }
+                i++;
+            }
+            return (i == sn);
+        }
+
+
+        // -- Scanning --
+
+        // The various scan and parse methods that follow use a uniform
+        // convention of taking the current start position and end index as
+        // their first two arguments.  The start is inclusive while the end is
+        // exclusive, just as in the String class, i.e., a start/end pair
+        // denotes the left-open interval [start, end) of the input string.
+        //
+        // These methods never proceed past the end position.  They may return
+        // -1 to indicate outright failure, but more often they simply return
+        // the position of the first char after the last char scanned.  Thus
+        // a typical idiom is
+        //
+        //     int p = start;
+        //     int q = scan(p, end, ...);
+        //     if (q > p)
+        //         // We scanned something
+        //         ...;
+        //     else if (q == p)
+        //         // We scanned nothing
+        //         ...;
+        //     else if (q == -1)
+        //         // Something went wrong
+        //         ...;
+
+
+        // Scan a specific char: If the char at the given start position is
+        // equal to c, return the index of the next char; otherwise, return the
+        // start position.
+        //
+        private int scan(int start, int end, char c) {
+            if ((start < end) && (charAt(start) == c))
+                return start + 1;
+            return start;
+        }
+
+        // Scan forward from the given start position.  Stop at the first char
+        // in the err string (in which case -1 is returned), or the first char
+        // in the stop string (in which case the index of the preceding char is
+        // returned), or the end of the input string (in which case the length
+        // of the input string is returned).  May return the start position if
+        // nothing matches.
+        //
+        private int scan(int start, int end, String err, String stop) {
+            int p = start;
+            while (p < end) {
+                char c = charAt(p);
+                if (err.indexOf(c) >= 0)
+                    return -1;
+                if (stop.indexOf(c) >= 0)
+                    break;
+                p++;
+            }
+            return p;
+        }
+
+        // Scan a potential escape sequence, starting at the given position,
+        // with the given first char (i.e., charAt(start) == c).
+        //
+        // This method assumes that if escapes are allowed then visible
+        // non-US-ASCII chars are also allowed.
+        //
+        private int scanEscape(int start, int n, char first)
+            throws URISyntaxException
+        {
+            int p = start;
+            char c = first;
+            if (c == '%') {
+                // Process escape pair
+                if ((p + 3 <= n)
+                    && match(charAt(p + 1), L_HEX, H_HEX)
+                    && match(charAt(p + 2), L_HEX, H_HEX)) {
+                    return p + 3;
+                }
+                fail("Malformed escape pair", p);
+            } else if ((c > 128)
+                       && !Character.isSpaceChar(c)
+                       && !Character.isISOControl(c)) {
+                // Allow unescaped but visible non-US-ASCII chars
+                return p + 1;
+            }
+            return p;
+        }
+
+        // Scan chars that match the given mask pair
+        //
+        private int scan(int start, int n, long lowMask, long highMask)
+            throws URISyntaxException
+        {
+            int p = start;
+            while (p < n) {
+                char c = charAt(p);
+                if (match(c, lowMask, highMask)) {
+                    p++;
+                    continue;
+                }
+                if ((lowMask & L_ESCAPED) != 0) {
+                    int q = scanEscape(p, n, c);
+                    if (q > p) {
+                        p = q;
+                        continue;
+                    }
+                }
+                break;
+            }
+            return p;
+        }
+
+        // Check that each of the chars in [start, end) matches the given mask
+        //
+        private void checkChars(int start, int end,
+                                long lowMask, long highMask,
+                                String what)
+            throws URISyntaxException
+        {
+            int p = scan(start, end, lowMask, highMask);
+            if (p < end)
+                fail("Illegal character in " + what, p);
+        }
+
+        // Check that the char at position p matches the given mask
+        //
+        private void checkChar(int p,
+                               long lowMask, long highMask,
+                               String what)
+            throws URISyntaxException
+        {
+            checkChars(p, p + 1, lowMask, highMask, what);
+        }
+
+
+        // -- Parsing --
+
+        // [<scheme>:]<scheme-specific-part>[#<fragment>]
+        //
+        void parse(boolean rsa) throws URISyntaxException {
+            requireServerAuthority = rsa;
+            int ssp;                    // Start of scheme-specific part
+            int n = input.length();
+            int p = scan(0, n, "/?#", ":");
+            if ((p >= 0) && at(p, n, ':')) {
+                if (p == 0)
+                    failExpecting("scheme name", 0);
+                checkChar(0, L_ALPHA, H_ALPHA, "scheme name");
+                checkChars(1, p, L_SCHEME, H_SCHEME, "scheme name");
+                scheme = substring(0, p);
+                p++;                    // Skip ':'
+                ssp = p;
+                if (at(p, n, '/')) {
+                    p = parseHierarchical(p, n);
+                } else {
+                    int q = scan(p, n, "", "#");
+                    if (q <= p)
+                        failExpecting("scheme-specific part", p);
+                    checkChars(p, q, L_URIC, H_URIC, "opaque part");
+                    p = q;
+                }
+            } else {
+                ssp = 0;
+                p = parseHierarchical(0, n);
+            }
+            schemeSpecificPart = substring(ssp, p);
+            if (at(p, n, '#')) {
+                checkChars(p + 1, n, L_URIC, H_URIC, "fragment");
+                fragment = substring(p + 1, n);
+                p = n;
+            }
+            if (p < n)
+                fail("end of URI", p);
+        }
+
+        // [//authority]<path>[?<query>]
+        //
+        // DEVIATION from RFC2396: We allow an empty authority component as
+        // long as it's followed by a non-empty path, query component, or
+        // fragment component.  This is so that URIs such as "file:///foo/bar"
+        // will parse.  This seems to be the intent of RFC2396, though the
+        // grammar does not permit it.  If the authority is empty then the
+        // userInfo, host, and port components are undefined.
+        //
+        // DEVIATION from RFC2396: We allow empty relative paths.  This seems
+        // to be the intent of RFC2396, but the grammar does not permit it.
+        // The primary consequence of this deviation is that "#f" parses as a
+        // relative URI with an empty path.
+        //
+        private int parseHierarchical(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            if (at(p, n, '/') && at(p + 1, n, '/')) {
+                p += 2;
+                int q = scan(p, n, "", "/?#");
+                if (q > p) {
+                    p = parseAuthority(p, q);
+                } else if (q < n) {
+                    // DEVIATION: Allow empty authority prior to non-empty
+                    // path, query component or fragment identifier
+                } else
+                    failExpecting("authority", p);
+            }
+            int q = scan(p, n, "", "?#"); // DEVIATION: May be empty
+            checkChars(p, q, L_PATH, H_PATH, "path");
+            path = substring(p, q);
+            p = q;
+            if (at(p, n, '?')) {
+                p++;
+                q = scan(p, n, "", "#");
+                checkChars(p, q, L_URIC, H_URIC, "query");
+                query = substring(p, q);
+                p = q;
+            }
+            return p;
+        }
+
+        // authority     = server | reg_name
+        //
+        // Ambiguity: An authority that is a registry name rather than a server
+        // might have a prefix that parses as a server.  We use the fact that
+        // the authority component is always followed by '/' or the end of the
+        // input string to resolve this: If the complete authority did not
+        // parse as a server then we try to parse it as a registry name.
+        //
+        private int parseAuthority(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q = p;
+            URISyntaxException ex = null;
+
+            boolean serverChars;
+            boolean regChars;
+
+            if (scan(p, n, "", "]") > p) {
+                // contains a literal IPv6 address, therefore % is allowed
+                serverChars = (scan(p, n, L_SERVER_PERCENT, H_SERVER_PERCENT) == n);
+            } else {
+                serverChars = (scan(p, n, L_SERVER, H_SERVER) == n);
+            }
+            regChars = (scan(p, n, L_REG_NAME, H_REG_NAME) == n);
+
+            if (regChars && !serverChars) {
+                // Must be a registry-based authority
+                authority = substring(p, n);
+                return n;
+            }
+
+            if (serverChars) {
+                // Might be (probably is) a server-based authority, so attempt
+                // to parse it as such.  If the attempt fails, try to treat it
+                // as a registry-based authority.
+                try {
+                    q = parseServer(p, n);
+                    if (q < n)
+                        failExpecting("end of authority", q);
+                    authority = substring(p, n);
+                } catch (URISyntaxException x) {
+                    // Undo results of failed parse
+                    userInfo = null;
+                    host = null;
+                    port = -1;
+                    if (requireServerAuthority) {
+                        // If we're insisting upon a server-based authority,
+                        // then just re-throw the exception
+                        throw x;
+                    } else {
+                        // Save the exception in case it doesn't parse as a
+                        // registry either
+                        ex = x;
+                        q = p;
+                    }
+                }
+            }
+
+            if (q < n) {
+                if (regChars) {
+                    // Registry-based authority
+                    authority = substring(p, n);
+                } else if (ex != null) {
+                    // Re-throw exception; it was probably due to
+                    // a malformed IPv6 address
+                    throw ex;
+                } else {
+                    fail("Illegal character in authority", q);
+                }
+            }
+
+            return n;
+        }
+
+
+        // [<userinfo>@]<host>[:<port>]
+        //
+        private int parseServer(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q;
+
+            // userinfo
+            q = scan(p, n, "/?#", "@");
+            if ((q >= p) && at(q, n, '@')) {
+                checkChars(p, q, L_USERINFO, H_USERINFO, "user info");
+                userInfo = substring(p, q);
+                p = q + 1;              // Skip '@'
+            }
+
+            // hostname, IPv4 address, or IPv6 address
+            if (at(p, n, '[')) {
+                // DEVIATION from RFC2396: Support IPv6 addresses, per RFC2732
+                p++;
+                q = scan(p, n, "/?#", "]");
+                if ((q > p) && at(q, n, ']')) {
+                    // look for a "%" scope id
+                    int r = scan (p, q, "", "%");
+                    if (r > p) {
+                        parseIPv6Reference(p, r);
+                        if (r+1 == q) {
+                            fail ("scope id expected");
+                        }
+                        checkChars (r+1, q, L_ALPHANUM, H_ALPHANUM,
+                                                "scope id");
+                    } else {
+                        parseIPv6Reference(p, q);
+                    }
+                    host = substring(p-1, q+1);
+                    p = q + 1;
+                } else {
+                    failExpecting("closing bracket for IPv6 address", q);
+                }
+            } else {
+                q = parseIPv4Address(p, n);
+                if (q <= p)
+                    q = parseHostname(p, n);
+                p = q;
+            }
+
+            // port
+            if (at(p, n, ':')) {
+                p++;
+                q = scan(p, n, "", "/");
+                if (q > p) {
+                    checkChars(p, q, L_DIGIT, H_DIGIT, "port number");
+                    try {
+                        port = Integer.parseInt(substring(p, q));
+                    } catch (NumberFormatException x) {
+                        fail("Malformed port number", p);
+                    }
+                    p = q;
+                }
+            }
+            if (p < n)
+                failExpecting("port number", p);
+
+            return p;
+        }
+
+        // Scan a string of decimal digits whose value fits in a byte
+        //
+        private int scanByte(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q = scan(p, n, L_DIGIT, H_DIGIT);
+            if (q <= p) return q;
+            if (Integer.parseInt(substring(p, q)) > 255) return p;
+            return q;
+        }
+
+        // Scan an IPv4 address.
+        //
+        // If the strict argument is true then we require that the given
+        // interval contain nothing besides an IPv4 address; if it is false
+        // then we only require that it start with an IPv4 address.
+        //
+        // If the interval does not contain or start with (depending upon the
+        // strict argument) a legal IPv4 address characters then we return -1
+        // immediately; otherwise we insist that these characters parse as a
+        // legal IPv4 address and throw an exception on failure.
+        //
+        // We assume that any string of decimal digits and dots must be an IPv4
+        // address.  It won't parse as a hostname anyway, so making that
+        // assumption here allows more meaningful exceptions to be thrown.
+        //
+        private int scanIPv4Address(int start, int n, boolean strict)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q;
+            int m = scan(p, n, L_DIGIT | L_DOT, H_DIGIT | H_DOT);
+            if ((m <= p) || (strict && (m != n)))
+                return -1;
+            for (;;) {
+                // Per RFC2732: At most three digits per byte
+                // Further constraint: Each element fits in a byte
+                if ((q = scanByte(p, m)) <= p) break;   p = q;
+                if ((q = scan(p, m, '.')) <= p) break;  p = q;
+                if ((q = scanByte(p, m)) <= p) break;   p = q;
+                if ((q = scan(p, m, '.')) <= p) break;  p = q;
+                if ((q = scanByte(p, m)) <= p) break;   p = q;
+                if ((q = scan(p, m, '.')) <= p) break;  p = q;
+                if ((q = scanByte(p, m)) <= p) break;   p = q;
+                if (q < m) break;
+                return q;
+            }
+            fail("Malformed IPv4 address", q);
+            return -1;
+        }
+
+        // Take an IPv4 address: Throw an exception if the given interval
+        // contains anything except an IPv4 address
+        //
+        private int takeIPv4Address(int start, int n, String expected)
+            throws URISyntaxException
+        {
+            int p = scanIPv4Address(start, n, true);
+            if (p <= start)
+                failExpecting(expected, start);
+            return p;
+        }
+
+        // Attempt to parse an IPv4 address, returning -1 on failure but
+        // allowing the given interval to contain [:<characters>] after
+        // the IPv4 address.
+        //
+        private int parseIPv4Address(int start, int n) {
+            int p;
+
+            try {
+                p = scanIPv4Address(start, n, false);
+            } catch (URISyntaxException x) {
+                return -1;
+            } catch (NumberFormatException nfe) {
+                return -1;
+            }
+
+            if (p > start && p < n) {
+                // IPv4 address is followed by something - check that
+                // it's a ":" as this is the only valid character to
+                // follow an address.
+                if (charAt(p) != ':') {
+                    p = -1;
+                }
+            }
+
+            if (p > start)
+                host = substring(start, p);
+
+            return p;
+        }
+
+        // Android-changed: Allow underscore in hostname.
+        // Added "_" to the grammars for domainLabel and topLabel.
+        // hostname      = domainlabel [ "." ] | 1*( domainlabel "." ) toplabel [ "." ]
+        // domainlabel   = alphanum | alphanum *( alphanum | "-" | "_" ) alphanum
+        // toplabel      = alpha | alpha *( alphanum | "-" | "_" ) alphanum
+        //
+        private int parseHostname(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q;
+            int l = -1;                 // Start of last parsed label
+
+            do {
+                // Android-changed: Allow underscore in hostname.
+                // RFC 2396 only allows alphanumeric characters and hyphens, but real,
+                // large Internet hosts in the wild use underscore, so we have to allow it.
+                // http://code.google.com/p/android/issues/detail?id=37577
+                // http://b/17579865
+                // http://b/18016625
+                // http://b/18023709
+
+                // domainlabel = alphanum [ *( alphanum | "-" | "_" ) alphanum ]
+                q = scan(p, n, L_ALPHANUM, H_ALPHANUM);
+                if (q <= p)
+                    break;
+                l = p;
+                if (q > p) {
+                    p = q;
+                    // Android-changed: Allow underscore in hostname.
+                    // q = scan(p, n, L_ALPHANUM | L_DASH, H_ALPHANUM | H_DASH);
+                    q = scan(p, n, L_ALPHANUM | L_DASH | L_UNDERSCORE, H_ALPHANUM | H_DASH | H_UNDERSCORE);
+                    if (q > p) {
+                        if (charAt(q - 1) == '-')
+                            fail("Illegal character in hostname", q - 1);
+                        p = q;
+                    }
+                }
+                q = scan(p, n, '.');
+                if (q <= p)
+                    break;
+                p = q;
+            } while (p < n);
+
+            if ((p < n) && !at(p, n, ':'))
+                fail("Illegal character in hostname", p);
+
+            if (l < 0)
+                failExpecting("hostname", start);
+
+            // for a fully qualified hostname check that the rightmost
+            // label starts with an alpha character.
+            if (l > start && !match(charAt(l), L_ALPHA, H_ALPHA)) {
+                fail("Illegal character in hostname", l);
+            }
+
+            host = substring(start, p);
+            return p;
+        }
+
+
+        // IPv6 address parsing, from RFC2373: IPv6 Addressing Architecture
+        //
+        // Bug: The grammar in RFC2373 Appendix B does not allow addresses of
+        // the form ::12.34.56.78, which are clearly shown in the examples
+        // earlier in the document.  Here is the original grammar:
+        //
+        //   IPv6address = hexpart [ ":" IPv4address ]
+        //   hexpart     = hexseq | hexseq "::" [ hexseq ] | "::" [ hexseq ]
+        //   hexseq      = hex4 *( ":" hex4)
+        //   hex4        = 1*4HEXDIG
+        //
+        // We therefore use the following revised grammar:
+        //
+        //   IPv6address = hexseq [ ":" IPv4address ]
+        //                 | hexseq [ "::" [ hexpost ] ]
+        //                 | "::" [ hexpost ]
+        //   hexpost     = hexseq | hexseq ":" IPv4address | IPv4address
+        //   hexseq      = hex4 *( ":" hex4)
+        //   hex4        = 1*4HEXDIG
+        //
+        // This covers all and only the following cases:
+        //
+        //   hexseq
+        //   hexseq : IPv4address
+        //   hexseq ::
+        //   hexseq :: hexseq
+        //   hexseq :: hexseq : IPv4address
+        //   hexseq :: IPv4address
+        //   :: hexseq
+        //   :: hexseq : IPv4address
+        //   :: IPv4address
+        //   ::
+        //
+        // Additionally we constrain the IPv6 address as follows :-
+        //
+        //  i.  IPv6 addresses without compressed zeros should contain
+        //      exactly 16 bytes.
+        //
+        //  ii. IPv6 addresses with compressed zeros should contain
+        //      less than 16 bytes.
+
+        private int ipv6byteCount = 0;
+
+        private int parseIPv6Reference(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q;
+            boolean compressedZeros = false;
+
+            q = scanHexSeq(p, n);
+
+            if (q > p) {
+                p = q;
+                if (at(p, n, "::")) {
+                    compressedZeros = true;
+                    p = scanHexPost(p + 2, n);
+                } else if (at(p, n, ':')) {
+                    p = takeIPv4Address(p + 1,  n, "IPv4 address");
+                    ipv6byteCount += 4;
+                }
+            } else if (at(p, n, "::")) {
+                compressedZeros = true;
+                p = scanHexPost(p + 2, n);
+            }
+            if (p < n)
+                fail("Malformed IPv6 address", start);
+            if (ipv6byteCount > 16)
+                fail("IPv6 address too long", start);
+            if (!compressedZeros && ipv6byteCount < 16)
+                fail("IPv6 address too short", start);
+            if (compressedZeros && ipv6byteCount == 16)
+                fail("Malformed IPv6 address", start);
+
+            return p;
+        }
+
+        private int scanHexPost(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q;
+
+            if (p == n)
+                return p;
+
+            q = scanHexSeq(p, n);
+            if (q > p) {
+                p = q;
+                if (at(p, n, ':')) {
+                    p++;
+                    p = takeIPv4Address(p, n, "hex digits or IPv4 address");
+                    ipv6byteCount += 4;
+                }
+            } else {
+                p = takeIPv4Address(p, n, "hex digits or IPv4 address");
+                ipv6byteCount += 4;
+            }
+            return p;
+        }
+
+        // Scan a hex sequence; return -1 if one could not be scanned
+        //
+        private int scanHexSeq(int start, int n)
+            throws URISyntaxException
+        {
+            int p = start;
+            int q;
+
+            q = scan(p, n, L_HEX, H_HEX);
+            if (q <= p)
+                return -1;
+            if (at(q, n, '.'))          // Beginning of IPv4 address
+                return -1;
+            if (q > p + 4)
+                fail("IPv6 hexadecimal digit sequence too long", p);
+            ipv6byteCount += 2;
+            p = q;
+            while (p < n) {
+                if (!at(p, n, ':'))
+                    break;
+                if (at(p + 1, n, ':'))
+                    break;              // "::"
+                p++;
+                q = scan(p, n, L_HEX, H_HEX);
+                if (q <= p)
+                    failExpecting("digits for an IPv6 address", p);
+                if (at(q, n, '.')) {    // Beginning of IPv4 address
+                    p--;
+                    break;
+                }
+                if (q > p + 4)
+                    fail("IPv6 hexadecimal digit sequence too long", p);
+                ipv6byteCount += 2;
+                p = q;
+            }
+
+            return p;
+        }
+
+    }
+
+}
diff --git a/java/net/URISyntaxException.java b/java/net/URISyntaxException.java
new file mode 100644
index 0000000..8072c37
--- /dev/null
+++ b/java/net/URISyntaxException.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+
+/**
+ * Checked exception thrown to indicate that a string could not be parsed as a
+ * URI reference.
+ *
+ * @author Mark Reinhold
+ * @see URI
+ * @since 1.4
+ */
+
+public class URISyntaxException
+    extends Exception
+{
+    private static final long serialVersionUID = 2137979680897488891L;
+
+    private String input;
+    private int index;
+
+    /**
+     * Constructs an instance from the given input string, reason, and error
+     * index.
+     *
+     * @param  input   The input string
+     * @param  reason  A string explaining why the input could not be parsed
+     * @param  index   The index at which the parse error occurred,
+     *                 or {@code -1} if the index is not known
+     *
+     * @throws  NullPointerException
+     *          If either the input or reason strings are {@code null}
+     *
+     * @throws  IllegalArgumentException
+     *          If the error index is less than {@code -1}
+     */
+    public URISyntaxException(String input, String reason, int index) {
+        super(reason);
+        if ((input == null) || (reason == null))
+            throw new NullPointerException();
+        if (index < -1)
+            throw new IllegalArgumentException();
+        this.input = input;
+        this.index = index;
+    }
+
+    /**
+     * Constructs an instance from the given input string and reason.  The
+     * resulting object will have an error index of {@code -1}.
+     *
+     * @param  input   The input string
+     * @param  reason  A string explaining why the input could not be parsed
+     *
+     * @throws  NullPointerException
+     *          If either the input or reason strings are {@code null}
+     */
+    public URISyntaxException(String input, String reason) {
+        this(input, reason, -1);
+    }
+
+    /**
+     * Returns the input string.
+     *
+     * @return  The input string
+     */
+    public String getInput() {
+        return input;
+    }
+
+    /**
+     * Returns a string explaining why the input string could not be parsed.
+     *
+     * @return  The reason string
+     */
+    public String getReason() {
+        return super.getMessage();
+    }
+
+    /**
+     * Returns an index into the input string of the position at which the
+     * parse error occurred, or {@code -1} if this position is not known.
+     *
+     * @return  The error index
+     */
+    public int getIndex() {
+        return index;
+    }
+
+    /**
+     * Returns a string describing the parse error.  The resulting string
+     * consists of the reason string followed by a colon character
+     * ({@code ':'}), a space, and the input string.  If the error index is
+     * defined then the string {@code " at index "} followed by the index, in
+     * decimal, is inserted after the reason string and before the colon
+     * character.
+     *
+     * @return  A string describing the parse error
+     */
+    public String getMessage() {
+        StringBuffer sb = new StringBuffer();
+        sb.append(getReason());
+        if (index > -1) {
+            sb.append(" at index ");
+            sb.append(index);
+        }
+        sb.append(": ");
+        sb.append(input);
+        return sb.toString();
+    }
+
+}
diff --git a/java/net/URL.java b/java/net/URL.java
new file mode 100644
index 0000000..74dec92
--- /dev/null
+++ b/java/net/URL.java
@@ -0,0 +1,1627 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream.GetField;
+import java.io.ObjectStreamException;
+import java.io.ObjectStreamField;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.StringTokenizer;
+import sun.security.util.SecurityConstants;
+
+/**
+ * Class {@code URL} represents a Uniform Resource
+ * Locator, a pointer to a "resource" on the World
+ * Wide Web. A resource can be something as simple as a file or a
+ * directory, or it can be a reference to a more complicated object,
+ * such as a query to a database or to a search engine. More
+ * information on the types of URLs and their formats can be found at:
+ * <a href=
+ * "http://web.archive.org/web/20051219043731/http://archive.ncsa.uiuc.edu/SDG/Software/Mosaic/Demo/url-primer.html">
+ * <i>Types of URL</i></a>
+ * <p>
+ * In general, a URL can be broken into several parts. Consider the
+ * following example:
+ * <blockquote><pre>
+ *     http://www.example.com/docs/resource1.html
+ * </pre></blockquote>
+ * <p>
+ * The URL above indicates that the protocol to use is
+ * {@code http} (HyperText Transfer Protocol) and that the
+ * information resides on a host machine named
+ * {@code www.example.com}. The information on that host
+ * machine is named {@code /docs/resource1.html}. The exact
+ * meaning of this name on the host machine is both protocol
+ * dependent and host dependent. The information normally resides in
+ * a file, but it could be generated on the fly. This component of
+ * the URL is called the <i>path</i> component.
+ * <p>
+ * A URL can optionally specify a "port", which is the
+ * port number to which the TCP connection is made on the remote host
+ * machine. If the port is not specified, the default port for
+ * the protocol is used instead. For example, the default port for
+ * {@code http} is {@code 80}. An alternative port could be
+ * specified as:
+ * <blockquote><pre>
+ *     http://www.example.com:1080/docs/resource1.html
+ * </pre></blockquote>
+ * <p>
+ * The syntax of {@code URL} is defined by  <a
+ * href="http://www.ietf.org/rfc/rfc2396.txt"><i>RFC&nbsp;2396: Uniform
+ * Resource Identifiers (URI): Generic Syntax</i></a>, amended by <a
+ * href="http://www.ietf.org/rfc/rfc2732.txt"><i>RFC&nbsp;2732: Format for
+ * Literal IPv6 Addresses in URLs</i></a>. The Literal IPv6 address format
+ * also supports scope_ids. The syntax and usage of scope_ids is described
+ * <a href="Inet6Address.html#scoped">here</a>.
+ * <p>
+ * A URL may have appended to it a "fragment", also known
+ * as a "ref" or a "reference". The fragment is indicated by the sharp
+ * sign character "#" followed by more characters. For example,
+ * <blockquote><pre>
+ *     http://java.sun.com/index.html#chapter1
+ * </pre></blockquote>
+ * <p>
+ * This fragment is not technically part of the URL. Rather, it
+ * indicates that after the specified resource is retrieved, the
+ * application is specifically interested in that part of the
+ * document that has the tag {@code chapter1} attached to it. The
+ * meaning of a tag is resource specific.
+ * <p>
+ * An application can also specify a "relative URL",
+ * which contains only enough information to reach the resource
+ * relative to another URL. Relative URLs are frequently used within
+ * HTML pages. For example, if the contents of the URL:
+ * <blockquote><pre>
+ *     http://java.sun.com/index.html
+ * </pre></blockquote>
+ * contained within it the relative URL:
+ * <blockquote><pre>
+ *     FAQ.html
+ * </pre></blockquote>
+ * it would be a shorthand for:
+ * <blockquote><pre>
+ *     http://java.sun.com/FAQ.html
+ * </pre></blockquote>
+ * <p>
+ * The relative URL need not specify all the components of a URL. If
+ * the protocol, host name, or port number is missing, the value is
+ * inherited from the fully specified URL. The file component must be
+ * specified. The optional fragment is not inherited.
+ * <p>
+ * The URL class does not itself encode or decode any URL components
+ * according to the escaping mechanism defined in RFC2396. It is the
+ * responsibility of the caller to encode any fields, which need to be
+ * escaped prior to calling URL, and also to decode any escaped fields,
+ * that are returned from URL. Furthermore, because URL has no knowledge
+ * of URL escaping, it does not recognise equivalence between the encoded
+ * or decoded form of the same URL. For example, the two URLs:<br>
+ * <pre>    http://foo.com/hello world/ and http://foo.com/hello%20world</pre>
+ * would be considered not equal to each other.
+ * <p>
+ * Note, the {@link java.net.URI} class does perform escaping of its
+ * component fields in certain circumstances. The recommended way
+ * to manage the encoding and decoding of URLs is to use {@link java.net.URI},
+ * and to convert between these two classes using {@link #toURI()} and
+ * {@link URI#toURL()}.
+ * <p>
+ * The {@link URLEncoder} and {@link URLDecoder} classes can also be
+ * used, but only for HTML form encoding, which is not the same
+ * as the encoding scheme defined in RFC2396.
+ *
+ * @author  James Gosling
+ * @since JDK1.0
+ */
+public final class URL implements java.io.Serializable {
+
+    // Android-changed: Custom built-in URLStreamHandlers for http, https.
+    // static final String BUILTIN_HANDLERS_PREFIX = "sun.net.www.protocol";
+    private static final Set<String> BUILTIN_HANDLER_CLASS_NAMES = createBuiltinHandlerClassNames();
+    static final long serialVersionUID = -7627629688361524110L;
+
+    /**
+     * The property which specifies the package prefix list to be scanned
+     * for protocol handlers.  The value of this property (if any) should
+     * be a vertical bar delimited list of package names to search through
+     * for a protocol handler to load.  The policy of this class is that
+     * all protocol handlers will be in a class called <protocolname>.Handler,
+     * and each package in the list is examined in turn for a matching
+     * handler.  If none are found (or the property is not specified), the
+     * default package prefix, sun.net.www.protocol, is used.  The search
+     * proceeds from the first package in the list to the last and stops
+     * when a match is found.
+     */
+    private static final String protocolPathProp = "java.protocol.handler.pkgs";
+
+    /**
+     * The protocol to use (ftp, http, nntp, ... etc.) .
+     * @serial
+     */
+    private String protocol;
+
+    /**
+     * The host name to connect to.
+     * @serial
+     */
+    private String host;
+
+    /**
+     * The protocol port to connect to.
+     * @serial
+     */
+    private int port = -1;
+
+    /**
+     * The specified file name on that host. {@code file} is
+     * defined as {@code path[?query]}
+     * @serial
+     */
+    private String file;
+
+    /**
+     * The query part of this URL.
+     */
+    private transient String query;
+
+    /**
+     * The authority part of this URL.
+     * @serial
+     */
+    private String authority;
+
+    /**
+     * The path part of this URL.
+     */
+    private transient String path;
+
+    /**
+     * The userinfo part of this URL.
+     */
+    private transient String userInfo;
+
+    /**
+     * # reference.
+     * @serial
+     */
+    private String ref;
+
+    /**
+     * The host's IP address, used in equals and hashCode.
+     * Computed on demand. An uninitialized or unknown hostAddress is null.
+     */
+    transient InetAddress hostAddress;
+
+    /**
+     * The URLStreamHandler for this URL.
+     */
+    transient URLStreamHandler handler;
+
+    /* Our hash code.
+     * @serial
+     */
+    private int hashCode = -1;
+
+    private transient UrlDeserializedState tempState;
+
+    /**
+     * Creates a {@code URL} object from the specified
+     * {@code protocol}, {@code host}, {@code port}
+     * number, and {@code file}.<p>
+     *
+     * {@code host} can be expressed as a host name or a literal
+     * IP address. If IPv6 literal address is used, it should be
+     * enclosed in square brackets ({@code '['} and {@code ']'}), as
+     * specified by <a
+     * href="http://www.ietf.org/rfc/rfc2732.txt">RFC&nbsp;2732</a>;
+     * However, the literal IPv6 address format defined in <a
+     * href="http://www.ietf.org/rfc/rfc2373.txt"><i>RFC&nbsp;2373: IP
+     * Version 6 Addressing Architecture</i></a> is also accepted.<p>
+     *
+     * Specifying a {@code port} number of {@code -1}
+     * indicates that the URL should use the default port for the
+     * protocol.<p>
+     *
+     * If this is the first URL object being created with the specified
+     * protocol, a <i>stream protocol handler</i> object, an instance of
+     * class {@code URLStreamHandler}, is created for that protocol:
+     * <ol>
+     * <li>If the application has previously set up an instance of
+     *     {@code URLStreamHandlerFactory} as the stream handler factory,
+     *     then the {@code createURLStreamHandler} method of that instance
+     *     is called with the protocol string as an argument to create the
+     *     stream protocol handler.
+     * <li>If no {@code URLStreamHandlerFactory} has yet been set up,
+     *     or if the factory's {@code createURLStreamHandler} method
+     *     returns {@code null}, then the constructor finds the
+     *     value of the system property:
+     *     <blockquote><pre>
+     *         java.protocol.handler.pkgs
+     *     </pre></blockquote>
+     *     If the value of that system property is not {@code null},
+     *     it is interpreted as a list of packages separated by a vertical
+     *     slash character '{@code |}'. The constructor tries to load
+     *     the class named:
+     *     <blockquote><pre>
+     *         &lt;<i>package</i>&gt;.&lt;<i>protocol</i>&gt;.Handler
+     *     </pre></blockquote>
+     *     where &lt;<i>package</i>&gt; is replaced by the name of the package
+     *     and &lt;<i>protocol</i>&gt; is replaced by the name of the protocol.
+     *     If this class does not exist, or if the class exists but it is not
+     *     a subclass of {@code URLStreamHandler}, then the next package
+     *     in the list is tried.
+     * <li>If the previous step fails to find a protocol handler, then the
+     *     constructor tries to load from a system default package.
+     *     <blockquote><pre>
+     *         &lt;<i>system default package</i>&gt;.&lt;<i>protocol</i>&gt;.Handler
+     *     </pre></blockquote>
+     *     If this class does not exist, or if the class exists but it is not a
+     *     subclass of {@code URLStreamHandler}, then a
+     *     {@code MalformedURLException} is thrown.
+     * </ol>
+     *
+     * <p>Protocol handlers for the following protocols are guaranteed
+     * to exist on the search path :-
+     * <blockquote><pre>
+     *     http, https, file, and jar
+     * </pre></blockquote>
+     * Protocol handlers for additional protocols may also be
+     * available.
+     *
+     * <p>No validation of the inputs is performed by this constructor.
+     *
+     * @param      protocol   the name of the protocol to use.
+     * @param      host       the name of the host.
+     * @param      port       the port number on the host.
+     * @param      file       the file on the host
+     * @exception  MalformedURLException  if an unknown protocol is specified.
+     * @see        java.lang.System#getProperty(java.lang.String)
+     * @see        java.net.URL#setURLStreamHandlerFactory(
+     *                  java.net.URLStreamHandlerFactory)
+     * @see        java.net.URLStreamHandler
+     * @see        java.net.URLStreamHandlerFactory#createURLStreamHandler(
+     *                  java.lang.String)
+     */
+    public URL(String protocol, String host, int port, String file)
+        throws MalformedURLException
+    {
+        this(protocol, host, port, file, null);
+    }
+
+    /**
+     * Creates a URL from the specified {@code protocol}
+     * name, {@code host} name, and {@code file} name. The
+     * default port for the specified protocol is used.
+     * <p>
+     * This method is equivalent to calling the four-argument
+     * constructor with the arguments being {@code protocol},
+     * {@code host}, {@code -1}, and {@code file}.
+     *
+     * No validation of the inputs is performed by this constructor.
+     *
+     * @param      protocol   the name of the protocol to use.
+     * @param      host       the name of the host.
+     * @param      file       the file on the host.
+     * @exception  MalformedURLException  if an unknown protocol is specified.
+     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
+     *                  int, java.lang.String)
+     */
+    public URL(String protocol, String host, String file)
+            throws MalformedURLException {
+        this(protocol, host, -1, file);
+    }
+
+    /**
+     * Creates a {@code URL} object from the specified
+     * {@code protocol}, {@code host}, {@code port}
+     * number, {@code file}, and {@code handler}. Specifying
+     * a {@code port} number of {@code -1} indicates that
+     * the URL should use the default port for the protocol. Specifying
+     * a {@code handler} of {@code null} indicates that the URL
+     * should use a default stream handler for the protocol, as outlined
+     * for:
+     *     java.net.URL#URL(java.lang.String, java.lang.String, int,
+     *                      java.lang.String)
+     *
+     * <p>If the handler is not null and there is a security manager,
+     * the security manager's {@code checkPermission}
+     * method is called with a
+     * {@code NetPermission("specifyStreamHandler")} permission.
+     * This may result in a SecurityException.
+     *
+     * No validation of the inputs is performed by this constructor.
+     *
+     * @param      protocol   the name of the protocol to use.
+     * @param      host       the name of the host.
+     * @param      port       the port number on the host.
+     * @param      file       the file on the host
+     * @param      handler    the stream handler for the URL.
+     * @exception  MalformedURLException  if an unknown protocol is specified.
+     * @exception  SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        specifying a stream handler explicitly.
+     * @see        java.lang.System#getProperty(java.lang.String)
+     * @see        java.net.URL#setURLStreamHandlerFactory(
+     *                  java.net.URLStreamHandlerFactory)
+     * @see        java.net.URLStreamHandler
+     * @see        java.net.URLStreamHandlerFactory#createURLStreamHandler(
+     *                  java.lang.String)
+     * @see        SecurityManager#checkPermission
+     * @see        java.net.NetPermission
+     */
+    public URL(String protocol, String host, int port, String file,
+               URLStreamHandler handler) throws MalformedURLException {
+        if (handler != null) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                // check for permission to specify a handler
+                checkSpecifyHandler(sm);
+            }
+        }
+
+        protocol = protocol.toLowerCase();
+        this.protocol = protocol;
+        if (host != null) {
+
+            /**
+             * if host is a literal IPv6 address,
+             * we will make it conform to RFC 2732
+             */
+            if (host.indexOf(':') >= 0 && !host.startsWith("[")) {
+                host = "["+host+"]";
+            }
+            this.host = host;
+
+            if (port < -1) {
+                throw new MalformedURLException("Invalid port number :" +
+                                                    port);
+            }
+            this.port = port;
+            authority = (port == -1) ? host : host + ":" + port;
+        }
+
+        // Android-changed: App compat. Prepend '/' if host is null / empty
+        // Parts parts = new Parts(file);
+        Parts parts = new Parts(file, host);
+        path = parts.getPath();
+        query = parts.getQuery();
+
+        if (query != null) {
+            this.file = path + "?" + query;
+        } else {
+            this.file = path;
+        }
+        ref = parts.getRef();
+
+        // Note: we don't do validation of the URL here. Too risky to change
+        // right now, but worth considering for future reference. -br
+        if (handler == null &&
+            (handler = getURLStreamHandler(protocol)) == null) {
+            throw new MalformedURLException("unknown protocol: " + protocol);
+        }
+        this.handler = handler;
+    }
+
+    /**
+     * Creates a {@code URL} object from the {@code String}
+     * representation.
+     * <p>
+     * This constructor is equivalent to a call to the two-argument
+     * constructor with a {@code null} first argument.
+     *
+     * @param      spec   the {@code String} to parse as a URL.
+     * @exception  MalformedURLException  if no protocol is specified, or an
+     *               unknown protocol is found, or {@code spec} is {@code null}.
+     * @see        java.net.URL#URL(java.net.URL, java.lang.String)
+     */
+    public URL(String spec) throws MalformedURLException {
+        this(null, spec);
+    }
+
+    /**
+     * Creates a URL by parsing the given spec within a specified context.
+     *
+     * The new URL is created from the given context URL and the spec
+     * argument as described in
+     * RFC2396 &quot;Uniform Resource Identifiers : Generic * Syntax&quot; :
+     * <blockquote><pre>
+     *          &lt;scheme&gt;://&lt;authority&gt;&lt;path&gt;?&lt;query&gt;#&lt;fragment&gt;
+     * </pre></blockquote>
+     * The reference is parsed into the scheme, authority, path, query and
+     * fragment parts. If the path component is empty and the scheme,
+     * authority, and query components are undefined, then the new URL is a
+     * reference to the current document. Otherwise, the fragment and query
+     * parts present in the spec are used in the new URL.
+     * <p>
+     * If the scheme component is defined in the given spec and does not match
+     * the scheme of the context, then the new URL is created as an absolute
+     * URL based on the spec alone. Otherwise the scheme component is inherited
+     * from the context URL.
+     * <p>
+     * If the authority component is present in the spec then the spec is
+     * treated as absolute and the spec authority and path will replace the
+     * context authority and path. If the authority component is absent in the
+     * spec then the authority of the new URL will be inherited from the
+     * context.
+     * <p>
+     * If the spec's path component begins with a slash character
+     * &quot;/&quot; then the
+     * path is treated as absolute and the spec path replaces the context path.
+     * <p>
+     * Otherwise, the path is treated as a relative path and is appended to the
+     * context path, as described in RFC2396. Also, in this case,
+     * the path is canonicalized through the removal of directory
+     * changes made by occurrences of &quot;..&quot; and &quot;.&quot;.
+     * <p>
+     * For a more detailed description of URL parsing, refer to RFC2396.
+     *
+     * @param      context   the context in which to parse the specification.
+     * @param      spec      the {@code String} to parse as a URL.
+     * @exception  MalformedURLException  if no protocol is specified, or an
+     *               unknown protocol is found, or {@code spec} is {@code null}.
+     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
+     *                  int, java.lang.String)
+     * @see        java.net.URLStreamHandler
+     * @see        java.net.URLStreamHandler#parseURL(java.net.URL,
+     *                  java.lang.String, int, int)
+     */
+    public URL(URL context, String spec) throws MalformedURLException {
+        this(context, spec, null);
+    }
+
+    /**
+     * Creates a URL by parsing the given spec with the specified handler
+     * within a specified context. If the handler is null, the parsing
+     * occurs as with the two argument constructor.
+     *
+     * @param      context   the context in which to parse the specification.
+     * @param      spec      the {@code String} to parse as a URL.
+     * @param      handler   the stream handler for the URL.
+     * @exception  MalformedURLException  if no protocol is specified, or an
+     *               unknown protocol is found, or {@code spec} is {@code null}.
+     * @exception  SecurityException
+     *        if a security manager exists and its
+     *        {@code checkPermission} method doesn't allow
+     *        specifying a stream handler.
+     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
+     *                  int, java.lang.String)
+     * @see        java.net.URLStreamHandler
+     * @see        java.net.URLStreamHandler#parseURL(java.net.URL,
+     *                  java.lang.String, int, int)
+     */
+    public URL(URL context, String spec, URLStreamHandler handler)
+        throws MalformedURLException
+    {
+        String original = spec;
+        int i, limit, c;
+        int start = 0;
+        String newProtocol = null;
+        boolean aRef=false;
+        boolean isRelative = false;
+
+        // Check for permission to specify a handler
+        if (handler != null) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                checkSpecifyHandler(sm);
+            }
+        }
+
+        try {
+            limit = spec.length();
+            while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) {
+                limit--;        //eliminate trailing whitespace
+            }
+            while ((start < limit) && (spec.charAt(start) <= ' ')) {
+                start++;        // eliminate leading whitespace
+            }
+
+            if (spec.regionMatches(true, start, "url:", 0, 4)) {
+                start += 4;
+            }
+            if (start < spec.length() && spec.charAt(start) == '#') {
+                /* we're assuming this is a ref relative to the context URL.
+                 * This means protocols cannot start w/ '#', but we must parse
+                 * ref URL's like: "hello:there" w/ a ':' in them.
+                 */
+                aRef=true;
+            }
+            for (i = start ; !aRef && (i < limit) &&
+                     ((c = spec.charAt(i)) != '/') ; i++) {
+                if (c == ':') {
+
+                    String s = spec.substring(start, i).toLowerCase();
+                    if (isValidProtocol(s)) {
+                        newProtocol = s;
+                        start = i + 1;
+                    }
+                    break;
+                }
+            }
+
+            // Only use our context if the protocols match.
+            protocol = newProtocol;
+            if ((context != null) && ((newProtocol == null) ||
+                            newProtocol.equalsIgnoreCase(context.protocol))) {
+                // inherit the protocol handler from the context
+                // if not specified to the constructor
+                if (handler == null) {
+                    handler = context.handler;
+                }
+
+                // If the context is a hierarchical URL scheme and the spec
+                // contains a matching scheme then maintain backwards
+                // compatibility and treat it as if the spec didn't contain
+                // the scheme; see 5.2.3 of RFC2396
+                if (context.path != null && context.path.startsWith("/"))
+                    newProtocol = null;
+
+                if (newProtocol == null) {
+                    protocol = context.protocol;
+                    authority = context.authority;
+                    userInfo = context.userInfo;
+                    host = context.host;
+                    port = context.port;
+                    file = context.file;
+                    path = context.path;
+                    isRelative = true;
+                }
+            }
+
+            if (protocol == null) {
+                throw new MalformedURLException("no protocol: "+original);
+            }
+
+            // Get the protocol handler if not specified or the protocol
+            // of the context could not be used
+            if (handler == null &&
+                (handler = getURLStreamHandler(protocol)) == null) {
+                throw new MalformedURLException("unknown protocol: "+protocol);
+            }
+
+            this.handler = handler;
+
+            i = spec.indexOf('#', start);
+            if (i >= 0) {
+                ref = spec.substring(i + 1, limit);
+                limit = i;
+            }
+
+            /*
+             * Handle special case inheritance of query and fragment
+             * implied by RFC2396 section 5.2.2.
+             */
+            if (isRelative && start == limit) {
+                query = context.query;
+                if (ref == null) {
+                    ref = context.ref;
+                }
+            }
+
+            handler.parseURL(this, spec, start, limit);
+
+        } catch(MalformedURLException e) {
+            throw e;
+        } catch(Exception e) {
+            MalformedURLException exception = new MalformedURLException(e.getMessage());
+            exception.initCause(e);
+            throw exception;
+        }
+    }
+
+    /*
+     * Returns true if specified string is a valid protocol name.
+     */
+    private boolean isValidProtocol(String protocol) {
+        int len = protocol.length();
+        if (len < 1)
+            return false;
+        char c = protocol.charAt(0);
+        if (!Character.isLetter(c))
+            return false;
+        for (int i = 1; i < len; i++) {
+            c = protocol.charAt(i);
+            if (!Character.isLetterOrDigit(c) && c != '.' && c != '+' &&
+                c != '-') {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /*
+     * Checks for permission to specify a stream handler.
+     */
+    private void checkSpecifyHandler(SecurityManager sm) {
+        sm.checkPermission(SecurityConstants.SPECIFY_HANDLER_PERMISSION);
+    }
+
+    /**
+     * Sets the fields of the URL. This is not a public method so that
+     * only URLStreamHandlers can modify URL fields. URLs are
+     * otherwise constant.
+     *
+     * @param protocol the name of the protocol to use
+     * @param host the name of the host
+       @param port the port number on the host
+     * @param file the file on the host
+     * @param ref the internal reference in the URL
+     */
+    void set(String protocol, String host, int port,
+             String file, String ref) {
+        synchronized (this) {
+            this.protocol = protocol;
+            this.host = host;
+            authority = port == -1 ? host : host + ":" + port;
+            this.port = port;
+            this.file = file;
+            this.ref = ref;
+            /* This is very important. We must recompute this after the
+             * URL has been changed. */
+            hashCode = -1;
+            hostAddress = null;
+            int q = file.lastIndexOf('?');
+            if (q != -1) {
+                query = file.substring(q+1);
+                path = file.substring(0, q);
+            } else
+                path = file;
+        }
+    }
+
+    /**
+     * Sets the specified 8 fields of the URL. This is not a public method so
+     * that only URLStreamHandlers can modify URL fields. URLs are otherwise
+     * constant.
+     *
+     * @param protocol the name of the protocol to use
+     * @param host the name of the host
+     * @param port the port number on the host
+     * @param authority the authority part for the url
+     * @param userInfo the username and password
+     * @param path the file on the host
+     * @param ref the internal reference in the URL
+     * @param query the query part of this URL
+     * @since 1.3
+     */
+    void set(String protocol, String host, int port,
+             String authority, String userInfo, String path,
+             String query, String ref) {
+        synchronized (this) {
+            this.protocol = protocol;
+            this.host = host;
+            this.port = port;
+            // Android-changed: App compat. Only include query part if it's nonempty.
+            // this.file = query == null ? path : path + "?" + query;
+            this.file = (query == null || query.isEmpty()) ? path : path + "?" + query;
+            this.userInfo = userInfo;
+            this.path = path;
+            this.ref = ref;
+            /* This is very important. We must recompute this after the
+             * URL has been changed. */
+            hashCode = -1;
+            hostAddress = null;
+            this.query = query;
+            this.authority = authority;
+        }
+    }
+
+    /**
+     * Gets the query part of this {@code URL}.
+     *
+     * @return  the query part of this {@code URL},
+     * or <CODE>null</CODE> if one does not exist
+     * @since 1.3
+     */
+    public String getQuery() {
+        return query;
+    }
+
+    /**
+     * Gets the path part of this {@code URL}.
+     *
+     * @return  the path part of this {@code URL}, or an
+     * empty string if one does not exist
+     * @since 1.3
+     */
+    public String getPath() {
+        return path;
+    }
+
+    /**
+     * Gets the userInfo part of this {@code URL}.
+     *
+     * @return  the userInfo part of this {@code URL}, or
+     * <CODE>null</CODE> if one does not exist
+     * @since 1.3
+     */
+    public String getUserInfo() {
+        return userInfo;
+    }
+
+    /**
+     * Gets the authority part of this {@code URL}.
+     *
+     * @return  the authority part of this {@code URL}
+     * @since 1.3
+     */
+    public String getAuthority() {
+        return authority;
+    }
+
+    /**
+     * Gets the port number of this {@code URL}.
+     *
+     * @return  the port number, or -1 if the port is not set
+     */
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Gets the default port number of the protocol associated
+     * with this {@code URL}. If the URL scheme or the URLStreamHandler
+     * for the URL do not define a default port number,
+     * then -1 is returned.
+     *
+     * @return  the port number
+     * @since 1.4
+     */
+    public int getDefaultPort() {
+        return handler.getDefaultPort();
+    }
+
+    /**
+     * Gets the protocol name of this {@code URL}.
+     *
+     * @return  the protocol of this {@code URL}.
+     */
+    public String getProtocol() {
+        return protocol;
+    }
+
+    /**
+     * Gets the host name of this {@code URL}, if applicable.
+     * The format of the host conforms to RFC 2732, i.e. for a
+     * literal IPv6 address, this method will return the IPv6 address
+     * enclosed in square brackets ({@code '['} and {@code ']'}).
+     *
+     * @return  the host name of this {@code URL}.
+     */
+    public String getHost() {
+        return host;
+    }
+
+    /**
+     * Gets the file name of this {@code URL}.
+     * The returned file portion will be
+     * the same as <CODE>getPath()</CODE>, plus the concatenation of
+     * the value of <CODE>getQuery()</CODE>, if any. If there is
+     * no query portion, this method and <CODE>getPath()</CODE> will
+     * return identical results.
+     *
+     * @return  the file name of this {@code URL},
+     * or an empty string if one does not exist
+     */
+    public String getFile() {
+        return file;
+    }
+
+    /**
+     * Gets the anchor (also known as the "reference") of this
+     * {@code URL}.
+     *
+     * @return  the anchor (also known as the "reference") of this
+     *          {@code URL}, or <CODE>null</CODE> if one does not exist
+     */
+    public String getRef() {
+        return ref;
+    }
+
+    // Android-changed: Don't let URL.equals() attempt to resolve host names.
+    /**
+     * Compares this URL for equality with another object.<p>
+     *
+     * If the given object is not a URL then this method immediately returns
+     * {@code false}.<p>
+     *
+     * Two URL objects are equal if they have the same protocol, reference
+     * equivalent hosts, have the same port number on the host, and the same
+     * file and fragment of the file.<p>
+     *
+     * Returns true if this URL equals {@code o}. URLs are equal if they have
+     * the same protocol, host, port, file, and reference.
+     *
+     * <h3>Network I/O Warning</h3>
+     * <p>Some implementations of URL.equals() resolve host names over the
+     * network. This is problematic:
+     * <ul>
+     * <li><strong>The network may be slow.</strong> Many classes, including
+     * core collections like {@link java.util.Map Map} and {@link java.util.Set
+     * Set} expect that {@code equals} and {@code hashCode} will return quickly.
+     * By violating this assumption, this method posed potential performance
+     * problems.
+     * <li><strong>Equal IP addresses do not imply equal content.</strong>
+     * Virtual hosting permits unrelated sites to share an IP address. This
+     * method could report two otherwise unrelated URLs to be equal because
+     * they're hosted on the same server.</li>
+     * <li><strong>The network may not be available.</strong> Two URLs could be
+     * equal when a network is available and unequal otherwise.</li>
+     * <li><strong>The network may change.</strong> The IP address for a given
+     * host name varies by network and over time. This is problematic for mobile
+     * devices. Two URLs could be equal on some networks and unequal on
+     * others.</li>
+     * </ul>
+     * <p>This problem is fixed in Android 4.0 (Ice Cream Sandwich). In that
+     * release, URLs are only equal if their host names are equal (ignoring
+     * case).
+     *
+     * @param   obj   the URL to compare against.
+     * @return  {@code true} if the objects are the same;
+     *          {@code false} otherwise.
+     */
+    public boolean equals(Object obj) {
+        if (!(obj instanceof URL))
+            return false;
+        URL u2 = (URL)obj;
+
+        return handler.equals(this, u2);
+    }
+
+    /**
+     * Creates an integer suitable for hash table indexing.<p>
+     *
+     * The hash code is based upon all the URL components relevant for URL
+     * comparison. As such, this operation is a blocking operation.<p>
+     *
+     * @return  a hash code for this {@code URL}.
+     */
+    public synchronized int hashCode() {
+        if (hashCode != -1)
+            return hashCode;
+
+        hashCode = handler.hashCode(this);
+        return hashCode;
+    }
+
+    /**
+     * Compares two URLs, excluding the fragment component.<p>
+     *
+     * Returns {@code true} if this {@code URL} and the
+     * {@code other} argument are equal without taking the
+     * fragment component into consideration.
+     *
+     * @param   other   the {@code URL} to compare against.
+     * @return  {@code true} if they reference the same remote object;
+     *          {@code false} otherwise.
+     */
+    public boolean sameFile(URL other) {
+        return handler.sameFile(this, other);
+    }
+
+    /**
+     * Constructs a string representation of this {@code URL}. The
+     * string is created by calling the {@code toExternalForm}
+     * method of the stream protocol handler for this object.
+     *
+     * @return  a string representation of this object.
+     * @see     java.net.URL#URL(java.lang.String, java.lang.String, int,
+     *                  java.lang.String)
+     * @see     java.net.URLStreamHandler#toExternalForm(java.net.URL)
+     */
+    public String toString() {
+        return toExternalForm();
+    }
+
+    /**
+     * Constructs a string representation of this {@code URL}. The
+     * string is created by calling the {@code toExternalForm}
+     * method of the stream protocol handler for this object.
+     *
+     * @return  a string representation of this object.
+     * @see     java.net.URL#URL(java.lang.String, java.lang.String,
+     *                  int, java.lang.String)
+     * @see     java.net.URLStreamHandler#toExternalForm(java.net.URL)
+     */
+    public String toExternalForm() {
+        return handler.toExternalForm(this);
+    }
+
+    /**
+     * Returns a {@link java.net.URI} equivalent to this URL.
+     * This method functions in the same way as {@code new URI (this.toString())}.
+     * <p>Note, any URL instance that complies with RFC 2396 can be converted
+     * to a URI. However, some URLs that are not strictly in compliance
+     * can not be converted to a URI.
+     *
+     * @exception URISyntaxException if this URL is not formatted strictly according to
+     *            to RFC2396 and cannot be converted to a URI.
+     *
+     * @return    a URI instance equivalent to this URL.
+     * @since 1.5
+     */
+    public URI toURI() throws URISyntaxException {
+        return new URI (toString());
+    }
+
+    /**
+     * Returns a {@link java.net.URLConnection URLConnection} instance that
+     * represents a connection to the remote object referred to by the
+     * {@code URL}.
+     *
+     * <P>A new instance of {@linkplain java.net.URLConnection URLConnection} is
+     * created every time when invoking the
+     * {@linkplain java.net.URLStreamHandler#openConnection(URL)
+     * URLStreamHandler.openConnection(URL)} method of the protocol handler for
+     * this URL.</P>
+     *
+     * <P>It should be noted that a URLConnection instance does not establish
+     * the actual network connection on creation. This will happen only when
+     * calling {@linkplain java.net.URLConnection#connect() URLConnection.connect()}.</P>
+     *
+     * <P>If for the URL's protocol (such as HTTP or JAR), there
+     * exists a public, specialized URLConnection subclass belonging
+     * to one of the following packages or one of their subpackages:
+     * java.lang, java.io, java.util, java.net, the connection
+     * returned will be of that subclass. For example, for HTTP an
+     * HttpURLConnection will be returned, and for JAR a
+     * JarURLConnection will be returned.</P>
+     *
+     * @return     a {@link java.net.URLConnection URLConnection} linking
+     *             to the URL.
+     * @exception  IOException  if an I/O exception occurs.
+     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
+     *             int, java.lang.String)
+     */
+    public URLConnection openConnection() throws java.io.IOException {
+        return handler.openConnection(this);
+    }
+
+    /**
+     * Same as {@link #openConnection()}, except that the connection will be
+     * made through the specified proxy; Protocol handlers that do not
+     * support proxing will ignore the proxy parameter and make a
+     * normal connection.
+     *
+     * Invoking this method preempts the system's default ProxySelector
+     * settings.
+     *
+     * @param      proxy the Proxy through which this connection
+     *             will be made. If direct connection is desired,
+     *             Proxy.NO_PROXY should be specified.
+     * @return     a {@code URLConnection} to the URL.
+     * @exception  IOException  if an I/O exception occurs.
+     * @exception  SecurityException if a security manager is present
+     *             and the caller doesn't have permission to connect
+     *             to the proxy.
+     * @exception  IllegalArgumentException will be thrown if proxy is null,
+     *             or proxy has the wrong type
+     * @exception  UnsupportedOperationException if the subclass that
+     *             implements the protocol handler doesn't support
+     *             this method.
+     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
+     *             int, java.lang.String)
+     * @see        java.net.URLConnection
+     * @see        java.net.URLStreamHandler#openConnection(java.net.URL,
+     *             java.net.Proxy)
+     * @since      1.5
+     */
+    public URLConnection openConnection(Proxy proxy)
+        throws java.io.IOException {
+        if (proxy == null) {
+            throw new IllegalArgumentException("proxy can not be null");
+        }
+
+        // Create a copy of Proxy as a security measure
+        Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy);
+        SecurityManager sm = System.getSecurityManager();
+        if (p.type() != Proxy.Type.DIRECT && sm != null) {
+            InetSocketAddress epoint = (InetSocketAddress) p.address();
+            if (epoint.isUnresolved())
+                sm.checkConnect(epoint.getHostName(), epoint.getPort());
+            else
+                sm.checkConnect(epoint.getAddress().getHostAddress(),
+                                epoint.getPort());
+        }
+        return handler.openConnection(this, p);
+    }
+
+    /**
+     * Opens a connection to this {@code URL} and returns an
+     * {@code InputStream} for reading from that connection. This
+     * method is a shorthand for:
+     * <blockquote><pre>
+     *     openConnection().getInputStream()
+     * </pre></blockquote>
+     *
+     * @return     an input stream for reading from the URL connection.
+     * @exception  IOException  if an I/O exception occurs.
+     * @see        java.net.URL#openConnection()
+     * @see        java.net.URLConnection#getInputStream()
+     */
+    public final InputStream openStream() throws java.io.IOException {
+        return openConnection().getInputStream();
+    }
+
+    /**
+     * Gets the contents of this URL. This method is a shorthand for:
+     * <blockquote><pre>
+     *     openConnection().getContent()
+     * </pre></blockquote>
+     *
+     * @return     the contents of this URL.
+     * @exception  IOException  if an I/O exception occurs.
+     * @see        java.net.URLConnection#getContent()
+     */
+    public final Object getContent() throws java.io.IOException {
+        return openConnection().getContent();
+    }
+
+    /**
+     * Gets the contents of this URL. This method is a shorthand for:
+     * <blockquote><pre>
+     *     openConnection().getContent(Class[])
+     * </pre></blockquote>
+     *
+     * @param classes an array of Java types
+     * @return     the content object of this URL that is the first match of
+     *               the types specified in the classes array.
+     *               null if none of the requested types are supported.
+     * @exception  IOException  if an I/O exception occurs.
+     * @see        java.net.URLConnection#getContent(Class[])
+     * @since 1.3
+     */
+    public final Object getContent(Class[] classes)
+    throws java.io.IOException {
+        return openConnection().getContent(classes);
+    }
+
+    /**
+     * The URLStreamHandler factory.
+     */
+    static URLStreamHandlerFactory factory;
+
+    /**
+     * Sets an application's {@code URLStreamHandlerFactory}.
+     * This method can be called at most once in a given Java Virtual
+     * Machine.
+     *
+     *<p> The {@code URLStreamHandlerFactory} instance is used to
+     *construct a stream protocol handler from a protocol name.
+     *
+     * <p> If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param      fac   the desired factory.
+     * @exception  Error  if the application has already set a factory.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't allow
+     *             the operation.
+     * @see        java.net.URL#URL(java.lang.String, java.lang.String,
+     *             int, java.lang.String)
+     * @see        java.net.URLStreamHandlerFactory
+     * @see        SecurityManager#checkSetFactory
+     */
+    public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) {
+        synchronized (streamHandlerLock) {
+            if (factory != null) {
+                throw new Error("factory already defined");
+            }
+            SecurityManager security = System.getSecurityManager();
+            if (security != null) {
+                security.checkSetFactory();
+            }
+            handlers.clear();
+            factory = fac;
+        }
+    }
+
+    /**
+     * A table of protocol handlers.
+     */
+    static Hashtable<String,URLStreamHandler> handlers = new Hashtable<>();
+    private static Object streamHandlerLock = new Object();
+
+    /**
+     * Returns the Stream Handler.
+     * @param protocol the protocol to use
+     */
+    static URLStreamHandler getURLStreamHandler(String protocol) {
+
+        URLStreamHandler handler = handlers.get(protocol);
+        if (handler == null) {
+
+            boolean checkedWithFactory = false;
+
+            // Use the factory (if any)
+            if (factory != null) {
+                handler = factory.createURLStreamHandler(protocol);
+                checkedWithFactory = true;
+            }
+
+            // Try java protocol handler
+            if (handler == null) {
+                // Android-changed: Android doesn't need AccessController.
+                // Remove unnecessary use of reflection for sun classes
+                /*
+                packagePrefixList
+                    = java.security.AccessController.doPrivileged(
+                    new sun.security.action.GetPropertyAction(
+                        protocolPathProp,""));
+                if (packagePrefixList != "") {
+                    packagePrefixList += "|";
+                }
+
+                // REMIND: decide whether to allow the "null" class prefix
+                // or not.
+                packagePrefixList += "sun.net.www.protocol";
+                 */
+                final String packagePrefixList = System.getProperty(protocolPathProp,"");
+
+                StringTokenizer packagePrefixIter =
+                    new StringTokenizer(packagePrefixList, "|");
+
+                while (handler == null &&
+                       packagePrefixIter.hasMoreTokens()) {
+
+                    String packagePrefix =
+                      packagePrefixIter.nextToken().trim();
+                    try {
+                        String clsName = packagePrefix + "." + protocol +
+                          ".Handler";
+                        Class<?> cls = null;
+                        try {
+                            ClassLoader cl = ClassLoader.getSystemClassLoader();
+                            // BEGIN Android-changed: Fall back to thread's contextClassLoader.
+                            // http://b/25897689
+                            cls = Class.forName(clsName, true, cl);
+                        } catch (ClassNotFoundException e) {
+                            ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
+                            if (contextLoader != null) {
+                                cls = Class.forName(clsName, true, contextLoader);
+                            }
+                            // END Android-changed: Fall back to thread's contextClassLoader.
+                        }
+                        if (cls != null) {
+                            handler  =
+                              (URLStreamHandler)cls.newInstance();
+                        }
+                    } catch (ReflectiveOperationException ignored) {
+                    }
+                }
+            }
+
+            // BEGIN Android-added: Custom built-in URLStreamHandlers for http, https.
+            // Fallback to built-in stream handler.
+            if (handler == null) {
+                try {
+                    handler = createBuiltinHandler(protocol);
+                } catch (Exception e) {
+                    throw new AssertionError(e);
+                }
+            }
+            // END Android-added: Custom built-in URLStreamHandlers for http, https.
+
+            synchronized (streamHandlerLock) {
+
+                URLStreamHandler handler2 = null;
+
+                // Check again with hashtable just in case another
+                // thread created a handler since we last checked
+                handler2 = handlers.get(protocol);
+
+                if (handler2 != null) {
+                    return handler2;
+                }
+
+                // Check with factory if another thread set a
+                // factory since our last check
+                if (!checkedWithFactory && factory != null) {
+                    handler2 = factory.createURLStreamHandler(protocol);
+                }
+
+                if (handler2 != null) {
+                    // The handler from the factory must be given more
+                    // importance. Discard the default handler that
+                    // this thread created.
+                    handler = handler2;
+                }
+
+                // Insert this handler into the hashtable
+                if (handler != null) {
+                    handlers.put(protocol, handler);
+                }
+
+            }
+        }
+
+        return handler;
+
+    }
+
+    // BEGIN Android-added: Custom built-in URLStreamHandlers for http, https.
+    /**
+     * Returns an instance of the built-in handler for the given protocol, or null if none exists.
+     */
+    private static URLStreamHandler createBuiltinHandler(String protocol)
+            throws ClassNotFoundException, InstantiationException, IllegalAccessException {
+        URLStreamHandler handler = null;
+        if (protocol.equals("file")) {
+            handler = new sun.net.www.protocol.file.Handler();
+        } else if (protocol.equals("ftp")) {
+            handler = new sun.net.www.protocol.ftp.Handler();
+        } else if (protocol.equals("jar")) {
+            handler = new sun.net.www.protocol.jar.Handler();
+        } else if (protocol.equals("http")) {
+            handler = (URLStreamHandler)Class.
+                    forName("com.android.okhttp.HttpHandler").newInstance();
+        } else if (protocol.equals("https")) {
+            handler = (URLStreamHandler)Class.
+                    forName("com.android.okhttp.HttpsHandler").newInstance();
+        }
+        return handler;
+    }
+
+    /** Names of implementation classes returned by {@link #createBuiltinHandler(String)}. */
+    private static Set<String> createBuiltinHandlerClassNames() {
+        Set<String> result = new HashSet<>();
+        // Refer to class names rather than classes to avoid needlessly triggering <clinit>.
+        result.add("sun.net.www.protocol.file.Handler");
+        result.add("sun.net.www.protocol.ftp.Handler");
+        result.add("sun.net.www.protocol.jar.Handler");
+        result.add("com.android.okhttp.HttpHandler");
+        result.add("com.android.okhttp.HttpsHandler");
+        return Collections.unmodifiableSet(result);
+    }
+    // END Android-added: Custom built-in URLStreamHandlers for http, https.
+
+    /**
+     * @serialField    protocol String
+     *
+     * @serialField    host String
+     *
+     * @serialField    port int
+     *
+     * @serialField    authority String
+     *
+     * @serialField    file String
+     *
+     * @serialField    ref String
+     *
+     * @serialField    hashCode int
+     *
+     */
+    private static final ObjectStreamField[] serialPersistentFields = {
+        new ObjectStreamField("protocol", String.class),
+        new ObjectStreamField("host", String.class),
+        new ObjectStreamField("port", int.class),
+        new ObjectStreamField("authority", String.class),
+        new ObjectStreamField("file", String.class),
+        new ObjectStreamField("ref", String.class),
+    // Android-changed: App compat: hashCode should not be serialized.
+    //    new ObjectStreamField("hashCode", int.class), };
+    };
+
+    /**
+     * WriteObject is called to save the state of the URL to an
+     * ObjectOutputStream. The handler is not saved since it is
+     * specific to this system.
+     *
+     * @serialData the default write object value. When read back in,
+     * the reader must ensure that calling getURLStreamHandler with
+     * the protocol variable returns a valid URLStreamHandler and
+     * throw an IOException if it does not.
+     */
+    private synchronized void writeObject(java.io.ObjectOutputStream s)
+        throws IOException
+    {
+        s.defaultWriteObject(); // write the fields
+    }
+
+    /**
+     * readObject is called to restore the state of the URL from the
+     * stream.  It reads the components of the URL and finds the local
+     * stream handler.
+     */
+    private synchronized void readObject(java.io.ObjectInputStream s)
+            throws IOException, ClassNotFoundException {
+        GetField gf = s.readFields();
+        String protocol = (String)gf.get("protocol", null);
+        if (getURLStreamHandler(protocol) == null) {
+            throw new IOException("unknown protocol: " + protocol);
+        }
+        String host = (String)gf.get("host", null);
+        int port = gf.get("port", -1);
+        String authority = (String)gf.get("authority", null);
+        String file = (String)gf.get("file", null);
+        String ref = (String)gf.get("ref", null);
+        // Android-changed: App compat: hashCode should not be serialized.
+        // int hashCode = gf.get("hashCode", -1);
+        final int hashCode = -1;
+        if (authority == null
+                && ((host != null && host.length() > 0) || port != -1)) {
+            if (host == null)
+                host = "";
+            authority = (port == -1) ? host : host + ":" + port;
+        }
+        tempState = new UrlDeserializedState(protocol, host, port, authority,
+               file, ref, hashCode);
+    }
+
+    /**
+     * Replaces the de-serialized object with an URL object.
+     *
+     * @return a newly created object from the deserialzed state.
+     *
+     * @throws ObjectStreamException if a new object replacing this
+     * object could not be created
+     */
+
+   private Object readResolve() throws ObjectStreamException {
+
+        URLStreamHandler handler = null;
+        // already been checked in readObject
+        handler = getURLStreamHandler(tempState.getProtocol());
+
+        URL replacementURL = null;
+        if (isBuiltinStreamHandler(handler.getClass().getName())) {
+            replacementURL = fabricateNewURL();
+        } else {
+            replacementURL = setDeserializedFields(handler);
+        }
+        return replacementURL;
+    }
+
+    private URL setDeserializedFields(URLStreamHandler handler) {
+        URL replacementURL;
+        String userInfo = null;
+        String protocol = tempState.getProtocol();
+        String host = tempState.getHost();
+        int port = tempState.getPort();
+        String authority = tempState.getAuthority();
+        String file = tempState.getFile();
+        String ref = tempState.getRef();
+        int hashCode = tempState.getHashCode();
+
+
+        // Construct authority part
+        if (authority == null
+            && ((host != null && host.length() > 0) || port != -1)) {
+            if (host == null)
+                host = "";
+            authority = (port == -1) ? host : host + ":" + port;
+
+            // Handle hosts with userInfo in them
+            int at = host.lastIndexOf('@');
+            if (at != -1) {
+                userInfo = host.substring(0, at);
+                host = host.substring(at+1);
+            }
+        } else if (authority != null) {
+            // Construct user info part
+            int ind = authority.indexOf('@');
+            if (ind != -1)
+                userInfo = authority.substring(0, ind);
+        }
+
+        // Construct path and query part
+        String path = null;
+        String query = null;
+        if (file != null) {
+            // Fix: only do this if hierarchical?
+            int q = file.lastIndexOf('?');
+            if (q != -1) {
+                query = file.substring(q+1);
+                path = file.substring(0, q);
+            } else
+                path = file;
+        }
+
+        // Set the object fields.
+        this.protocol = protocol;
+        this.host = host;
+        this.port = port;
+        this.file = file;
+        this.authority = authority;
+        this.ref = ref;
+        this.hashCode = hashCode;
+        this.handler = handler;
+        this.query = query;
+        this.path = path;
+        this.userInfo = userInfo;
+        replacementURL = this;
+        return replacementURL;
+    }
+
+    private URL fabricateNewURL()
+                throws InvalidObjectException {
+        // create URL string from deserialized object
+        URL replacementURL = null;
+        String urlString = tempState.reconstituteUrlString();
+
+        try {
+            replacementURL = new URL(urlString);
+        } catch (MalformedURLException mEx) {
+            resetState();
+            InvalidObjectException invoEx = new InvalidObjectException(
+                    "Malformed URL: " + urlString);
+            invoEx.initCause(mEx);
+            throw invoEx;
+        }
+        replacementURL.setSerializedHashCode(tempState.getHashCode());
+        resetState();
+        return replacementURL;
+    }
+
+    private boolean isBuiltinStreamHandler(String handlerClassName) {
+        // Android-changed: Some built-in handlers (eg. HttpHandler) are not in sun.net.www.protocol.
+        // return (handlerClassName.startsWith(BUILTIN_HANDLERS_PREFIX));
+        return BUILTIN_HANDLER_CLASS_NAMES.contains(handlerClassName);
+    }
+
+    private void resetState() {
+        this.protocol = null;
+        this.host = null;
+        this.port = -1;
+        this.file = null;
+        this.authority = null;
+        this.ref = null;
+        this.hashCode = -1;
+        this.handler = null;
+        this.query = null;
+        this.path = null;
+        this.userInfo = null;
+        this.tempState = null;
+    }
+
+    private void setSerializedHashCode(int hc) {
+        this.hashCode = hc;
+    }
+}
+
+class Parts {
+    String path, query, ref;
+
+    // Android-changed: App compat. Prepend '/' if host is null / empty.
+    // Parts(String file)
+    Parts(String file, String host) {
+        int ind = file.indexOf('#');
+        ref = ind < 0 ? null: file.substring(ind + 1);
+        file = ind < 0 ? file: file.substring(0, ind);
+        int q = file.lastIndexOf('?');
+        if (q != -1) {
+            query = file.substring(q+1);
+            path = file.substring(0, q);
+        } else {
+            path = file;
+        }
+        // BEGIN Android-changed: App compat. Prepend '/' if host is null / empty.
+        if (path != null && path.length() > 0 && path.charAt(0) != '/' &&
+            host != null && !host.isEmpty()) {
+            path = '/' + path;
+        }
+        // END Android-changed: App compat. Prepend '/' if host is null / empty.
+    }
+
+    String getPath() {
+        return path;
+    }
+
+    String getQuery() {
+        return query;
+    }
+
+    String getRef() {
+        return ref;
+    }
+}
+
+final class UrlDeserializedState {
+    private final String protocol;
+    private final String host;
+    private final int port;
+    private final String authority;
+    private final String file;
+    private final String ref;
+    private final int hashCode;
+
+    public UrlDeserializedState(String protocol,
+                                String host, int port,
+                                String authority, String file,
+                                String ref, int hashCode) {
+        this.protocol = protocol;
+        this.host = host;
+        this.port = port;
+        this.authority = authority;
+        this.file = file;
+        this.ref = ref;
+        this.hashCode = hashCode;
+    }
+
+    String getProtocol() {
+        return protocol;
+    }
+
+    String getHost() {
+        return host;
+    }
+
+    String getAuthority () {
+        return authority;
+    }
+
+    int getPort() {
+        return port;
+    }
+
+    String getFile () {
+        return file;
+    }
+
+    String getRef () {
+        return ref;
+    }
+
+    int getHashCode () {
+        return hashCode;
+    }
+
+    String reconstituteUrlString() {
+
+        // pre-compute length of StringBuilder
+        int len = protocol.length() + 1;
+        if (authority != null && authority.length() > 0)
+            len += 2 + authority.length();
+        if (file != null) {
+            len += file.length();
+        }
+        if (ref != null)
+            len += 1 + ref.length();
+        StringBuilder result = new StringBuilder(len);
+        result.append(protocol);
+        result.append(":");
+        if (authority != null && authority.length() > 0) {
+            result.append("//");
+            result.append(authority);
+        }
+        if (file != null) {
+            result.append(file);
+        }
+        if (ref != null) {
+            result.append("#");
+            result.append(ref);
+        }
+        return result.toString();
+    }
+}
diff --git a/java/net/URLClassLoader.java b/java/net/URLClassLoader.java
new file mode 100644
index 0000000..6e8acb1
--- /dev/null
+++ b/java/net/URLClassLoader.java
@@ -0,0 +1,819 @@
+/*
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.CodeSigner;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.jar.Attributes;
+import java.util.jar.Attributes.Name;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import sun.misc.Resource;
+import sun.misc.URLClassPath;
+import sun.net.www.ParseUtil;
+import sun.security.util.SecurityConstants;
+
+/**
+ * This class loader is used to load classes and resources from a search
+ * path of URLs referring to both JAR files and directories. Any URL that
+ * ends with a '/' is assumed to refer to a directory. Otherwise, the URL
+ * is assumed to refer to a JAR file which will be opened as needed.
+ * <p>
+ * The AccessControlContext of the thread that created the instance of
+ * URLClassLoader will be used when subsequently loading classes and
+ * resources.
+ * <p>
+ * The classes that are loaded are by default granted permission only to
+ * access the URLs specified when the URLClassLoader was created.
+ *
+ * @author  David Connelly
+ * @since   1.2
+ */
+public class URLClassLoader extends SecureClassLoader implements Closeable {
+    /* The search path for classes and resources */
+    private final URLClassPath ucp;
+
+    /* The context to be used when loading classes and resources */
+    private final AccessControlContext acc;
+
+    /**
+     * Constructs a new URLClassLoader for the given URLs. The URLs will be
+     * searched in the order specified for classes and resources after first
+     * searching in the specified parent class loader. Any URL that ends with
+     * a '/' is assumed to refer to a directory. Otherwise, the URL is assumed
+     * to refer to a JAR file which will be downloaded and opened as needed.
+     *
+     * <p>If there is a security manager, this method first
+     * calls the security manager's {@code checkCreateClassLoader} method
+     * to ensure creation of a class loader is allowed.
+     *
+     * @param urls the URLs from which to load classes and resources
+     * @param parent the parent class loader for delegation
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkCreateClassLoader} method doesn't allow
+     *             creation of a class loader.
+     * @exception  NullPointerException if {@code urls} is {@code null}.
+     * @see SecurityManager#checkCreateClassLoader
+     */
+    public URLClassLoader(URL[] urls, ClassLoader parent) {
+        super(parent);
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        this.acc = AccessController.getContext();
+        ucp = new URLClassPath(urls, acc);
+    }
+
+    URLClassLoader(URL[] urls, ClassLoader parent,
+                   AccessControlContext acc) {
+        super(parent);
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        this.acc = acc;
+        ucp = new URLClassPath(urls, acc);
+    }
+
+    /**
+     * Constructs a new URLClassLoader for the specified URLs using the
+     * default delegation parent {@code ClassLoader}. The URLs will
+     * be searched in the order specified for classes and resources after
+     * first searching in the parent class loader. Any URL that ends with
+     * a '/' is assumed to refer to a directory. Otherwise, the URL is
+     * assumed to refer to a JAR file which will be downloaded and opened
+     * as needed.
+     *
+     * <p>If there is a security manager, this method first
+     * calls the security manager's {@code checkCreateClassLoader} method
+     * to ensure creation of a class loader is allowed.
+     *
+     * @param urls the URLs from which to load classes and resources
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkCreateClassLoader} method doesn't allow
+     *             creation of a class loader.
+     * @exception  NullPointerException if {@code urls} is {@code null}.
+     * @see SecurityManager#checkCreateClassLoader
+     */
+    public URLClassLoader(URL[] urls) {
+        super();
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        this.acc = AccessController.getContext();
+        ucp = new URLClassPath(urls, acc);
+    }
+
+    URLClassLoader(URL[] urls, AccessControlContext acc) {
+        super();
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        this.acc = acc;
+        ucp = new URLClassPath(urls, acc);
+    }
+
+    /**
+     * Constructs a new URLClassLoader for the specified URLs, parent
+     * class loader, and URLStreamHandlerFactory. The parent argument
+     * will be used as the parent class loader for delegation. The
+     * factory argument will be used as the stream handler factory to
+     * obtain protocol handlers when creating new jar URLs.
+     *
+     * <p>If there is a security manager, this method first
+     * calls the security manager's {@code checkCreateClassLoader} method
+     * to ensure creation of a class loader is allowed.
+     *
+     * @param urls the URLs from which to load classes and resources
+     * @param parent the parent class loader for delegation
+     * @param factory the URLStreamHandlerFactory to use when creating URLs
+     *
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkCreateClassLoader} method doesn't allow
+     *             creation of a class loader.
+     * @exception  NullPointerException if {@code urls} is {@code null}.
+     * @see SecurityManager#checkCreateClassLoader
+     */
+    public URLClassLoader(URL[] urls, ClassLoader parent,
+                          URLStreamHandlerFactory factory) {
+        super(parent);
+        // this is to make the stack depth consistent with 1.1
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkCreateClassLoader();
+        }
+        acc = AccessController.getContext();
+        ucp = new URLClassPath(urls, factory, acc);
+    }
+
+    /* A map (used as a set) to keep track of closeable local resources
+     * (either JarFiles or FileInputStreams). We don't care about
+     * Http resources since they don't need to be closed.
+     *
+     * If the resource is coming from a jar file
+     * we keep a (weak) reference to the JarFile object which can
+     * be closed if URLClassLoader.close() called. Due to jar file
+     * caching there will typically be only one JarFile object
+     * per underlying jar file.
+     *
+     * For file resources, which is probably a less common situation
+     * we have to keep a weak reference to each stream.
+     */
+
+    private WeakHashMap<Closeable,Void>
+        closeables = new WeakHashMap<>();
+
+    /**
+     * Returns an input stream for reading the specified resource.
+     * If this loader is closed, then any resources opened by this method
+     * will be closed.
+     *
+     * <p> The search order is described in the documentation for {@link
+     * #getResource(String)}.  </p>
+     *
+     * @param  name
+     *         The resource name
+     *
+     * @return  An input stream for reading the resource, or {@code null}
+     *          if the resource could not be found
+     *
+     * @since  1.7
+     */
+    public InputStream getResourceAsStream(String name) {
+        URL url = getResource(name);
+        try {
+            if (url == null) {
+                return null;
+            }
+            URLConnection urlc = url.openConnection();
+            InputStream is = urlc.getInputStream();
+            if (urlc instanceof JarURLConnection) {
+                JarURLConnection juc = (JarURLConnection)urlc;
+                JarFile jar = juc.getJarFile();
+                synchronized (closeables) {
+                    if (!closeables.containsKey(jar)) {
+                        closeables.put(jar, null);
+                    }
+                }
+            } else if (urlc instanceof sun.net.www.protocol.file.FileURLConnection) {
+                synchronized (closeables) {
+                    closeables.put(is, null);
+                }
+            }
+            return is;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+   /**
+    * Closes this URLClassLoader, so that it can no longer be used to load
+    * new classes or resources that are defined by this loader.
+    * Classes and resources defined by any of this loader's parents in the
+    * delegation hierarchy are still accessible. Also, any classes or resources
+    * that are already loaded, are still accessible.
+    * <p>
+    * In the case of jar: and file: URLs, it also closes any files
+    * that were opened by it. If another thread is loading a
+    * class when the {@code close} method is invoked, then the result of
+    * that load is undefined.
+    * <p>
+    * The method makes a best effort attempt to close all opened files,
+    * by catching {@link IOException}s internally. Unchecked exceptions
+    * and errors are not caught. Calling close on an already closed
+    * loader has no effect.
+    * <p>
+    * @exception IOException if closing any file opened by this class loader
+    * resulted in an IOException. Any such exceptions are caught internally.
+    * If only one is caught, then it is re-thrown. If more than one exception
+    * is caught, then the second and following exceptions are added
+    * as suppressed exceptions of the first one caught, which is then re-thrown.
+    *
+    * @exception SecurityException if a security manager is set, and it denies
+    *   {@link RuntimePermission}{@code ("closeClassLoader")}
+    *
+    * @since 1.7
+    */
+    public void close() throws IOException {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkPermission(new RuntimePermission("closeClassLoader"));
+        }
+        List<IOException> errors = ucp.closeLoaders();
+
+        // now close any remaining streams.
+
+        synchronized (closeables) {
+            Set<Closeable> keys = closeables.keySet();
+            for (Closeable c : keys) {
+                try {
+                    c.close();
+                } catch (IOException ioex) {
+                    errors.add(ioex);
+                }
+            }
+            closeables.clear();
+        }
+
+        if (errors.isEmpty()) {
+            return;
+        }
+
+        IOException firstex = errors.remove(0);
+
+        // Suppress any remaining exceptions
+
+        for (IOException error: errors) {
+            firstex.addSuppressed(error);
+        }
+        throw firstex;
+    }
+
+    /**
+     * Appends the specified URL to the list of URLs to search for
+     * classes and resources.
+     * <p>
+     * If the URL specified is {@code null} or is already in the
+     * list of URLs, or if this loader is closed, then invoking this
+     * method has no effect.
+     *
+     * @param url the URL to be added to the search path of URLs
+     */
+    protected void addURL(URL url) {
+        ucp.addURL(url);
+    }
+
+    /**
+     * Returns the search path of URLs for loading classes and resources.
+     * This includes the original list of URLs specified to the constructor,
+     * along with any URLs subsequently appended by the addURL() method.
+     * @return the search path of URLs for loading classes and resources.
+     */
+    public URL[] getURLs() {
+        return ucp.getURLs();
+    }
+
+    /**
+     * Finds and loads the class with the specified name from the URL search
+     * path. Any URLs referring to JAR files are loaded and opened as needed
+     * until the class is found.
+     *
+     * @param name the name of the class
+     * @return the resulting class
+     * @exception ClassNotFoundException if the class could not be found,
+     *            or if the loader is closed.
+     * @exception NullPointerException if {@code name} is {@code null}.
+     */
+    protected Class<?> findClass(final String name)
+        throws ClassNotFoundException
+    {
+        final Class<?> result;
+        try {
+            result = AccessController.doPrivileged(
+                new PrivilegedExceptionAction<Class<?>>() {
+                    public Class<?> run() throws ClassNotFoundException {
+                        String path = name.replace('.', '/').concat(".class");
+                        Resource res = ucp.getResource(path, false);
+                        if (res != null) {
+                            try {
+                                return defineClass(name, res);
+                            } catch (IOException e) {
+                                throw new ClassNotFoundException(name, e);
+                            }
+                        } else {
+                            return null;
+                        }
+                    }
+                }, acc);
+        } catch (java.security.PrivilegedActionException pae) {
+            throw (ClassNotFoundException) pae.getException();
+        }
+        if (result == null) {
+            throw new ClassNotFoundException(name);
+        }
+        return result;
+    }
+
+    /*
+     * Retrieve the package using the specified package name.
+     * If non-null, verify the package using the specified code
+     * source and manifest.
+     */
+    private Package getAndVerifyPackage(String pkgname,
+                                        Manifest man, URL url) {
+        Package pkg = getPackage(pkgname);
+        if (pkg != null) {
+            // Package found, so check package sealing.
+            if (pkg.isSealed()) {
+                // Verify that code source URL is the same.
+                if (!pkg.isSealed(url)) {
+                    throw new SecurityException(
+                        "sealing violation: package " + pkgname + " is sealed");
+                }
+            } else {
+                // Make sure we are not attempting to seal the package
+                // at this code source URL.
+                if ((man != null) && isSealed(pkgname, man)) {
+                    throw new SecurityException(
+                        "sealing violation: can't seal package " + pkgname +
+                        ": already loaded");
+                }
+            }
+        }
+        return pkg;
+    }
+
+    // Also called by VM to define Package for classes loaded from the CDS
+    // archive
+    private void definePackageInternal(String pkgname, Manifest man, URL url)
+    {
+        if (getAndVerifyPackage(pkgname, man, url) == null) {
+            try {
+                if (man != null) {
+                    definePackage(pkgname, man, url);
+                } else {
+                    definePackage(pkgname, null, null, null, null, null, null, null);
+                }
+            } catch (IllegalArgumentException iae) {
+                // parallel-capable class loaders: re-verify in case of a
+                // race condition
+                if (getAndVerifyPackage(pkgname, man, url) == null) {
+                    // Should never happen
+                    throw new AssertionError("Cannot find package " +
+                                             pkgname);
+                }
+            }
+        }
+    }
+
+    /*
+     * Defines a Class using the class bytes obtained from the specified
+     * Resource. The resulting Class must be resolved before it can be
+     * used.
+     */
+    private Class<?> defineClass(String name, Resource res) throws IOException {
+        long t0 = System.nanoTime();
+        int i = name.lastIndexOf('.');
+        URL url = res.getCodeSourceURL();
+        if (i != -1) {
+            String pkgname = name.substring(0, i);
+            // Check if package already loaded.
+            Manifest man = res.getManifest();
+            definePackageInternal(pkgname, man, url);
+        }
+        // Now read the class bytes and define the class
+        java.nio.ByteBuffer bb = res.getByteBuffer();
+        if (bb != null) {
+            // Use (direct) ByteBuffer:
+            CodeSigner[] signers = res.getCodeSigners();
+            CodeSource cs = new CodeSource(url, signers);
+            // Android-removed: Android doesn't use sun.misc.PerfCounter.
+            // sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
+            return defineClass(name, bb, cs);
+        } else {
+            byte[] b = res.getBytes();
+            // must read certificates AFTER reading bytes.
+            CodeSigner[] signers = res.getCodeSigners();
+            CodeSource cs = new CodeSource(url, signers);
+            // Android-removed: Android doesn't use sun.misc.PerfCounter.
+            // sun.misc.PerfCounter.getReadClassBytesTime().addElapsedTimeFrom(t0);
+            return defineClass(name, b, 0, b.length, cs);
+        }
+    }
+
+    /**
+     * Defines a new package by name in this ClassLoader. The attributes
+     * contained in the specified Manifest will be used to obtain package
+     * version and sealing information. For sealed packages, the additional
+     * URL specifies the code source URL from which the package was loaded.
+     *
+     * @param name  the package name
+     * @param man   the Manifest containing package version and sealing
+     *              information
+     * @param url   the code source url for the package, or null if none
+     * @exception   IllegalArgumentException if the package name duplicates
+     *              an existing package either in this class loader or one
+     *              of its ancestors
+     * @return the newly defined Package object
+     */
+    protected Package definePackage(String name, Manifest man, URL url)
+        throws IllegalArgumentException
+    {
+        String path = name.replace('.', '/').concat("/");
+        String specTitle = null, specVersion = null, specVendor = null;
+        String implTitle = null, implVersion = null, implVendor = null;
+        String sealed = null;
+        URL sealBase = null;
+
+        Attributes attr = man.getAttributes(path);
+        if (attr != null) {
+            specTitle   = attr.getValue(Name.SPECIFICATION_TITLE);
+            specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+            specVendor  = attr.getValue(Name.SPECIFICATION_VENDOR);
+            implTitle   = attr.getValue(Name.IMPLEMENTATION_TITLE);
+            implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+            implVendor  = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+            sealed      = attr.getValue(Name.SEALED);
+        }
+        attr = man.getMainAttributes();
+        if (attr != null) {
+            if (specTitle == null) {
+                specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
+            }
+            if (specVersion == null) {
+                specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
+            }
+            if (specVendor == null) {
+                specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
+            }
+            if (implTitle == null) {
+                implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
+            }
+            if (implVersion == null) {
+                implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
+            }
+            if (implVendor == null) {
+                implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
+            }
+            if (sealed == null) {
+                sealed = attr.getValue(Name.SEALED);
+            }
+        }
+        if ("true".equalsIgnoreCase(sealed)) {
+            sealBase = url;
+        }
+        return definePackage(name, specTitle, specVersion, specVendor,
+                             implTitle, implVersion, implVendor, sealBase);
+    }
+
+    /*
+     * Returns true if the specified package name is sealed according to the
+     * given manifest.
+     */
+    private boolean isSealed(String name, Manifest man) {
+        String path = name.replace('.', '/').concat("/");
+        Attributes attr = man.getAttributes(path);
+        String sealed = null;
+        if (attr != null) {
+            sealed = attr.getValue(Name.SEALED);
+        }
+        if (sealed == null) {
+            if ((attr = man.getMainAttributes()) != null) {
+                sealed = attr.getValue(Name.SEALED);
+            }
+        }
+        return "true".equalsIgnoreCase(sealed);
+    }
+
+    /**
+     * Finds the resource with the specified name on the URL search path.
+     *
+     * @param name the name of the resource
+     * @return a {@code URL} for the resource, or {@code null}
+     * if the resource could not be found, or if the loader is closed.
+     */
+    public URL findResource(final String name) {
+        /*
+         * The same restriction to finding classes applies to resources
+         */
+        URL url = AccessController.doPrivileged(
+            new PrivilegedAction<URL>() {
+                public URL run() {
+                    return ucp.findResource(name, true);
+                }
+            }, acc);
+
+        return url != null ? ucp.checkURL(url) : null;
+    }
+
+    /**
+     * Returns an Enumeration of URLs representing all of the resources
+     * on the URL search path having the specified name.
+     *
+     * @param name the resource name
+     * @exception IOException if an I/O exception occurs
+     * @return an {@code Enumeration} of {@code URL}s
+     *         If the loader is closed, the Enumeration will be empty.
+     */
+    public Enumeration<URL> findResources(final String name)
+        throws IOException
+    {
+        final Enumeration<URL> e = ucp.findResources(name, true);
+
+        return new Enumeration<URL>() {
+            private URL url = null;
+
+            private boolean next() {
+                if (url != null) {
+                    return true;
+                }
+                do {
+                    URL u = AccessController.doPrivileged(
+                        new PrivilegedAction<URL>() {
+                            public URL run() {
+                                if (!e.hasMoreElements())
+                                    return null;
+                                return e.nextElement();
+                            }
+                        }, acc);
+                    if (u == null)
+                        break;
+                    url = ucp.checkURL(u);
+                } while (url == null);
+                return url != null;
+            }
+
+            public URL nextElement() {
+                if (!next()) {
+                    throw new NoSuchElementException();
+                }
+                URL u = url;
+                url = null;
+                return u;
+            }
+
+            public boolean hasMoreElements() {
+                return next();
+            }
+        };
+    }
+
+    /**
+     * Returns the permissions for the given codesource object.
+     * The implementation of this method first calls super.getPermissions
+     * and then adds permissions based on the URL of the codesource.
+     * <p>
+     * If the protocol of this URL is "jar", then the permission granted
+     * is based on the permission that is required by the URL of the Jar
+     * file.
+     * <p>
+     * If the protocol is "file" and there is an authority component, then
+     * permission to connect to and accept connections from that authority
+     * may be granted. If the protocol is "file"
+     * and the path specifies a file, then permission to read that
+     * file is granted. If protocol is "file" and the path is
+     * a directory, permission is granted to read all files
+     * and (recursively) all files and subdirectories contained in
+     * that directory.
+     * <p>
+     * If the protocol is not "file", then permission
+     * to connect to and accept connections from the URL's host is granted.
+     * @param codesource the codesource
+     * @exception NullPointerException if {@code codesource} is {@code null}.
+     * @return the permissions granted to the codesource
+     */
+    protected PermissionCollection getPermissions(CodeSource codesource)
+    {
+        PermissionCollection perms = super.getPermissions(codesource);
+
+        URL url = codesource.getLocation();
+
+        Permission p;
+        URLConnection urlConnection;
+
+        try {
+            urlConnection = url.openConnection();
+            p = urlConnection.getPermission();
+        } catch (java.io.IOException ioe) {
+            p = null;
+            urlConnection = null;
+        }
+
+        if (p instanceof FilePermission) {
+            // if the permission has a separator char on the end,
+            // it means the codebase is a directory, and we need
+            // to add an additional permission to read recursively
+            String path = p.getName();
+            if (path.endsWith(File.separator)) {
+                path += "-";
+                p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
+            }
+        } else if ((p == null) && (url.getProtocol().equals("file"))) {
+            String path = url.getFile().replace('/', File.separatorChar);
+            path = ParseUtil.decode(path);
+            if (path.endsWith(File.separator))
+                path += "-";
+            p =  new FilePermission(path, SecurityConstants.FILE_READ_ACTION);
+        } else {
+            /**
+             * Not loading from a 'file:' URL so we want to give the class
+             * permission to connect to and accept from the remote host
+             * after we've made sure the host is the correct one and is valid.
+             */
+            URL locUrl = url;
+            if (urlConnection instanceof JarURLConnection) {
+                locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
+            }
+            String host = locUrl.getHost();
+            if (host != null && (host.length() > 0))
+                p = new SocketPermission(host,
+                                         SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION);
+        }
+
+        // make sure the person that created this class loader
+        // would have this permission
+
+        if (p != null) {
+            final SecurityManager sm = System.getSecurityManager();
+            if (sm != null) {
+                final Permission fp = p;
+                AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    public Void run() throws SecurityException {
+                        sm.checkPermission(fp);
+                        return null;
+                    }
+                }, acc);
+            }
+            perms.add(p);
+        }
+        return perms;
+    }
+
+    /**
+     * Creates a new instance of URLClassLoader for the specified
+     * URLs and parent class loader. If a security manager is
+     * installed, the {@code loadClass} method of the URLClassLoader
+     * returned by this method will invoke the
+     * {@code SecurityManager.checkPackageAccess} method before
+     * loading the class.
+     *
+     * @param urls the URLs to search for classes and resources
+     * @param parent the parent class loader for delegation
+     * @exception  NullPointerException if {@code urls} is {@code null}.
+     * @return the resulting class loader
+     */
+    public static URLClassLoader newInstance(final URL[] urls,
+                                             final ClassLoader parent) {
+        // Save the caller's context
+        final AccessControlContext acc = AccessController.getContext();
+        // Need a privileged block to create the class loader
+        URLClassLoader ucl = AccessController.doPrivileged(
+            new PrivilegedAction<URLClassLoader>() {
+                public URLClassLoader run() {
+                    return new FactoryURLClassLoader(urls, parent, acc);
+                }
+            });
+        return ucl;
+    }
+
+    /**
+     * Creates a new instance of URLClassLoader for the specified
+     * URLs and default parent class loader. If a security manager is
+     * installed, the {@code loadClass} method of the URLClassLoader
+     * returned by this method will invoke the
+     * {@code SecurityManager.checkPackageAccess} before
+     * loading the class.
+     *
+     * @param urls the URLs to search for classes and resources
+     * @exception  NullPointerException if {@code urls} is {@code null}.
+     * @return the resulting class loader
+     */
+    public static URLClassLoader newInstance(final URL[] urls) {
+        // Save the caller's context
+        final AccessControlContext acc = AccessController.getContext();
+        // Need a privileged block to create the class loader
+        URLClassLoader ucl = AccessController.doPrivileged(
+            new PrivilegedAction<URLClassLoader>() {
+                public URLClassLoader run() {
+                    return new FactoryURLClassLoader(urls, acc);
+                }
+            });
+        return ucl;
+    }
+
+    static {
+        // Android-removed: SharedSecrets.setJavaNetAccess call. Android doesn't use it.
+        /*sun.misc.SharedSecrets.setJavaNetAccess (
+            new sun.misc.JavaNetAccess() {
+                public URLClassPath getURLClassPath (URLClassLoader u) {
+                    return u.ucp;
+                }
+
+                public String getOriginalHostName(InetAddress ia) {
+                    return ia.holder.getOriginalHostName();
+                }
+            }
+        );*/
+        ClassLoader.registerAsParallelCapable();
+    }
+}
+
+final class FactoryURLClassLoader extends URLClassLoader {
+
+    static {
+        ClassLoader.registerAsParallelCapable();
+    }
+
+    FactoryURLClassLoader(URL[] urls, ClassLoader parent,
+                          AccessControlContext acc) {
+        super(urls, parent, acc);
+    }
+
+    FactoryURLClassLoader(URL[] urls, AccessControlContext acc) {
+        super(urls, acc);
+    }
+
+    public final Class<?> loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+        // First check if we have permission to access the package. This
+        // should go away once we've added support for exported packages.
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) {
+            int i = name.lastIndexOf('.');
+            if (i != -1) {
+                sm.checkPackageAccess(name.substring(0, i));
+            }
+        }
+        return super.loadClass(name, resolve);
+    }
+}
diff --git a/java/net/URLConnection.java b/java/net/URLConnection.java
new file mode 100644
index 0000000..55ec26d
--- /dev/null
+++ b/java/net/URLConnection.java
@@ -0,0 +1,1820 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Date;
+import java.util.StringTokenizer;
+import java.util.Collections;
+import java.util.Map;
+import java.util.List;
+import java.security.Permission;
+import java.security.AccessController;
+import sun.security.util.SecurityConstants;
+import sun.net.www.MessageHeader;
+
+/**
+ * The abstract class {@code URLConnection} is the superclass
+ * of all classes that represent a communications link between the
+ * application and a URL. Instances of this class can be used both to
+ * read from and to write to the resource referenced by the URL. In
+ * general, creating a connection to a URL is a multistep process:
+ *
+ * <center><table border=2 summary="Describes the process of creating a connection to a URL: openConnection() and connect() over time.">
+ * <tr><th>{@code openConnection()}</th>
+ *     <th>{@code connect()}</th></tr>
+ * <tr><td>Manipulate parameters that affect the connection to the remote
+ *         resource.</td>
+ *     <td>Interact with the resource; query header fields and
+ *         contents.</td></tr>
+ * </table>
+ * ----------------------------&gt;
+ * <br>time</center>
+ *
+ * <ol>
+ * <li>The connection object is created by invoking the
+ *     {@code openConnection} method on a URL.
+ * <li>The setup parameters and general request properties are manipulated.
+ * <li>The actual connection to the remote object is made, using the
+ *    {@code connect} method.
+ * <li>The remote object becomes available. The header fields and the contents
+ *     of the remote object can be accessed.
+ * </ol>
+ * <p>
+ * The setup parameters are modified using the following methods:
+ * <ul>
+ *   <li>{@code setAllowUserInteraction}
+ *   <li>{@code setDoInput}
+ *   <li>{@code setDoOutput}
+ *   <li>{@code setIfModifiedSince}
+ *   <li>{@code setUseCaches}
+ * </ul>
+ * <p>
+ * and the general request properties are modified using the method:
+ * <ul>
+ *   <li>{@code setRequestProperty}
+ * </ul>
+ * <p>
+ * Default values for the {@code AllowUserInteraction} and
+ * {@code UseCaches} parameters can be set using the methods
+ * {@code setDefaultAllowUserInteraction} and
+ * {@code setDefaultUseCaches}.
+ * <p>
+ * Each of the above {@code set} methods has a corresponding
+ * {@code get} method to retrieve the value of the parameter or
+ * general request property. The specific parameters and general
+ * request properties that are applicable are protocol specific.
+ * <p>
+ * The following methods are used to access the header fields and
+ * the contents after the connection is made to the remote object:
+ * <ul>
+ *   <li>{@code getContent}
+ *   <li>{@code getHeaderField}
+ *   <li>{@code getInputStream}
+ *   <li>{@code getOutputStream}
+ * </ul>
+ * <p>
+ * Certain header fields are accessed frequently. The methods:
+ * <ul>
+ *   <li>{@code getContentEncoding}
+ *   <li>{@code getContentLength}
+ *   <li>{@code getContentType}
+ *   <li>{@code getDate}
+ *   <li>{@code getExpiration}
+ *   <li>{@code getLastModifed}
+ * </ul>
+ * <p>
+ * provide convenient access to these fields. The
+ * {@code getContentType} method is used by the
+ * {@code getContent} method to determine the type of the remote
+ * object; subclasses may find it convenient to override the
+ * {@code getContentType} method.
+ * <p>
+ * In the common case, all of the pre-connection parameters and
+ * general request properties can be ignored: the pre-connection
+ * parameters and request properties default to sensible values. For
+ * most clients of this interface, there are only two interesting
+ * methods: {@code getInputStream} and {@code getContent},
+ * which are mirrored in the {@code URL} class by convenience methods.
+ * <p>
+ * More information on the request properties and header fields of
+ * an {@code http} connection can be found at:
+ * <blockquote><pre>
+ * <a href="http://www.ietf.org/rfc/rfc2616.txt">http://www.ietf.org/rfc/rfc2616.txt</a>
+ * </pre></blockquote>
+ *
+ * Invoking the {@code close()} methods on the {@code InputStream} or {@code OutputStream} of an
+ * {@code URLConnection} after a request may free network resources associated with this
+ * instance, unless particular protocol specifications specify different behaviours
+ * for it.
+ *
+ * @author  James Gosling
+ * @see     java.net.URL#openConnection()
+ * @see     java.net.URLConnection#connect()
+ * @see     java.net.URLConnection#getContent()
+ * @see     java.net.URLConnection#getContentEncoding()
+ * @see     java.net.URLConnection#getContentLength()
+ * @see     java.net.URLConnection#getContentType()
+ * @see     java.net.URLConnection#getDate()
+ * @see     java.net.URLConnection#getExpiration()
+ * @see     java.net.URLConnection#getHeaderField(int)
+ * @see     java.net.URLConnection#getHeaderField(java.lang.String)
+ * @see     java.net.URLConnection#getInputStream()
+ * @see     java.net.URLConnection#getLastModified()
+ * @see     java.net.URLConnection#getOutputStream()
+ * @see     java.net.URLConnection#setAllowUserInteraction(boolean)
+ * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
+ * @see     java.net.URLConnection#setDoInput(boolean)
+ * @see     java.net.URLConnection#setDoOutput(boolean)
+ * @see     java.net.URLConnection#setIfModifiedSince(long)
+ * @see     java.net.URLConnection#setRequestProperty(java.lang.String, java.lang.String)
+ * @see     java.net.URLConnection#setUseCaches(boolean)
+ * @since   JDK1.0
+ */
+public abstract class URLConnection {
+
+   /**
+     * The URL represents the remote object on the World Wide Web to
+     * which this connection is opened.
+     * <p>
+     * The value of this field can be accessed by the
+     * {@code getURL} method.
+     * <p>
+     * The default value of this variable is the value of the URL
+     * argument in the {@code URLConnection} constructor.
+     *
+     * @see     java.net.URLConnection#getURL()
+     * @see     java.net.URLConnection#url
+     */
+    protected URL url;
+
+   /**
+     * This variable is set by the {@code setDoInput} method. Its
+     * value is returned by the {@code getDoInput} method.
+     * <p>
+     * A URL connection can be used for input and/or output. Setting the
+     * {@code doInput} flag to {@code true} indicates that
+     * the application intends to read data from the URL connection.
+     * <p>
+     * The default value of this field is {@code true}.
+     *
+     * @see     java.net.URLConnection#getDoInput()
+     * @see     java.net.URLConnection#setDoInput(boolean)
+     */
+    protected boolean doInput = true;
+
+   /**
+     * This variable is set by the {@code setDoOutput} method. Its
+     * value is returned by the {@code getDoOutput} method.
+     * <p>
+     * A URL connection can be used for input and/or output. Setting the
+     * {@code doOutput} flag to {@code true} indicates
+     * that the application intends to write data to the URL connection.
+     * <p>
+     * The default value of this field is {@code false}.
+     *
+     * @see     java.net.URLConnection#getDoOutput()
+     * @see     java.net.URLConnection#setDoOutput(boolean)
+     */
+    protected boolean doOutput = false;
+
+    private static boolean defaultAllowUserInteraction = false;
+
+   /**
+     * If {@code true}, this {@code URL} is being examined in
+     * a context in which it makes sense to allow user interactions such
+     * as popping up an authentication dialog. If {@code false},
+     * then no user interaction is allowed.
+     * <p>
+     * The value of this field can be set by the
+     * {@code setAllowUserInteraction} method.
+     * Its value is returned by the
+     * {@code getAllowUserInteraction} method.
+     * Its default value is the value of the argument in the last invocation
+     * of the {@code setDefaultAllowUserInteraction} method.
+     *
+     * @see     java.net.URLConnection#getAllowUserInteraction()
+     * @see     java.net.URLConnection#setAllowUserInteraction(boolean)
+     * @see     java.net.URLConnection#setDefaultAllowUserInteraction(boolean)
+     */
+    protected boolean allowUserInteraction = defaultAllowUserInteraction;
+
+    private static boolean defaultUseCaches = true;
+
+   /**
+     * If {@code true}, the protocol is allowed to use caching
+     * whenever it can. If {@code false}, the protocol must always
+     * try to get a fresh copy of the object.
+     * <p>
+     * This field is set by the {@code setUseCaches} method. Its
+     * value is returned by the {@code getUseCaches} method.
+     * <p>
+     * Its default value is the value given in the last invocation of the
+     * {@code setDefaultUseCaches} method.
+     *
+     * @see     java.net.URLConnection#setUseCaches(boolean)
+     * @see     java.net.URLConnection#getUseCaches()
+     * @see     java.net.URLConnection#setDefaultUseCaches(boolean)
+     */
+    protected boolean useCaches = defaultUseCaches;
+
+   /**
+     * Some protocols support skipping the fetching of the object unless
+     * the object has been modified more recently than a certain time.
+     * <p>
+     * A nonzero value gives a time as the number of milliseconds since
+     * January 1, 1970, GMT. The object is fetched only if it has been
+     * modified more recently than that time.
+     * <p>
+     * This variable is set by the {@code setIfModifiedSince}
+     * method. Its value is returned by the
+     * {@code getIfModifiedSince} method.
+     * <p>
+     * The default value of this field is {@code 0}, indicating
+     * that the fetching must always occur.
+     *
+     * @see     java.net.URLConnection#getIfModifiedSince()
+     * @see     java.net.URLConnection#setIfModifiedSince(long)
+     */
+    protected long ifModifiedSince = 0;
+
+   /**
+     * If {@code false}, this connection object has not created a
+     * communications link to the specified URL. If {@code true},
+     * the communications link has been established.
+     */
+    protected boolean connected = false;
+
+    /**
+     * @since 1.5
+     */
+    private int connectTimeout;
+    private int readTimeout;
+
+    /**
+     * @since 1.6
+     */
+    private MessageHeader requests;
+
+   /**
+    * @since   JDK1.1
+    */
+    private static FileNameMap fileNameMap;
+
+    // BEGIN Android-changed: Android has its own mime table.
+    /*
+    /**
+     * @since 1.2.2
+     *
+    private static boolean fileNameMapLoaded = false;
+
+    /**
+     * Loads filename map (a mimetable) from a data file. It will
+     * first try to load the user-specific table, defined
+     * by &quot;content.types.user.table&quot; property. If that fails,
+     * it tries to load the default built-in table.
+     *
+     * @return the FileNameMap
+     * @since 1.2
+     * @see #setFileNameMap(java.net.FileNameMap)
+     *
+    public static synchronized FileNameMap getFileNameMap() {
+        if ((fileNameMap == null) && !fileNameMapLoaded) {
+            fileNameMap = sun.net.www.MimeTable.loadTable();
+            fileNameMapLoaded = true;
+        }
+
+        return new FileNameMap() {
+            private FileNameMap map = fileNameMap;
+            public String getContentTypeFor(String fileName) {
+                return map.getContentTypeFor(fileName);
+            }
+        };
+    }
+    */
+    /**
+     * Returns a {@link FileNameMap} implementation suitable for guessing a
+     * content type based on a URL's "file" component.
+     *
+     * @see #guessContentTypeFromName(String)
+     * @see #setFileNameMap(java.net.FileNameMap)
+     *
+     */
+    public static synchronized FileNameMap getFileNameMap() {
+        if (fileNameMap == null) {
+            fileNameMap = new DefaultFileNameMap();
+        }
+        return fileNameMap;
+    }
+    // END Android-changed: Android has its own mime table.
+
+    /**
+     * Sets the FileNameMap.
+     * <p>
+     * If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param map the FileNameMap to be set
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't allow the operation.
+     * @see        SecurityManager#checkSetFactory
+     * @see #getFileNameMap()
+     * @since 1.2
+     */
+    public static void setFileNameMap(FileNameMap map) {
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null) sm.checkSetFactory();
+        fileNameMap = map;
+    }
+
+    /**
+     * Opens a communications link to the resource referenced by this
+     * URL, if such a connection has not already been established.
+     * <p>
+     * If the {@code connect} method is called when the connection
+     * has already been opened (indicated by the {@code connected}
+     * field having the value {@code true}), the call is ignored.
+     * <p>
+     * URLConnection objects go through two phases: first they are
+     * created, then they are connected.  After being created, and
+     * before being connected, various options can be specified
+     * (e.g., doInput and UseCaches).  After connecting, it is an
+     * error to try to set them.  Operations that depend on being
+     * connected, like getContentLength, will implicitly perform the
+     * connection, if necessary.
+     *
+     * @throws SocketTimeoutException if the timeout expires before
+     *               the connection can be established
+     * @exception  IOException  if an I/O error occurs while opening the
+     *               connection.
+     * @see java.net.URLConnection#connected
+     * @see #getConnectTimeout()
+     * @see #setConnectTimeout(int)
+     */
+    abstract public void connect() throws IOException;
+
+    // Android-changed: Add javadoc to specify Android's timeout behavior.
+    /**
+     * Sets a specified timeout value, in milliseconds, to be used
+     * when opening a communications link to the resource referenced
+     * by this URLConnection.  If the timeout expires before the
+     * connection can be established, a
+     * java.net.SocketTimeoutException is raised. A timeout of zero is
+     * interpreted as an infinite timeout.
+
+     * <p> Some non-standard implementation of this method may ignore
+     * the specified timeout. To see the connect timeout set, please
+     * call getConnectTimeout().
+     *
+     * <p><strong>Warning</strong>: If the hostname resolves to multiple IP
+     * addresses, Android's default implementation of {@link HttpURLConnection}
+     * will try each in
+     * <a href="http://www.ietf.org/rfc/rfc3484.txt">RFC 3484</a> order. If
+     * connecting to each of these addresses fails, multiple timeouts will
+     * elapse before the connect attempt throws an exception. Host names
+     * that support both IPv6 and IPv4 always have at least 2 IP addresses.
+     *
+     * @param timeout an {@code int} that specifies the connect
+     *               timeout value in milliseconds
+     * @throws IllegalArgumentException if the timeout parameter is negative
+     *
+     * @see #getConnectTimeout()
+     * @see #connect()
+     * @since 1.5
+     */
+    public void setConnectTimeout(int timeout) {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout can not be negative");
+        }
+        connectTimeout = timeout;
+    }
+
+    /**
+     * Returns setting for connect timeout.
+     * <p>
+     * 0 return implies that the option is disabled
+     * (i.e., timeout of infinity).
+     *
+     * @return an {@code int} that indicates the connect timeout
+     *         value in milliseconds
+     * @see #setConnectTimeout(int)
+     * @see #connect()
+     * @since 1.5
+     */
+    public int getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    /**
+     * Sets the read timeout to a specified timeout, in
+     * milliseconds. A non-zero value specifies the timeout when
+     * reading from Input stream when a connection is established to a
+     * resource. If the timeout expires before there is data available
+     * for read, a java.net.SocketTimeoutException is raised. A
+     * timeout of zero is interpreted as an infinite timeout.
+     *
+     *<p> Some non-standard implementation of this method ignores the
+     * specified timeout. To see the read timeout set, please call
+     * getReadTimeout().
+     *
+     * @param timeout an {@code int} that specifies the timeout
+     * value to be used in milliseconds
+     * @throws IllegalArgumentException if the timeout parameter is negative
+     *
+     * @see #getReadTimeout()
+     * @see InputStream#read()
+     * @since 1.5
+     */
+    public void setReadTimeout(int timeout) {
+        if (timeout < 0) {
+            throw new IllegalArgumentException("timeout can not be negative");
+        }
+        readTimeout = timeout;
+    }
+
+    /**
+     * Returns setting for read timeout. 0 return implies that the
+     * option is disabled (i.e., timeout of infinity).
+     *
+     * @return an {@code int} that indicates the read timeout
+     *         value in milliseconds
+     *
+     * @see #setReadTimeout(int)
+     * @see InputStream#read()
+     * @since 1.5
+     */
+    public int getReadTimeout() {
+        return readTimeout;
+    }
+
+    /**
+     * Constructs a URL connection to the specified URL. A connection to
+     * the object referenced by the URL is not created.
+     *
+     * @param   url   the specified URL.
+     */
+    protected URLConnection(URL url) {
+        this.url = url;
+    }
+
+    /**
+     * Returns the value of this {@code URLConnection}'s {@code URL}
+     * field.
+     *
+     * @return  the value of this {@code URLConnection}'s {@code URL}
+     *          field.
+     * @see     java.net.URLConnection#url
+     */
+    public URL getURL() {
+        return url;
+    }
+
+    /**
+     * Returns the value of the {@code content-length} header field.
+     * <P>
+     * <B>Note</B>: {@link #getContentLengthLong() getContentLengthLong()}
+     * should be preferred over this method, since it returns a {@code long}
+     * instead and is therefore more portable.</P>
+     *
+     * @return  the content length of the resource that this connection's URL
+     *          references, {@code -1} if the content length is not known,
+     *          or if the content length is greater than Integer.MAX_VALUE.
+     */
+    public int getContentLength() {
+        long l = getContentLengthLong();
+        if (l > Integer.MAX_VALUE)
+            return -1;
+        return (int) l;
+    }
+
+    /**
+     * Returns the value of the {@code content-length} header field as a
+     * long.
+     *
+     * @return  the content length of the resource that this connection's URL
+     *          references, or {@code -1} if the content length is
+     *          not known.
+     * @since 7.0
+     */
+    public long getContentLengthLong() {
+        return getHeaderFieldLong("content-length", -1);
+    }
+
+    /**
+     * Returns the value of the {@code content-type} header field.
+     *
+     * @return  the content type of the resource that the URL references,
+     *          or {@code null} if not known.
+     * @see     java.net.URLConnection#getHeaderField(java.lang.String)
+     */
+    public String getContentType() {
+        return getHeaderField("content-type");
+    }
+
+    /**
+     * Returns the value of the {@code content-encoding} header field.
+     *
+     * @return  the content encoding of the resource that the URL references,
+     *          or {@code null} if not known.
+     * @see     java.net.URLConnection#getHeaderField(java.lang.String)
+     */
+    public String getContentEncoding() {
+        return getHeaderField("content-encoding");
+    }
+
+    /**
+     * Returns the value of the {@code expires} header field.
+     *
+     * @return  the expiration date of the resource that this URL references,
+     *          or 0 if not known. The value is the number of milliseconds since
+     *          January 1, 1970 GMT.
+     * @see     java.net.URLConnection#getHeaderField(java.lang.String)
+     */
+    public long getExpiration() {
+        return getHeaderFieldDate("expires", 0);
+    }
+
+    /**
+     * Returns the value of the {@code date} header field.
+     *
+     * @return  the sending date of the resource that the URL references,
+     *          or {@code 0} if not known. The value returned is the
+     *          number of milliseconds since January 1, 1970 GMT.
+     * @see     java.net.URLConnection#getHeaderField(java.lang.String)
+     */
+    public long getDate() {
+        return getHeaderFieldDate("date", 0);
+    }
+
+    /**
+     * Returns the value of the {@code last-modified} header field.
+     * The result is the number of milliseconds since January 1, 1970 GMT.
+     *
+     * @return  the date the resource referenced by this
+     *          {@code URLConnection} was last modified, or 0 if not known.
+     * @see     java.net.URLConnection#getHeaderField(java.lang.String)
+     */
+    public long getLastModified() {
+        return getHeaderFieldDate("last-modified", 0);
+    }
+
+    /**
+     * Returns the value of the named header field.
+     * <p>
+     * If called on a connection that sets the same header multiple times
+     * with possibly different values, only the last value is returned.
+     *
+     *
+     * @param   name   the name of a header field.
+     * @return  the value of the named header field, or {@code null}
+     *          if there is no such field in the header.
+     */
+    public String getHeaderField(String name) {
+        return null;
+    }
+
+    /**
+     * Returns an unmodifiable Map of the header fields.
+     * The Map keys are Strings that represent the
+     * response-header field names. Each Map value is an
+     * unmodifiable List of Strings that represents
+     * the corresponding field values.
+     *
+     * @return a Map of header fields
+     * @since 1.4
+     */
+    public Map<String,List<String>> getHeaderFields() {
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Returns the value of the named field parsed as a number.
+     * <p>
+     * This form of {@code getHeaderField} exists because some
+     * connection types (e.g., {@code http-ng}) have pre-parsed
+     * headers. Classes for that connection type can override this method
+     * and short-circuit the parsing.
+     *
+     * @param   name      the name of the header field.
+     * @param   Default   the default value.
+     * @return  the value of the named field, parsed as an integer. The
+     *          {@code Default} value is returned if the field is
+     *          missing or malformed.
+     */
+    public int getHeaderFieldInt(String name, int Default) {
+        String value = getHeaderField(name);
+        try {
+            return Integer.parseInt(value);
+        } catch (Exception e) { }
+        return Default;
+    }
+
+    /**
+     * Returns the value of the named field parsed as a number.
+     * <p>
+     * This form of {@code getHeaderField} exists because some
+     * connection types (e.g., {@code http-ng}) have pre-parsed
+     * headers. Classes for that connection type can override this method
+     * and short-circuit the parsing.
+     *
+     * @param   name      the name of the header field.
+     * @param   Default   the default value.
+     * @return  the value of the named field, parsed as a long. The
+     *          {@code Default} value is returned if the field is
+     *          missing or malformed.
+     * @since 7.0
+     */
+    public long getHeaderFieldLong(String name, long Default) {
+        String value = getHeaderField(name);
+        try {
+            return Long.parseLong(value);
+        } catch (Exception e) { }
+        return Default;
+    }
+
+    /**
+     * Returns the value of the named field parsed as date.
+     * The result is the number of milliseconds since January 1, 1970 GMT
+     * represented by the named field.
+     * <p>
+     * This form of {@code getHeaderField} exists because some
+     * connection types (e.g., {@code http-ng}) have pre-parsed
+     * headers. Classes for that connection type can override this method
+     * and short-circuit the parsing.
+     *
+     * @param   name     the name of the header field.
+     * @param   Default   a default value.
+     * @return  the value of the field, parsed as a date. The value of the
+     *          {@code Default} argument is returned if the field is
+     *          missing or malformed.
+     */
+    @SuppressWarnings("deprecation")
+    public long getHeaderFieldDate(String name, long Default) {
+        String value = getHeaderField(name);
+        try {
+            return Date.parse(value);
+        } catch (Exception e) { }
+        return Default;
+    }
+
+    /**
+     * Returns the key for the {@code n}<sup>th</sup> header field.
+     * It returns {@code null} if there are fewer than {@code n+1} fields.
+     *
+     * @param   n   an index, where {@code n>=0}
+     * @return  the key for the {@code n}<sup>th</sup> header field,
+     *          or {@code null} if there are fewer than {@code n+1}
+     *          fields.
+     */
+    public String getHeaderFieldKey(int n) {
+        return null;
+    }
+
+    /**
+     * Returns the value for the {@code n}<sup>th</sup> header field.
+     * It returns {@code null} if there are fewer than
+     * {@code n+1}fields.
+     * <p>
+     * This method can be used in conjunction with the
+     * {@link #getHeaderFieldKey(int) getHeaderFieldKey} method to iterate through all
+     * the headers in the message.
+     *
+     * @param   n   an index, where {@code n>=0}
+     * @return  the value of the {@code n}<sup>th</sup> header field
+     *          or {@code null} if there are fewer than {@code n+1} fields
+     * @see     java.net.URLConnection#getHeaderFieldKey(int)
+     */
+    public String getHeaderField(int n) {
+        return null;
+    }
+
+    /**
+     * Retrieves the contents of this URL connection.
+     * <p>
+     * This method first determines the content type of the object by
+     * calling the {@code getContentType} method. If this is
+     * the first time that the application has seen that specific content
+     * type, a content handler for that content type is created:
+     * <ol>
+     * <li>If the application has set up a content handler factory instance
+     *     using the {@code setContentHandlerFactory} method, the
+     *     {@code createContentHandler} method of that instance is called
+     *     with the content type as an argument; the result is a content
+     *     handler for that content type.
+     * <li>If no content handler factory has yet been set up, or if the
+     *     factory's {@code createContentHandler} method returns
+     *     {@code null}, then the application loads the class named:
+     *     <blockquote><pre>
+     *         sun.net.www.content.&lt;<i>contentType</i>&gt;
+     *     </pre></blockquote>
+     *     where &lt;<i>contentType</i>&gt; is formed by taking the
+     *     content-type string, replacing all slash characters with a
+     *     {@code period} ('.'), and all other non-alphanumeric characters
+     *     with the underscore character '{@code _}'. The alphanumeric
+     *     characters are specifically the 26 uppercase ASCII letters
+     *     '{@code A}' through '{@code Z}', the 26 lowercase ASCII
+     *     letters '{@code a}' through '{@code z}', and the 10 ASCII
+     *     digits '{@code 0}' through '{@code 9}'. If the specified
+     *     class does not exist, or is not a subclass of
+     *     {@code ContentHandler}, then an
+     *     {@code UnknownServiceException} is thrown.
+     * </ol>
+     *
+     * @return     the object fetched. The {@code instanceof} operator
+     *               should be used to determine the specific kind of object
+     *               returned.
+     * @exception  IOException              if an I/O error occurs while
+     *               getting the content.
+     * @exception  UnknownServiceException  if the protocol does not support
+     *               the content type.
+     * @see        java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
+     * @see        java.net.URLConnection#getContentType()
+     * @see        java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
+     */
+    public Object getContent() throws IOException {
+        // Must call getInputStream before GetHeaderField gets called
+        // so that FileNotFoundException has a chance to be thrown up
+        // from here without being caught.
+        getInputStream();
+        return getContentHandler().getContent(this);
+    }
+
+    /**
+     * Retrieves the contents of this URL connection.
+     *
+     * @param classes the {@code Class} array
+     * indicating the requested types
+     * @return     the object fetched that is the first match of the type
+     *               specified in the classes array. null if none of
+     *               the requested types are supported.
+     *               The {@code instanceof} operator should be used to
+     *               determine the specific kind of object returned.
+     * @exception  IOException              if an I/O error occurs while
+     *               getting the content.
+     * @exception  UnknownServiceException  if the protocol does not support
+     *               the content type.
+     * @see        java.net.URLConnection#getContent()
+     * @see        java.net.ContentHandlerFactory#createContentHandler(java.lang.String)
+     * @see        java.net.URLConnection#getContent(java.lang.Class[])
+     * @see        java.net.URLConnection#setContentHandlerFactory(java.net.ContentHandlerFactory)
+     * @since 1.3
+     */
+    public Object getContent(Class[] classes) throws IOException {
+        // Must call getInputStream before GetHeaderField gets called
+        // so that FileNotFoundException has a chance to be thrown up
+        // from here without being caught.
+        getInputStream();
+        return getContentHandler().getContent(this, classes);
+    }
+
+    /**
+     * Returns a permission object representing the permission
+     * necessary to make the connection represented by this
+     * object. This method returns null if no permission is
+     * required to make the connection. By default, this method
+     * returns {@code java.security.AllPermission}. Subclasses
+     * should override this method and return the permission
+     * that best represents the permission required to make a
+     * a connection to the URL. For example, a {@code URLConnection}
+     * representing a {@code file:} URL would return a
+     * {@code java.io.FilePermission} object.
+     *
+     * <p>The permission returned may dependent upon the state of the
+     * connection. For example, the permission before connecting may be
+     * different from that after connecting. For example, an HTTP
+     * sever, say foo.com, may redirect the connection to a different
+     * host, say bar.com. Before connecting the permission returned by
+     * the connection will represent the permission needed to connect
+     * to foo.com, while the permission returned after connecting will
+     * be to bar.com.
+     *
+     * <p>Permissions are generally used for two purposes: to protect
+     * caches of objects obtained through URLConnections, and to check
+     * the right of a recipient to learn about a particular URL. In
+     * the first case, the permission should be obtained
+     * <em>after</em> the object has been obtained. For example, in an
+     * HTTP connection, this will represent the permission to connect
+     * to the host from which the data was ultimately fetched. In the
+     * second case, the permission should be obtained and tested
+     * <em>before</em> connecting.
+     *
+     * @return the permission object representing the permission
+     * necessary to make the connection represented by this
+     * URLConnection.
+     *
+     * @exception IOException if the computation of the permission
+     * requires network or file I/O and an exception occurs while
+     * computing it.
+     */
+    public Permission getPermission() throws IOException {
+        return SecurityConstants.ALL_PERMISSION;
+    }
+
+    /**
+     * Returns an input stream that reads from this open connection.
+     *
+     * A SocketTimeoutException can be thrown when reading from the
+     * returned input stream if the read timeout expires before data
+     * is available for read.
+     *
+     * @return     an input stream that reads from this open connection.
+     * @exception  IOException              if an I/O error occurs while
+     *               creating the input stream.
+     * @exception  UnknownServiceException  if the protocol does not support
+     *               input.
+     * @see #setReadTimeout(int)
+     * @see #getReadTimeout()
+     */
+    public InputStream getInputStream() throws IOException {
+        throw new UnknownServiceException("protocol doesn't support input");
+    }
+
+    /**
+     * Returns an output stream that writes to this connection.
+     *
+     * @return     an output stream that writes to this connection.
+     * @exception  IOException              if an I/O error occurs while
+     *               creating the output stream.
+     * @exception  UnknownServiceException  if the protocol does not support
+     *               output.
+     */
+    public OutputStream getOutputStream() throws IOException {
+        throw new UnknownServiceException("protocol doesn't support output");
+    }
+
+    /**
+     * Returns a {@code String} representation of this URL connection.
+     *
+     * @return  a string representation of this {@code URLConnection}.
+     */
+    public String toString() {
+        return this.getClass().getName() + ":" + url;
+    }
+
+    /**
+     * Sets the value of the {@code doInput} field for this
+     * {@code URLConnection} to the specified value.
+     * <p>
+     * A URL connection can be used for input and/or output.  Set the DoInput
+     * flag to true if you intend to use the URL connection for input,
+     * false if not.  The default is true.
+     *
+     * @param   doinput   the new value.
+     * @throws IllegalStateException if already connected
+     * @see     java.net.URLConnection#doInput
+     * @see #getDoInput()
+     */
+    public void setDoInput(boolean doinput) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        doInput = doinput;
+    }
+
+    /**
+     * Returns the value of this {@code URLConnection}'s
+     * {@code doInput} flag.
+     *
+     * @return  the value of this {@code URLConnection}'s
+     *          {@code doInput} flag.
+     * @see     #setDoInput(boolean)
+     */
+    public boolean getDoInput() {
+        return doInput;
+    }
+
+    /**
+     * Sets the value of the {@code doOutput} field for this
+     * {@code URLConnection} to the specified value.
+     * <p>
+     * A URL connection can be used for input and/or output.  Set the DoOutput
+     * flag to true if you intend to use the URL connection for output,
+     * false if not.  The default is false.
+     *
+     * @param   dooutput   the new value.
+     * @throws IllegalStateException if already connected
+     * @see #getDoOutput()
+     */
+    public void setDoOutput(boolean dooutput) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        doOutput = dooutput;
+    }
+
+    /**
+     * Returns the value of this {@code URLConnection}'s
+     * {@code doOutput} flag.
+     *
+     * @return  the value of this {@code URLConnection}'s
+     *          {@code doOutput} flag.
+     * @see     #setDoOutput(boolean)
+     */
+    public boolean getDoOutput() {
+        return doOutput;
+    }
+
+    /**
+     * Set the value of the {@code allowUserInteraction} field of
+     * this {@code URLConnection}.
+     *
+     * @param   allowuserinteraction   the new value.
+     * @throws IllegalStateException if already connected
+     * @see     #getAllowUserInteraction()
+     */
+    public void setAllowUserInteraction(boolean allowuserinteraction) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        allowUserInteraction = allowuserinteraction;
+    }
+
+    /**
+     * Returns the value of the {@code allowUserInteraction} field for
+     * this object.
+     *
+     * @return  the value of the {@code allowUserInteraction} field for
+     *          this object.
+     * @see     #setAllowUserInteraction(boolean)
+     */
+    public boolean getAllowUserInteraction() {
+        return allowUserInteraction;
+    }
+
+    /**
+     * Sets the default value of the
+     * {@code allowUserInteraction} field for all future
+     * {@code URLConnection} objects to the specified value.
+     *
+     * @param   defaultallowuserinteraction   the new value.
+     * @see     #getDefaultAllowUserInteraction()
+     */
+    public static void setDefaultAllowUserInteraction(boolean defaultallowuserinteraction) {
+        defaultAllowUserInteraction = defaultallowuserinteraction;
+    }
+
+    /**
+     * Returns the default value of the {@code allowUserInteraction}
+     * field.
+     * <p>
+     * Ths default is "sticky", being a part of the static state of all
+     * URLConnections.  This flag applies to the next, and all following
+     * URLConnections that are created.
+     *
+     * @return  the default value of the {@code allowUserInteraction}
+     *          field.
+     * @see     #setDefaultAllowUserInteraction(boolean)
+     */
+    public static boolean getDefaultAllowUserInteraction() {
+        return defaultAllowUserInteraction;
+    }
+
+    /**
+     * Sets the value of the {@code useCaches} field of this
+     * {@code URLConnection} to the specified value.
+     * <p>
+     * Some protocols do caching of documents.  Occasionally, it is important
+     * to be able to "tunnel through" and ignore the caches (e.g., the
+     * "reload" button in a browser).  If the UseCaches flag on a connection
+     * is true, the connection is allowed to use whatever caches it can.
+     *  If false, caches are to be ignored.
+     *  The default value comes from DefaultUseCaches, which defaults to
+     * true.
+     *
+     * @param usecaches a {@code boolean} indicating whether
+     * or not to allow caching
+     * @throws IllegalStateException if already connected
+     * @see #getUseCaches()
+     */
+    public void setUseCaches(boolean usecaches) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        useCaches = usecaches;
+    }
+
+    /**
+     * Returns the value of this {@code URLConnection}'s
+     * {@code useCaches} field.
+     *
+     * @return  the value of this {@code URLConnection}'s
+     *          {@code useCaches} field.
+     * @see #setUseCaches(boolean)
+     */
+    public boolean getUseCaches() {
+        return useCaches;
+    }
+
+    /**
+     * Sets the value of the {@code ifModifiedSince} field of
+     * this {@code URLConnection} to the specified value.
+     *
+     * @param   ifmodifiedsince   the new value.
+     * @throws IllegalStateException if already connected
+     * @see     #getIfModifiedSince()
+     */
+    public void setIfModifiedSince(long ifmodifiedsince) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        ifModifiedSince = ifmodifiedsince;
+    }
+
+    /**
+     * Returns the value of this object's {@code ifModifiedSince} field.
+     *
+     * @return  the value of this object's {@code ifModifiedSince} field.
+     * @see #setIfModifiedSince(long)
+     */
+    public long getIfModifiedSince() {
+        return ifModifiedSince;
+    }
+
+   /**
+     * Returns the default value of a {@code URLConnection}'s
+     * {@code useCaches} flag.
+     * <p>
+     * Ths default is "sticky", being a part of the static state of all
+     * URLConnections.  This flag applies to the next, and all following
+     * URLConnections that are created.
+     *
+     * @return  the default value of a {@code URLConnection}'s
+     *          {@code useCaches} flag.
+     * @see     #setDefaultUseCaches(boolean)
+     */
+    public boolean getDefaultUseCaches() {
+        return defaultUseCaches;
+    }
+
+   /**
+     * Sets the default value of the {@code useCaches} field to the
+     * specified value.
+     *
+     * @param   defaultusecaches   the new value.
+     * @see     #getDefaultUseCaches()
+     */
+    public void setDefaultUseCaches(boolean defaultusecaches) {
+        defaultUseCaches = defaultusecaches;
+    }
+
+    /**
+     * Sets the general request property. If a property with the key already
+     * exists, overwrite its value with the new value.
+     *
+     * <p> NOTE: HTTP requires all request properties which can
+     * legally have multiple instances with the same key
+     * to use a comma-separated list syntax which enables multiple
+     * properties to be appended into a single property.
+     *
+     * @param   key     the keyword by which the request is known
+     *                  (e.g., "{@code Accept}").
+     * @param   value   the value associated with it.
+     * @throws IllegalStateException if already connected
+     * @throws NullPointerException if key is <CODE>null</CODE>
+     * @see #getRequestProperty(java.lang.String)
+     */
+    public void setRequestProperty(String key, String value) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        if (key == null)
+            throw new NullPointerException ("key is null");
+
+        if (requests == null)
+            requests = new MessageHeader();
+
+        requests.set(key, value);
+    }
+
+    /**
+     * Adds a general request property specified by a
+     * key-value pair.  This method will not overwrite
+     * existing values associated with the same key.
+     *
+     * @param   key     the keyword by which the request is known
+     *                  (e.g., "{@code Accept}").
+     * @param   value  the value associated with it.
+     * @throws IllegalStateException if already connected
+     * @throws NullPointerException if key is null
+     * @see #getRequestProperties()
+     * @since 1.4
+     */
+    public void addRequestProperty(String key, String value) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+        if (key == null)
+            throw new NullPointerException ("key is null");
+
+        if (requests == null)
+            requests = new MessageHeader();
+
+        requests.add(key, value);
+    }
+
+
+    /**
+     * Returns the value of the named general request property for this
+     * connection.
+     *
+     * @param key the keyword by which the request is known (e.g., "Accept").
+     * @return  the value of the named general request property for this
+     *           connection. If key is null, then null is returned.
+     * @throws IllegalStateException if already connected
+     * @see #setRequestProperty(java.lang.String, java.lang.String)
+     */
+    public String getRequestProperty(String key) {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+
+        if (requests == null)
+            return null;
+
+        return requests.findValue(key);
+    }
+
+    /**
+     * Returns an unmodifiable Map of general request
+     * properties for this connection. The Map keys
+     * are Strings that represent the request-header
+     * field names. Each Map value is a unmodifiable List
+     * of Strings that represents the corresponding
+     * field values.
+     *
+     * @return  a Map of the general request properties for this connection.
+     * @throws IllegalStateException if already connected
+     * @since 1.4
+     */
+    public Map<String,List<String>> getRequestProperties() {
+        if (connected)
+            throw new IllegalStateException("Already connected");
+
+        if (requests == null)
+            return Collections.emptyMap();
+
+        return requests.getHeaders(null);
+    }
+
+    /**
+     * Sets the default value of a general request property. When a
+     * {@code URLConnection} is created, it is initialized with
+     * these properties.
+     *
+     * @param   key     the keyword by which the request is known
+     *                  (e.g., "{@code Accept}").
+     * @param   value   the value associated with the key.
+     *
+     * @see java.net.URLConnection#setRequestProperty(java.lang.String,java.lang.String)
+     *
+     * @deprecated The instance specific setRequestProperty method
+     * should be used after an appropriate instance of URLConnection
+     * is obtained. Invoking this method will have no effect.
+     *
+     * @see #getDefaultRequestProperty(java.lang.String)
+     */
+    @Deprecated
+    public static void setDefaultRequestProperty(String key, String value) {
+    }
+
+    /**
+     * Returns the value of the default request property. Default request
+     * properties are set for every connection.
+     *
+     * @param key the keyword by which the request is known (e.g., "Accept").
+     * @return  the value of the default request property
+     * for the specified key.
+     *
+     * @see java.net.URLConnection#getRequestProperty(java.lang.String)
+     *
+     * @deprecated The instance specific getRequestProperty method
+     * should be used after an appropriate instance of URLConnection
+     * is obtained.
+     *
+     * @see #setDefaultRequestProperty(java.lang.String, java.lang.String)
+     */
+    @Deprecated
+    public static String getDefaultRequestProperty(String key) {
+        return null;
+    }
+
+    /**
+     * The ContentHandler factory.
+     */
+    static ContentHandlerFactory factory;
+
+    /**
+     * Sets the {@code ContentHandlerFactory} of an
+     * application. It can be called at most once by an application.
+     * <p>
+     * The {@code ContentHandlerFactory} instance is used to
+     * construct a content handler from a content type
+     * <p>
+     * If there is a security manager, this method first calls
+     * the security manager's {@code checkSetFactory} method
+     * to ensure the operation is allowed.
+     * This could result in a SecurityException.
+     *
+     * @param      fac   the desired factory.
+     * @exception  Error  if the factory has already been defined.
+     * @exception  SecurityException  if a security manager exists and its
+     *             {@code checkSetFactory} method doesn't allow the operation.
+     * @see        java.net.ContentHandlerFactory
+     * @see        java.net.URLConnection#getContent()
+     * @see        SecurityManager#checkSetFactory
+     */
+    public static synchronized void setContentHandlerFactory(ContentHandlerFactory fac) {
+        if (factory != null) {
+            throw new Error("factory already defined");
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            security.checkSetFactory();
+        }
+        factory = fac;
+    }
+
+    private static Hashtable<String, ContentHandler> handlers = new Hashtable<>();
+
+    /**
+     * Gets the Content Handler appropriate for this connection.
+     */
+    synchronized ContentHandler getContentHandler()
+        throws IOException
+    {
+        String contentType = stripOffParameters(getContentType());
+        ContentHandler handler = null;
+        // BEGIN Android-changed: App Compat. Android guesses content type from name and stream.
+        if (contentType == null) {
+            if ((contentType = guessContentTypeFromName(url.getFile())) == null) {
+                contentType = guessContentTypeFromStream(getInputStream());
+            }
+        }
+
+        if (contentType == null) {
+            return UnknownContentHandler.INSTANCE;
+        }
+        // END Android-changed: App Compat. Android guesses content type from name and stream.
+        try {
+            handler = handlers.get(contentType);
+            if (handler != null)
+                return handler;
+        } catch(Exception e) {
+        }
+
+        if (factory != null)
+            handler = factory.createContentHandler(contentType);
+        if (handler == null) {
+            try {
+                handler = lookupContentHandlerClassFor(contentType);
+            } catch(Exception e) {
+                e.printStackTrace();
+                handler = UnknownContentHandler.INSTANCE;
+            }
+            handlers.put(contentType, handler);
+        }
+        return handler;
+    }
+
+    /*
+     * Media types are in the format: type/subtype*(; parameter).
+     * For looking up the content handler, we should ignore those
+     * parameters.
+     */
+    private String stripOffParameters(String contentType)
+    {
+        if (contentType == null)
+            return null;
+        int index = contentType.indexOf(';');
+
+        if (index > 0)
+            return contentType.substring(0, index);
+        else
+            return contentType;
+    }
+
+    private static final String contentClassPrefix = "sun.net.www.content";
+    private static final String contentPathProp = "java.content.handler.pkgs";
+
+    /**
+     * Looks for a content handler in a user-defineable set of places.
+     * By default it looks in sun.net.www.content, but users can define a
+     * vertical-bar delimited set of class prefixes to search through in
+     * addition by defining the java.content.handler.pkgs property.
+     * The class name must be of the form:
+     * <pre>
+     *     {package-prefix}.{major}.{minor}
+     * e.g.
+     *     YoyoDyne.experimental.text.plain
+     * </pre>
+     */
+    private ContentHandler lookupContentHandlerClassFor(String contentType)
+        throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+        String contentHandlerClassName = typeToPackageName(contentType);
+
+        String contentHandlerPkgPrefixes =getContentHandlerPkgPrefixes();
+
+        StringTokenizer packagePrefixIter =
+            new StringTokenizer(contentHandlerPkgPrefixes, "|");
+
+        while (packagePrefixIter.hasMoreTokens()) {
+            String packagePrefix = packagePrefixIter.nextToken().trim();
+
+            try {
+                String clsName = packagePrefix + "." + contentHandlerClassName;
+                Class<?> cls = null;
+                try {
+                    cls = Class.forName(clsName);
+                } catch (ClassNotFoundException e) {
+                    ClassLoader cl = ClassLoader.getSystemClassLoader();
+                    if (cl != null) {
+                        cls = cl.loadClass(clsName);
+                    }
+                }
+                if (cls != null) {
+                    ContentHandler handler =
+                        (ContentHandler)cls.newInstance();
+                    return handler;
+                }
+            } catch(Exception e) {
+            }
+        }
+
+        return UnknownContentHandler.INSTANCE;
+    }
+
+    /**
+     * Utility function to map a MIME content type into an equivalent
+     * pair of class name components.  For example: "text/html" would
+     * be returned as "text.html"
+     */
+    private String typeToPackageName(String contentType) {
+        // make sure we canonicalize the class name: all lower case
+        contentType = contentType.toLowerCase();
+        int len = contentType.length();
+        char nm[] = new char[len];
+        contentType.getChars(0, len, nm, 0);
+        for (int i = 0; i < len; i++) {
+            char c = nm[i];
+            if (c == '/') {
+                nm[i] = '.';
+            } else if (!('A' <= c && c <= 'Z' ||
+                       'a' <= c && c <= 'z' ||
+                       '0' <= c && c <= '9')) {
+                nm[i] = '_';
+            }
+        }
+        return new String(nm);
+    }
+
+
+    /**
+     * Returns a vertical bar separated list of package prefixes for potential
+     * content handlers.  Tries to get the java.content.handler.pkgs property
+     * to use as a set of package prefixes to search.  Whether or not
+     * that property has been defined, the sun.net.www.content is always
+     * the last one on the returned package list.
+     */
+    private String getContentHandlerPkgPrefixes() {
+        String packagePrefixList = AccessController.doPrivileged(
+            new sun.security.action.GetPropertyAction(contentPathProp, ""));
+
+        if (packagePrefixList != "") {
+            packagePrefixList += "|";
+        }
+
+        return packagePrefixList + contentClassPrefix;
+    }
+
+    /**
+     * Tries to determine the content type of an object, based
+     * on the specified "file" component of a URL.
+     * This is a convenience method that can be used by
+     * subclasses that override the {@code getContentType} method.
+     *
+     * @param   fname   a filename.
+     * @return  a guess as to what the content type of the object is,
+     *          based upon its file name.
+     * @see     java.net.URLConnection#getContentType()
+     */
+    public static String guessContentTypeFromName(String fname) {
+        return getFileNameMap().getContentTypeFor(fname);
+    }
+
+    /**
+     * Tries to determine the type of an input stream based on the
+     * characters at the beginning of the input stream. This method can
+     * be used by subclasses that override the
+     * {@code getContentType} method.
+     * <p>
+     * Ideally, this routine would not be needed. But many
+     * {@code http} servers return the incorrect content type; in
+     * addition, there are many nonstandard extensions. Direct inspection
+     * of the bytes to determine the content type is often more accurate
+     * than believing the content type claimed by the {@code http} server.
+     *
+     * @param      is   an input stream that supports marks.
+     * @return     a guess at the content type, or {@code null} if none
+     *             can be determined.
+     * @exception  IOException  if an I/O error occurs while reading the
+     *               input stream.
+     * @see        java.io.InputStream#mark(int)
+     * @see        java.io.InputStream#markSupported()
+     * @see        java.net.URLConnection#getContentType()
+     */
+    static public String guessContentTypeFromStream(InputStream is)
+                        throws IOException {
+        // If we can't read ahead safely, just give up on guessing
+        if (!is.markSupported())
+            return null;
+
+        is.mark(16);
+        int c1 = is.read();
+        int c2 = is.read();
+        int c3 = is.read();
+        int c4 = is.read();
+        int c5 = is.read();
+        int c6 = is.read();
+        int c7 = is.read();
+        int c8 = is.read();
+        int c9 = is.read();
+        int c10 = is.read();
+        int c11 = is.read();
+        int c12 = is.read();
+        int c13 = is.read();
+        int c14 = is.read();
+        int c15 = is.read();
+        int c16 = is.read();
+        is.reset();
+
+        if (c1 == 0xCA && c2 == 0xFE && c3 == 0xBA && c4 == 0xBE) {
+            return "application/java-vm";
+        }
+
+        if (c1 == 0xAC && c2 == 0xED) {
+            // next two bytes are version number, currently 0x00 0x05
+            return "application/x-java-serialized-object";
+        }
+
+        if (c1 == '<') {
+            if (c2 == '!'
+                || ((c2 == 'h' && (c3 == 't' && c4 == 'm' && c5 == 'l' ||
+                                   c3 == 'e' && c4 == 'a' && c5 == 'd') ||
+                (c2 == 'b' && c3 == 'o' && c4 == 'd' && c5 == 'y'))) ||
+                ((c2 == 'H' && (c3 == 'T' && c4 == 'M' && c5 == 'L' ||
+                                c3 == 'E' && c4 == 'A' && c5 == 'D') ||
+                (c2 == 'B' && c3 == 'O' && c4 == 'D' && c5 == 'Y')))) {
+                return "text/html";
+            }
+
+            if (c2 == '?' && c3 == 'x' && c4 == 'm' && c5 == 'l' && c6 == ' ') {
+                return "application/xml";
+            }
+        }
+
+        // big and little (identical) endian UTF-8 encodings, with BOM
+        if (c1 == 0xef &&  c2 == 0xbb &&  c3 == 0xbf) {
+            if (c4 == '<' &&  c5 == '?' &&  c6 == 'x') {
+                return "application/xml";
+            }
+        }
+
+        // big and little endian UTF-16 encodings, with byte order mark
+        if (c1 == 0xfe && c2 == 0xff) {
+            if (c3 == 0 && c4 == '<' && c5 == 0 && c6 == '?' &&
+                c7 == 0 && c8 == 'x') {
+                return "application/xml";
+            }
+        }
+
+        if (c1 == 0xff && c2 == 0xfe) {
+            if (c3 == '<' && c4 == 0 && c5 == '?' && c6 == 0 &&
+                c7 == 'x' && c8 == 0) {
+                return "application/xml";
+            }
+        }
+
+        // big and little endian UTF-32 encodings, with BOM
+        if (c1 == 0x00 &&  c2 == 0x00 &&  c3 == 0xfe &&  c4 == 0xff) {
+            if (c5  == 0 && c6  == 0 && c7  == 0 && c8  == '<' &&
+                c9  == 0 && c10 == 0 && c11 == 0 && c12 == '?' &&
+                c13 == 0 && c14 == 0 && c15 == 0 && c16 == 'x') {
+                return "application/xml";
+            }
+        }
+
+        if (c1 == 0xff &&  c2 == 0xfe &&  c3 == 0x00 &&  c4 == 0x00) {
+            if (c5  == '<' && c6  == 0 && c7  == 0 && c8  == 0 &&
+                c9  == '?' && c10 == 0 && c11 == 0 && c12 == 0 &&
+                c13 == 'x' && c14 == 0 && c15 == 0 && c16 == 0) {
+                return "application/xml";
+            }
+        }
+
+        if (c1 == 'G' && c2 == 'I' && c3 == 'F' && c4 == '8') {
+            return "image/gif";
+        }
+
+        if (c1 == '#' && c2 == 'd' && c3 == 'e' && c4 == 'f') {
+            return "image/x-bitmap";
+        }
+
+        if (c1 == '!' && c2 == ' ' && c3 == 'X' && c4 == 'P' &&
+                        c5 == 'M' && c6 == '2') {
+            return "image/x-pixmap";
+        }
+
+        if (c1 == 137 && c2 == 80 && c3 == 78 &&
+                c4 == 71 && c5 == 13 && c6 == 10 &&
+                c7 == 26 && c8 == 10) {
+            return "image/png";
+        }
+
+        if (c1 == 0xFF && c2 == 0xD8 && c3 == 0xFF) {
+            if (c4 == 0xE0 || c4 == 0xEE) {
+                return "image/jpeg";
+            }
+
+            /**
+             * File format used by digital cameras to store images.
+             * Exif Format can be read by any application supporting
+             * JPEG. Exif Spec can be found at:
+             * http://www.pima.net/standards/it10/PIMA15740/Exif_2-1.PDF
+             */
+            if ((c4 == 0xE1) &&
+                (c7 == 'E' && c8 == 'x' && c9 == 'i' && c10 =='f' &&
+                 c11 == 0)) {
+                return "image/jpeg";
+            }
+        }
+
+        if (c1 == 0xD0 && c2 == 0xCF && c3 == 0x11 && c4 == 0xE0 &&
+            c5 == 0xA1 && c6 == 0xB1 && c7 == 0x1A && c8 == 0xE1) {
+
+            /* Above is signature of Microsoft Structured Storage.
+             * Below this, could have tests for various SS entities.
+             * For now, just test for FlashPix.
+             */
+            if (checkfpx(is)) {
+                return "image/vnd.fpx";
+            }
+        }
+
+        if (c1 == 0x2E && c2 == 0x73 && c3 == 0x6E && c4 == 0x64) {
+            return "audio/basic";  // .au format, big endian
+        }
+
+        if (c1 == 0x64 && c2 == 0x6E && c3 == 0x73 && c4 == 0x2E) {
+            return "audio/basic";  // .au format, little endian
+        }
+
+        if (c1 == 'R' && c2 == 'I' && c3 == 'F' && c4 == 'F') {
+            /* I don't know if this is official but evidence
+             * suggests that .wav files start with "RIFF" - brown
+             */
+            return "audio/x-wav";
+        }
+        return null;
+    }
+
+    /**
+     * Check for FlashPix image data in InputStream is.  Return true if
+     * the stream has FlashPix data, false otherwise.  Before calling this
+     * method, the stream should have already been checked to be sure it
+     * contains Microsoft Structured Storage data.
+     */
+    static private boolean checkfpx(InputStream is) throws IOException {
+
+        /* Test for FlashPix image data in Microsoft Structured Storage format.
+         * In general, should do this with calls to an SS implementation.
+         * Lacking that, need to dig via offsets to get to the FlashPix
+         * ClassID.  Details:
+         *
+         * Offset to Fpx ClsID from beginning of stream should be:
+         *
+         * FpxClsidOffset = rootEntryOffset + clsidOffset
+         *
+         * where: clsidOffset = 0x50.
+         *        rootEntryOffset = headerSize + sectorSize*sectDirStart
+         *                          + 128*rootEntryDirectory
+         *
+         *        where:  headerSize = 0x200 (always)
+         *                sectorSize = 2 raised to power of uSectorShift,
+         *                             which is found in the header at
+         *                             offset 0x1E.
+         *                sectDirStart = found in the header at offset 0x30.
+         *                rootEntryDirectory = in general, should search for
+         *                                     directory labelled as root.
+         *                                     We will assume value of 0 (i.e.,
+         *                                     rootEntry is in first directory)
+         */
+
+        // Mark the stream so we can reset it. 0x100 is enough for the first
+        // few reads, but the mark will have to be reset and set again once
+        // the offset to the root directory entry is computed. That offset
+        // can be very large and isn't know until the stream has been read from
+        is.mark(0x100);
+
+        // Get the byte ordering located at 0x1E. 0xFE is Intel,
+        // 0xFF is other
+        long toSkip = (long)0x1C;
+        long posn;
+
+        if ((posn = skipForward(is, toSkip)) < toSkip) {
+          is.reset();
+          return false;
+        }
+
+        int c[] = new int[16];
+        if (readBytes(c, 2, is) < 0) {
+            is.reset();
+            return false;
+        }
+
+        int byteOrder = c[0];
+
+        posn+=2;
+        int uSectorShift;
+        if (readBytes(c, 2, is) < 0) {
+            is.reset();
+            return false;
+        }
+
+        if(byteOrder == 0xFE) {
+            uSectorShift = c[0];
+            uSectorShift += c[1] << 8;
+        }
+        else {
+            uSectorShift = c[0] << 8;
+            uSectorShift += c[1];
+        }
+
+        posn += 2;
+        toSkip = (long)0x30 - posn;
+        long skipped = 0;
+        if ((skipped = skipForward(is, toSkip)) < toSkip) {
+          is.reset();
+          return false;
+        }
+        posn += skipped;
+
+        if (readBytes(c, 4, is) < 0) {
+            is.reset();
+            return false;
+        }
+
+        int sectDirStart;
+        if(byteOrder == 0xFE) {
+            sectDirStart = c[0];
+            sectDirStart += c[1] << 8;
+            sectDirStart += c[2] << 16;
+            sectDirStart += c[3] << 24;
+        } else {
+            sectDirStart =  c[0] << 24;
+            sectDirStart += c[1] << 16;
+            sectDirStart += c[2] << 8;
+            sectDirStart += c[3];
+        }
+        posn += 4;
+        is.reset(); // Reset back to the beginning
+
+        toSkip = 0x200L + (long)(1<<uSectorShift)*sectDirStart + 0x50L;
+
+        // Sanity check!
+        if (toSkip < 0) {
+            return false;
+        }
+
+        /*
+         * How far can we skip? Is there any performance problem here?
+         * This skip can be fairly long, at least 0x4c650 in at least
+         * one case. Have to assume that the skip will fit in an int.
+         * Leave room to read whole root dir
+         */
+        is.mark((int)toSkip+0x30);
+
+        if ((skipForward(is, toSkip)) < toSkip) {
+            is.reset();
+            return false;
+        }
+
+        /* should be at beginning of ClassID, which is as follows
+         * (in Intel byte order):
+         *    00 67 61 56 54 C1 CE 11 85 53 00 AA 00 A1 F9 5B
+         *
+         * This is stored from Windows as long,short,short,char[8]
+         * so for byte order changes, the order only changes for
+         * the first 8 bytes in the ClassID.
+         *
+         * Test against this, ignoring second byte (Intel) since
+         * this could change depending on part of Fpx file we have.
+         */
+
+        if (readBytes(c, 16, is) < 0) {
+            is.reset();
+            return false;
+        }
+
+        // intel byte order
+        if (byteOrder == 0xFE &&
+            c[0] == 0x00 && c[2] == 0x61 && c[3] == 0x56 &&
+            c[4] == 0x54 && c[5] == 0xC1 && c[6] == 0xCE &&
+            c[7] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
+            c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
+            c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
+            is.reset();
+            return true;
+        }
+
+        // non-intel byte order
+        else if (c[3] == 0x00 && c[1] == 0x61 && c[0] == 0x56 &&
+            c[5] == 0x54 && c[4] == 0xC1 && c[7] == 0xCE &&
+            c[6] == 0x11 && c[8] == 0x85 && c[9] == 0x53 &&
+            c[10]== 0x00 && c[11]== 0xAA && c[12]== 0x00 &&
+            c[13]== 0xA1 && c[14]== 0xF9 && c[15]== 0x5B) {
+            is.reset();
+            return true;
+        }
+        is.reset();
+        return false;
+    }
+
+    /**
+     * Tries to read the specified number of bytes from the stream
+     * Returns -1, If EOF is reached before len bytes are read, returns 0
+     * otherwise
+     */
+    static private int readBytes(int c[], int len, InputStream is)
+                throws IOException {
+
+        byte buf[] = new byte[len];
+        if (is.read(buf, 0, len) < len) {
+            return -1;
+        }
+
+        // fill the passed in int array
+        for (int i = 0; i < len; i++) {
+             c[i] = buf[i] & 0xff;
+        }
+        return 0;
+    }
+
+
+    /**
+     * Skips through the specified number of bytes from the stream
+     * until either EOF is reached, or the specified
+     * number of bytes have been skipped
+     */
+    static private long skipForward(InputStream is, long toSkip)
+                throws IOException {
+
+        long eachSkip = 0;
+        long skipped = 0;
+
+        while (skipped != toSkip) {
+            eachSkip = is.skip(toSkip - skipped);
+
+            // check if EOF is reached
+            if (eachSkip <= 0) {
+                if (is.read() == -1) {
+                    return skipped ;
+                } else {
+                    skipped++;
+                }
+            }
+            skipped += eachSkip;
+        }
+        return skipped;
+    }
+
+}
+
+
+class UnknownContentHandler extends ContentHandler {
+    static final ContentHandler INSTANCE = new UnknownContentHandler();
+
+    public Object getContent(URLConnection uc) throws IOException {
+        return uc.getInputStream();
+    }
+}
diff --git a/java/net/URLDecoder.java b/java/net/URLDecoder.java
new file mode 100644
index 0000000..8b14eb8
--- /dev/null
+++ b/java/net/URLDecoder.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.*;
+
+/**
+ * Utility class for HTML form decoding. This class contains static methods
+ * for decoding a String from the <CODE>application/x-www-form-urlencoded</CODE>
+ * MIME format.
+ * <p>
+ * The conversion process is the reverse of that used by the URLEncoder class. It is assumed
+ * that all characters in the encoded string are one of the following:
+ * &quot;{@code a}&quot; through &quot;{@code z}&quot;,
+ * &quot;{@code A}&quot; through &quot;{@code Z}&quot;,
+ * &quot;{@code 0}&quot; through &quot;{@code 9}&quot;, and
+ * &quot;{@code -}&quot;, &quot;{@code _}&quot;,
+ * &quot;{@code .}&quot;, and &quot;{@code *}&quot;. The
+ * character &quot;{@code %}&quot; is allowed but is interpreted
+ * as the start of a special escaped sequence.
+ * <p>
+ * The following rules are applied in the conversion:
+ *
+ * <ul>
+ * <li>The alphanumeric characters &quot;{@code a}&quot; through
+ *     &quot;{@code z}&quot;, &quot;{@code A}&quot; through
+ *     &quot;{@code Z}&quot; and &quot;{@code 0}&quot;
+ *     through &quot;{@code 9}&quot; remain the same.
+ * <li>The special characters &quot;{@code .}&quot;,
+ *     &quot;{@code -}&quot;, &quot;{@code *}&quot;, and
+ *     &quot;{@code _}&quot; remain the same.
+ * <li>The plus sign &quot;{@code +}&quot; is converted into a
+ *     space character &quot; &nbsp; &quot; .
+ * <li>A sequence of the form "<i>{@code %xy}</i>" will be
+ *     treated as representing a byte where <i>xy</i> is the two-digit
+ *     hexadecimal representation of the 8 bits. Then, all substrings
+ *     that contain one or more of these byte sequences consecutively
+ *     will be replaced by the character(s) whose encoding would result
+ *     in those consecutive bytes.
+ *     The encoding scheme used to decode these characters may be specified,
+ *     or if unspecified, the default encoding of the platform will be used.
+ * </ul>
+ * <p>
+ * There are two possible ways in which this decoder could deal with
+ * illegal strings.  It could either leave illegal characters alone or
+ * it could throw an {@link java.lang.IllegalArgumentException}.
+ * Which approach the decoder takes is left to the
+ * implementation.
+ *
+ * @author  Mark Chamness
+ * @author  Michael McCloskey
+ * @since   1.2
+ */
+
+public class URLDecoder {
+
+    // The platform default encoding
+    static String dfltEncName = URLEncoder.dfltEncName;
+
+    /**
+     * Decodes a {@code x-www-form-urlencoded} string.
+     * The platform's default encoding is used to determine what characters
+     * are represented by any consecutive sequences of the form
+     * "<i>{@code %xy}</i>".
+     * @param s the {@code String} to decode
+     * @deprecated The resulting string may vary depending on the platform's
+     *          default encoding. Instead, use the decode(String,String) method
+     *          to specify the encoding.
+     * @return the newly decoded {@code String}
+     */
+    @Deprecated
+    public static String decode(String s) {
+
+        String str = null;
+
+        try {
+            str = decode(s, dfltEncName);
+        } catch (UnsupportedEncodingException e) {
+            // The system should always have the platform default
+        }
+
+        return str;
+    }
+
+    /**
+     * Decodes a {@code application/x-www-form-urlencoded} string using a specific
+     * encoding scheme.
+     * The supplied encoding is used to determine
+     * what characters are represented by any consecutive sequences of the
+     * form "<i>{@code %xy}</i>".
+     * <p>
+     * <em><strong>Note:</strong> The <a href=
+     * "http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">
+     * World Wide Web Consortium Recommendation</a> states that
+     * UTF-8 should be used. Not doing so may introduce
+     * incompatibilities.</em>
+     *
+     * @param s the {@code String} to decode
+     * @param enc   The name of a supported
+     *    <a href="../lang/package-summary.html#charenc">character
+     *    encoding</a>.
+     * @return the newly decoded {@code String}
+     * @exception  UnsupportedEncodingException
+     *             If character encoding needs to be consulted, but
+     *             named character encoding is not supported
+     * @see URLEncoder#encode(java.lang.String, java.lang.String)
+     * @since 1.4
+     */
+    public static String decode(String s, String enc)
+        throws UnsupportedEncodingException{
+
+        boolean needToChange = false;
+        int numChars = s.length();
+        StringBuffer sb = new StringBuffer(numChars > 500 ? numChars / 2 : numChars);
+        int i = 0;
+
+        if (enc.length() == 0) {
+            throw new UnsupportedEncodingException ("URLDecoder: empty string enc parameter");
+        }
+
+        char c;
+        byte[] bytes = null;
+        while (i < numChars) {
+            c = s.charAt(i);
+            switch (c) {
+            case '+':
+                sb.append(' ');
+                i++;
+                needToChange = true;
+                break;
+            case '%':
+                /*
+                 * Starting with this instance of %, process all
+                 * consecutive substrings of the form %xy. Each
+                 * substring %xy will yield a byte. Convert all
+                 * consecutive  bytes obtained this way to whatever
+                 * character(s) they represent in the provided
+                 * encoding.
+                 */
+
+                try {
+
+                    // (numChars-i)/3 is an upper bound for the number
+                    // of remaining bytes
+                    if (bytes == null)
+                        bytes = new byte[(numChars-i)/3];
+                    int pos = 0;
+
+                    while ( ((i+2) < numChars) &&
+                            (c=='%')) {
+                        // BEGIN Android-changed: App compat. Forbid non-hex chars after '%'.
+                        if (!isValidHexChar(s.charAt(i+1)) || !isValidHexChar(s.charAt(i+2))) {
+                            throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern : "
+                                    + s.substring(i, i + 3));
+                        }
+                        // END Android-changed: App compat. Forbid non-hex chars after '%'.
+                        int v = Integer.parseInt(s.substring(i+1,i+3),16);
+                        if (v < 0)
+                            // Android-changed: Improve error message by printing the string value.
+                            throw new IllegalArgumentException("URLDecoder: Illegal hex characters in escape (%) pattern - negative value : "
+                                    + s.substring(i, i + 3));
+                        bytes[pos++] = (byte) v;
+                        i+= 3;
+                        if (i < numChars)
+                            c = s.charAt(i);
+                    }
+
+                    // A trailing, incomplete byte encoding such as
+                    // "%x" will cause an exception to be thrown
+
+                    if ((i < numChars) && (c=='%'))
+                        throw new IllegalArgumentException(
+                         "URLDecoder: Incomplete trailing escape (%) pattern");
+
+                    sb.append(new String(bytes, 0, pos, enc));
+                } catch (NumberFormatException e) {
+                    throw new IllegalArgumentException(
+                    "URLDecoder: Illegal hex characters in escape (%) pattern - "
+                    + e.getMessage());
+                }
+                needToChange = true;
+                break;
+            default:
+                sb.append(c);
+                i++;
+                break;
+            }
+        }
+
+        return (needToChange? sb.toString() : s);
+    }
+
+    // BEGIN Android-added: App compat. Forbid non-hex chars after '%'.
+    private static boolean isValidHexChar(char c) {
+        return ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F');
+    }
+    // END Android-added: App compat. Forbid non-hex chars after '%'.
+}
diff --git a/java/net/URLEncoder.java b/java/net/URLEncoder.java
new file mode 100644
index 0000000..86377b7
--- /dev/null
+++ b/java/net/URLEncoder.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.ByteArrayOutputStream;
+import java.io.BufferedWriter;
+import java.io.OutputStreamWriter;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.io.CharArrayWriter;
+import java.nio.charset.Charset;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException ;
+import java.util.BitSet;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import sun.security.action.GetBooleanAction;
+import sun.security.action.GetPropertyAction;
+
+/**
+ * Utility class for HTML form encoding. This class contains static methods
+ * for converting a String to the <CODE>application/x-www-form-urlencoded</CODE> MIME
+ * format. For more information about HTML form encoding, consult the HTML
+ * <A HREF="http://www.w3.org/TR/html4/">specification</A>.
+ *
+ * <p>
+ * When encoding a String, the following rules apply:
+ *
+ * <ul>
+ * <li>The alphanumeric characters &quot;{@code a}&quot; through
+ *     &quot;{@code z}&quot;, &quot;{@code A}&quot; through
+ *     &quot;{@code Z}&quot; and &quot;{@code 0}&quot;
+ *     through &quot;{@code 9}&quot; remain the same.
+ * <li>The special characters &quot;{@code .}&quot;,
+ *     &quot;{@code -}&quot;, &quot;{@code *}&quot;, and
+ *     &quot;{@code _}&quot; remain the same.
+ * <li>The space character &quot; &nbsp; &quot; is
+ *     converted into a plus sign &quot;{@code +}&quot;.
+ * <li>All other characters are unsafe and are first converted into
+ *     one or more bytes using some encoding scheme. Then each byte is
+ *     represented by the 3-character string
+ *     &quot;<i>{@code %xy}</i>&quot;, where <i>xy</i> is the
+ *     two-digit hexadecimal representation of the byte.
+ *     The recommended encoding scheme to use is UTF-8. However,
+ *     for compatibility reasons, if an encoding is not specified,
+ *     then the default encoding of the platform is used.
+ * </ul>
+ *
+ * <p>
+ * For example using UTF-8 as the encoding scheme the string &quot;The
+ * string &#252;@foo-bar&quot; would get converted to
+ * &quot;The+string+%C3%BC%40foo-bar&quot; because in UTF-8 the character
+ * &#252; is encoded as two bytes C3 (hex) and BC (hex), and the
+ * character @ is encoded as one byte 40 (hex).
+ *
+ * @author  Herb Jellinek
+ * @since   JDK1.0
+ */
+public class URLEncoder {
+    static BitSet dontNeedEncoding;
+    static final int caseDiff = ('a' - 'A');
+    static String dfltEncName = null;
+
+    static {
+
+        /* The list of characters that are not encoded has been
+         * determined as follows:
+         *
+         * RFC 2396 states:
+         * -----
+         * Data characters that are allowed in a URI but do not have a
+         * reserved purpose are called unreserved.  These include upper
+         * and lower case letters, decimal digits, and a limited set of
+         * punctuation marks and symbols.
+         *
+         * unreserved  = alphanum | mark
+         *
+         * mark        = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+         *
+         * Unreserved characters can be escaped without changing the
+         * semantics of the URI, but this should not be done unless the
+         * URI is being used in a context that does not allow the
+         * unescaped character to appear.
+         * -----
+         *
+         * It appears that both Netscape and Internet Explorer escape
+         * all special characters from this list with the exception
+         * of "-", "_", ".", "*". While it is not clear why they are
+         * escaping the other characters, perhaps it is safest to
+         * assume that there might be contexts in which the others
+         * are unsafe if not escaped. Therefore, we will use the same
+         * list. It is also noteworthy that this is consistent with
+         * O'Reilly's "HTML: The Definitive Guide" (page 164).
+         *
+         * As a last note, Intenet Explorer does not encode the "@"
+         * character which is clearly not unreserved according to the
+         * RFC. We are being consistent with the RFC in this matter,
+         * as is Netscape.
+         *
+         */
+
+        dontNeedEncoding = new BitSet(256);
+        int i;
+        for (i = 'a'; i <= 'z'; i++) {
+            dontNeedEncoding.set(i);
+        }
+        for (i = 'A'; i <= 'Z'; i++) {
+            dontNeedEncoding.set(i);
+        }
+        for (i = '0'; i <= '9'; i++) {
+            dontNeedEncoding.set(i);
+        }
+        dontNeedEncoding.set(' '); /* encoding a space to a + is done
+                                    * in the encode() method */
+        dontNeedEncoding.set('-');
+        dontNeedEncoding.set('_');
+        dontNeedEncoding.set('.');
+        dontNeedEncoding.set('*');
+
+        dfltEncName = AccessController.doPrivileged(
+            new GetPropertyAction("file.encoding")
+        );
+    }
+
+    /**
+     * You can't call the constructor.
+     */
+    private URLEncoder() { }
+
+    /**
+     * Translates a string into {@code x-www-form-urlencoded}
+     * format. This method uses the platform's default encoding
+     * as the encoding scheme to obtain the bytes for unsafe characters.
+     *
+     * @param   s   {@code String} to be translated.
+     * @deprecated The resulting string may vary depending on the platform's
+     *             default encoding. Instead, use the encode(String,String)
+     *             method to specify the encoding.
+     * @return  the translated {@code String}.
+     */
+    @Deprecated
+    public static String encode(String s) {
+
+        String str = null;
+
+        try {
+            str = encode(s, dfltEncName);
+        } catch (UnsupportedEncodingException e) {
+            // The system should always have the platform default
+        }
+
+        return str;
+    }
+
+    /**
+     * Translates a string into {@code application/x-www-form-urlencoded}
+     * format using a specific encoding scheme. This method uses the
+     * supplied encoding scheme to obtain the bytes for unsafe
+     * characters.
+     * <p>
+     * <em><strong>Note:</strong> The <a href=
+     * "http://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars">
+     * World Wide Web Consortium Recommendation</a> states that
+     * UTF-8 should be used. Not doing so may introduce
+     * incompatibilities.</em>
+     *
+     * @param   s   {@code String} to be translated.
+     * @param   enc   The name of a supported
+     *    <a href="../lang/package-summary.html#charenc">character
+     *    encoding</a>.
+     * @return  the translated {@code String}.
+     * @exception  UnsupportedEncodingException
+     *             If the named encoding is not supported
+     * @see URLDecoder#decode(java.lang.String, java.lang.String)
+     * @since 1.4
+     */
+    public static String encode(String s, String enc)
+        throws UnsupportedEncodingException {
+
+        boolean needToChange = false;
+        StringBuffer out = new StringBuffer(s.length());
+        Charset charset;
+        CharArrayWriter charArrayWriter = new CharArrayWriter();
+
+        if (enc == null)
+            throw new NullPointerException("charsetName");
+
+        try {
+            charset = Charset.forName(enc);
+        } catch (IllegalCharsetNameException e) {
+            throw new UnsupportedEncodingException(enc);
+        } catch (UnsupportedCharsetException e) {
+            throw new UnsupportedEncodingException(enc);
+        }
+
+        for (int i = 0; i < s.length();) {
+            int c = (int) s.charAt(i);
+            //System.out.println("Examining character: " + c);
+            if (dontNeedEncoding.get(c)) {
+                if (c == ' ') {
+                    c = '+';
+                    needToChange = true;
+                }
+                //System.out.println("Storing: " + c);
+                out.append((char)c);
+                i++;
+            } else {
+                // convert to external encoding before hex conversion
+                do {
+                    charArrayWriter.write(c);
+                    /*
+                     * If this character represents the start of a Unicode
+                     * surrogate pair, then pass in two characters. It's not
+                     * clear what should be done if a bytes reserved in the
+                     * surrogate pairs range occurs outside of a legal
+                     * surrogate pair. For now, just treat it as if it were
+                     * any other character.
+                     */
+                    if (c >= 0xD800 && c <= 0xDBFF) {
+                        /*
+                          System.out.println(Integer.toHexString(c)
+                          + " is high surrogate");
+                        */
+                        if ( (i+1) < s.length()) {
+                            int d = (int) s.charAt(i+1);
+                            /*
+                              System.out.println("\tExamining "
+                              + Integer.toHexString(d));
+                            */
+                            if (d >= 0xDC00 && d <= 0xDFFF) {
+                                /*
+                                  System.out.println("\t"
+                                  + Integer.toHexString(d)
+                                  + " is low surrogate");
+                                */
+                                charArrayWriter.write(d);
+                                i++;
+                            }
+                        }
+                    }
+                    i++;
+                } while (i < s.length() && !dontNeedEncoding.get((c = (int) s.charAt(i))));
+
+                charArrayWriter.flush();
+                String str = new String(charArrayWriter.toCharArray());
+                byte[] ba = str.getBytes(charset);
+                for (int j = 0; j < ba.length; j++) {
+                    out.append('%');
+                    char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
+                    // converting to use uppercase letter as part of
+                    // the hex value if ch is a letter.
+                    if (Character.isLetter(ch)) {
+                        ch -= caseDiff;
+                    }
+                    out.append(ch);
+                    ch = Character.forDigit(ba[j] & 0xF, 16);
+                    if (Character.isLetter(ch)) {
+                        ch -= caseDiff;
+                    }
+                    out.append(ch);
+                }
+                charArrayWriter.reset();
+                needToChange = true;
+            }
+        }
+
+        return (needToChange? out.toString() : s);
+    }
+}
diff --git a/java/net/URLStreamHandler.java b/java/net/URLStreamHandler.java
new file mode 100644
index 0000000..dffc6d5
--- /dev/null
+++ b/java/net/URLStreamHandler.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+import java.util.Objects;
+
+import sun.net.util.IPAddressUtil;
+
+/**
+ * The abstract class {@code URLStreamHandler} is the common
+ * superclass for all stream protocol handlers. A stream protocol
+ * handler knows how to make a connection for a particular protocol
+ * type, such as {@code http} or {@code https}.
+ * <p>
+ * In most cases, an instance of a {@code URLStreamHandler}
+ * subclass is not created directly by an application. Rather, the
+ * first time a protocol name is encountered when constructing a
+ * {@code URL}, the appropriate stream protocol handler is
+ * automatically loaded.
+ *
+ * @author  James Gosling
+ * @see     java.net.URL#URL(java.lang.String, java.lang.String, int, java.lang.String)
+ * @since   JDK1.0
+ */
+public abstract class URLStreamHandler {
+    /**
+     * Opens a connection to the object referenced by the
+     * {@code URL} argument.
+     * This method should be overridden by a subclass.
+     *
+     * <p>If for the handler's protocol (such as HTTP or JAR), there
+     * exists a public, specialized URLConnection subclass belonging
+     * to one of the following packages or one of their subpackages:
+     * java.lang, java.io, java.util, java.net, the connection
+     * returned will be of that subclass. For example, for HTTP an
+     * HttpURLConnection will be returned, and for JAR a
+     * JarURLConnection will be returned.
+     *
+     * @param      u   the URL that this connects to.
+     * @return     a {@code URLConnection} object for the {@code URL}.
+     * @exception  IOException  if an I/O error occurs while opening the
+     *               connection.
+     */
+    abstract protected URLConnection openConnection(URL u) throws IOException;
+
+    /**
+     * Same as openConnection(URL), except that the connection will be
+     * made through the specified proxy; Protocol handlers that do not
+     * support proxying will ignore the proxy parameter and make a
+     * normal connection.
+     *
+     * Calling this method preempts the system's default ProxySelector
+     * settings.
+     *
+     * @param      u   the URL that this connects to.
+     * @param      p   the proxy through which the connection will be made.
+     *                 If direct connection is desired, Proxy.NO_PROXY
+     *                 should be specified.
+     * @return     a {@code URLConnection} object for the {@code URL}.
+     * @exception  IOException  if an I/O error occurs while opening the
+     *               connection.
+     * @exception  IllegalArgumentException if either u or p is null,
+     *               or p has the wrong type.
+     * @exception  UnsupportedOperationException if the subclass that
+     *               implements the protocol doesn't support this method.
+     * @since      1.5
+     */
+    protected URLConnection openConnection(URL u, Proxy p) throws IOException {
+        throw new UnsupportedOperationException("Method not implemented.");
+    }
+
+    /**
+     * Parses the string representation of a {@code URL} into a
+     * {@code URL} object.
+     * <p>
+     * If there is any inherited context, then it has already been
+     * copied into the {@code URL} argument.
+     * <p>
+     * The {@code parseURL} method of {@code URLStreamHandler}
+     * parses the string representation as if it were an
+     * {@code http} specification. Most URL protocol families have a
+     * similar parsing. A stream protocol handler for a protocol that has
+     * a different syntax must override this routine.
+     *
+     * @param   u       the {@code URL} to receive the result of parsing
+     *                  the spec.
+     * @param   spec    the {@code String} representing the URL that
+     *                  must be parsed.
+     * @param   start   the character index at which to begin parsing. This is
+     *                  just past the '{@code :}' (if there is one) that
+     *                  specifies the determination of the protocol name.
+     * @param   limit   the character position to stop parsing at. This is the
+     *                  end of the string or the position of the
+     *                  "{@code #}" character, if present. All information
+     *                  after the sharp sign indicates an anchor.
+     */
+    protected void parseURL(URL u, String spec, int start, int limit) {
+        // These fields may receive context content if this was relative URL
+        String protocol = u.getProtocol();
+        String authority = u.getAuthority();
+        String userInfo = u.getUserInfo();
+        String host = u.getHost();
+        int port = u.getPort();
+        String path = u.getPath();
+        String query = u.getQuery();
+
+        // This field has already been parsed
+        String ref = u.getRef();
+
+        boolean isRelPath = false;
+        boolean queryOnly = false;
+        // BEGIN Android-changed: App compat
+        boolean querySet = false;
+        // END Android-changed: App compat
+
+// FIX: should not assume query if opaque
+        // Strip off the query part
+        if (start < limit) {
+            int queryStart = spec.indexOf('?');
+            queryOnly = queryStart == start;
+            if ((queryStart != -1) && (queryStart < limit)) {
+                query = spec.substring(queryStart+1, limit);
+                if (limit > queryStart)
+                    limit = queryStart;
+                spec = spec.substring(0, queryStart);
+                // BEGIN Android-changed: App compat
+                querySet = true;
+                // END Android-changed: App compat
+            }
+        }
+
+        int i = 0;
+        // Parse the authority part if any
+        // BEGIN Android-changed: App compat
+        // boolean isUNCName = (start <= limit - 4) &&
+        //                 (spec.charAt(start) == '/') &&
+        //                 (spec.charAt(start + 1) == '/') &&
+        //                 (spec.charAt(start + 2) == '/') &&
+        //                 (spec.charAt(start + 3) == '/');
+        boolean isUNCName = false;
+        // END Android-changed: App compat
+        if (!isUNCName && (start <= limit - 2) && (spec.charAt(start) == '/') &&
+            (spec.charAt(start + 1) == '/')) {
+            start += 2;
+            // BEGIN Android-changed: Check for all hostname termination chars. http://b/110955991
+            /*
+            i = spec.indexOf('/', start);
+            if (i < 0 || i > limit) {
+                i = spec.indexOf('?', start);
+                if (i < 0 || i > limit)
+                    i = limit;
+            }
+            */
+            LOOP: for (i = start; i < limit; i++) {
+                switch (spec.charAt(i)) {
+                    case '/':  // Start of path
+                    case '\\': // Start of path - see https://url.spec.whatwg.org/#host-state
+                    case '?':  // Start of query
+                    case '#':  // Start of fragment
+                        break LOOP;
+                }
+            }
+            // END Android-changed: Check for all hostname termination chars. http://b/110955991
+
+            host = authority = spec.substring(start, i);
+
+            int ind = authority.indexOf('@');
+            if (ind != -1) {
+                if (ind != authority.lastIndexOf('@')) {
+                    // more than one '@' in authority. This is not server based
+                    userInfo = null;
+                    host = null;
+                } else {
+                    userInfo = authority.substring(0, ind);
+                    host = authority.substring(ind+1);
+                }
+            } else {
+                userInfo = null;
+            }
+            if (host != null) {
+                // If the host is surrounded by [ and ] then its an IPv6
+                // literal address as specified in RFC2732
+                if (host.length()>0 && (host.charAt(0) == '[')) {
+                    if ((ind = host.indexOf(']')) > 2) {
+
+                        String nhost = host ;
+                        host = nhost.substring(0,ind+1);
+                        if (!IPAddressUtil.
+                            isIPv6LiteralAddress(host.substring(1, ind))) {
+                            throw new IllegalArgumentException(
+                                "Invalid host: "+ host);
+                        }
+
+                        port = -1 ;
+                        if (nhost.length() > ind+1) {
+                            if (nhost.charAt(ind+1) == ':') {
+                                ++ind ;
+                                // port can be null according to RFC2396
+                                if (nhost.length() > (ind + 1)) {
+                                    port = Integer.parseInt(nhost.substring(ind+1));
+                                }
+                            } else {
+                                throw new IllegalArgumentException(
+                                    "Invalid authority field: " + authority);
+                            }
+                        }
+                    } else {
+                        throw new IllegalArgumentException(
+                            "Invalid authority field: " + authority);
+                    }
+                } else {
+                    ind = host.indexOf(':');
+                    port = -1;
+                    if (ind >= 0) {
+                        // port can be null according to RFC2396
+                        if (host.length() > (ind + 1)) {
+                            // BEGIN Android-changed: App compat
+                            // port = Integer.parseInt(host.substring(ind + 1));
+                            char firstPortChar = host.charAt(ind+1);
+                            if (firstPortChar >= '0' && firstPortChar <= '9') {
+                                port = Integer.parseInt(host.substring(ind + 1));
+                            } else {
+                                throw new IllegalArgumentException("invalid port: " +
+                                                                   host.substring(ind + 1));
+                            }
+                            // END Android-changed: App compat
+                        }
+                        host = host.substring(0, ind);
+                    }
+                }
+            } else {
+                host = "";
+            }
+            if (port < -1)
+                throw new IllegalArgumentException("Invalid port number :" +
+                                                   port);
+            start = i;
+
+            // If the authority is defined then the path is defined by the
+            // spec only; See RFC 2396 Section 5.2.4.
+            // BEGIN Android-changed: App compat
+            // if (authority != null && authority.length() > 0)
+            //   path = "";
+            path = null;
+            if (!querySet) {
+                query = null;
+            }
+            // END Android-changed: App compat
+        }
+
+        if (host == null) {
+            host = "";
+        }
+
+        // Parse the file path if any
+        if (start < limit) {
+            // Android-changed: Check for all hostname termination chars. http://b/110955991
+            // if (spec.charAt(start) == '/') {
+            if (spec.charAt(start) == '/' || spec.charAt(start) == '\\') {
+                path = spec.substring(start, limit);
+            } else if (path != null && path.length() > 0) {
+                isRelPath = true;
+                int ind = path.lastIndexOf('/');
+                String seperator = "";
+                if (ind == -1 && authority != null)
+                    seperator = "/";
+                path = path.substring(0, ind + 1) + seperator +
+                         spec.substring(start, limit);
+
+            } else {
+                String seperator = (authority != null) ? "/" : "";
+                path = seperator + spec.substring(start, limit);
+            }
+        }
+        // BEGIN Android-changed: App compat
+        //else if (queryOnly && path != null) {
+        //    int ind = path.lastIndexOf('/');
+        //    if (ind < 0)
+        //        ind = 0;
+        //    path = path.substring(0, ind) + "/";
+        //}
+        // END Android-changed: App compat
+        if (path == null)
+            path = "";
+
+        // BEGIN Android-changed
+        //if (isRelPath) {
+        if (true) {
+        // END Android-changed
+            // Remove embedded /./
+            while ((i = path.indexOf("/./")) >= 0) {
+                path = path.substring(0, i) + path.substring(i + 2);
+            }
+            // Remove embedded /../ if possible
+            i = 0;
+            while ((i = path.indexOf("/../", i)) >= 0) {
+                // BEGIN Android-changed: App compat
+                /*
+                 * Trailing /../
+                 */
+                if (i == 0) {
+                    path = path.substring(i + 3);
+                    i = 0;
+                // END Android-changed: App compat
+                /*
+                 * A "/../" will cancel the previous segment and itself,
+                 * unless that segment is a "/../" itself
+                 * i.e. "/a/b/../c" becomes "/a/c"
+                 * but "/../../a" should stay unchanged
+                 */
+                // Android-changed: App compat
+                // if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
+                } else if (i > 0 && (limit = path.lastIndexOf('/', i - 1)) >= 0 &&
+                    (path.indexOf("/../", limit) != 0)) {
+                    path = path.substring(0, limit) + path.substring(i + 3);
+                    i = 0;
+                } else {
+                    i = i + 3;
+                }
+            }
+            // Remove trailing .. if possible
+            while (path.endsWith("/..")) {
+                i = path.indexOf("/..");
+                if ((limit = path.lastIndexOf('/', i - 1)) >= 0) {
+                    path = path.substring(0, limit+1);
+                } else {
+                    break;
+                }
+            }
+            // Remove starting .
+            if (path.startsWith("./") && path.length() > 2)
+                path = path.substring(2);
+
+            // Remove trailing .
+            if (path.endsWith("/."))
+                path = path.substring(0, path.length() -1);
+
+            // Android-changed: App compat: Remove trailing ?
+            if (path.endsWith("?"))
+                path = path.substring(0, path.length() -1);
+        }
+
+        setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
+    }
+
+    /**
+     * Returns the default port for a URL parsed by this handler. This method
+     * is meant to be overidden by handlers with default port numbers.
+     * @return the default port for a {@code URL} parsed by this handler.
+     * @since 1.3
+     */
+    protected int getDefaultPort() {
+        return -1;
+    }
+
+    /**
+     * Provides the default equals calculation. May be overidden by handlers
+     * for other protocols that have different requirements for equals().
+     * This method requires that none of its arguments is null. This is
+     * guaranteed by the fact that it is only called by java.net.URL class.
+     * @param u1 a URL object
+     * @param u2 a URL object
+     * @return {@code true} if the two urls are
+     * considered equal, ie. they refer to the same
+     * fragment in the same file.
+     * @since 1.3
+     */
+    protected boolean equals(URL u1, URL u2) {
+        // Android-changed: Avoid network I/O
+        return Objects.equals(u1.getRef(), u2.getRef()) &&
+               Objects.equals(u1.getQuery(), u2.getQuery()) &&
+               // sameFile compares the protocol, file, port & host components of
+               // the URLs.
+               sameFile(u1, u2);
+    }
+
+    /**
+     * Provides the default hash calculation. May be overidden by handlers for
+     * other protocols that have different requirements for hashCode
+     * calculation.
+     * @param u a URL object
+     * @return an {@code int} suitable for hash table indexing
+     * @since 1.3
+     */
+    protected int hashCode(URL u) {
+        // Android-changed: Avoid network I/O
+        // Hash on the same set of fields that we compare in equals().
+        return Objects.hash(
+                u.getRef(),
+                u.getQuery(),
+                u.getProtocol(),
+                u.getFile(),
+                u.getHost(),
+                u.getPort());
+    }
+
+    /**
+     * Compare two urls to see whether they refer to the same file,
+     * i.e., having the same protocol, host, port, and path.
+     * This method requires that none of its arguments is null. This is
+     * guaranteed by the fact that it is only called indirectly
+     * by java.net.URL class.
+     * @param u1 a URL object
+     * @param u2 a URL object
+     * @return true if u1 and u2 refer to the same file
+     * @since 1.3
+     */
+    protected boolean sameFile(URL u1, URL u2) {
+        // Compare the protocols.
+        if (!((u1.getProtocol() == u2.getProtocol()) ||
+              (u1.getProtocol() != null &&
+               u1.getProtocol().equalsIgnoreCase(u2.getProtocol()))))
+            return false;
+
+        // Compare the files.
+        if (!(u1.getFile() == u2.getFile() ||
+              (u1.getFile() != null && u1.getFile().equals(u2.getFile()))))
+            return false;
+
+        // Compare the ports.
+        int port1, port2;
+        port1 = (u1.getPort() != -1) ? u1.getPort() : u1.handler.getDefaultPort();
+        port2 = (u2.getPort() != -1) ? u2.getPort() : u2.handler.getDefaultPort();
+        if (port1 != port2)
+            return false;
+
+        // Compare the hosts.
+        if (!hostsEqual(u1, u2))
+            return false;
+
+        return true;
+    }
+
+    /**
+     * Get the IP address of our host. An empty host field or a DNS failure
+     * will result in a null return.
+     *
+     * @param u a URL object
+     * @return an {@code InetAddress} representing the host
+     * IP address.
+     * @since 1.3
+     */
+    protected synchronized InetAddress getHostAddress(URL u) {
+        if (u.hostAddress != null)
+            return u.hostAddress;
+
+        String host = u.getHost();
+        if (host == null || host.equals("")) {
+            return null;
+        } else {
+            try {
+                u.hostAddress = InetAddress.getByName(host);
+            } catch (UnknownHostException ex) {
+                return null;
+            } catch (SecurityException se) {
+                return null;
+            }
+        }
+        return u.hostAddress;
+    }
+
+    /**
+     * Compares the host components of two URLs.
+     * @param u1 the URL of the first host to compare
+     * @param u2 the URL of the second host to compare
+     * @return  {@code true} if and only if they
+     * are equal, {@code false} otherwise.
+     * @since 1.3
+     */
+    protected boolean hostsEqual(URL u1, URL u2) {
+        // Android-changed: Don't compare the InetAddresses of the hosts.
+        if (u1.getHost() != null && u2.getHost() != null)
+            return u1.getHost().equalsIgnoreCase(u2.getHost());
+         else
+            return u1.getHost() == null && u2.getHost() == null;
+    }
+
+    /**
+     * Converts a {@code URL} of a specific protocol to a
+     * {@code String}.
+     *
+     * @param   u   the URL.
+     * @return  a string representation of the {@code URL} argument.
+     */
+    protected String toExternalForm(URL u) {
+
+        // pre-compute length of StringBuffer
+        int len = u.getProtocol().length() + 1;
+        if (u.getAuthority() != null && u.getAuthority().length() > 0)
+            len += 2 + u.getAuthority().length();
+        if (u.getPath() != null) {
+            len += u.getPath().length();
+        }
+        if (u.getQuery() != null) {
+            len += 1 + u.getQuery().length();
+        }
+        if (u.getRef() != null)
+            len += 1 + u.getRef().length();
+
+        // BEGIN Android-changed: Add a toExternalForm variant that optionally escapes illegal chars
+        // TODO: The variant has been removed. We can potentially revert the change
+        StringBuilder result = new StringBuilder(len);
+        result.append(u.getProtocol());
+        result.append(":");
+        if (u.getAuthority() != null) {// ANDROID: && u.getAuthority().length() > 0) {
+            result.append("//");
+            result.append(u.getAuthority());
+        }
+        String fileAndQuery = u.getFile();
+        if (fileAndQuery != null) {
+            result.append(fileAndQuery);
+        }
+        // END Android-changed: Add a toExternalForm variant that optionally escapes illegal chars
+        if (u.getRef() != null) {
+            result.append("#");
+            result.append(u.getRef());
+        }
+        return result.toString();
+    }
+
+    // Android-changed: Removed @see tag (target is package-private):
+    // @see     java.net.URL#set(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String)
+    /**
+     * Sets the fields of the {@code URL} argument to the indicated values.
+     * Only classes derived from URLStreamHandler are able
+     * to use this method to set the values of the URL fields.
+     *
+     * @param   u         the URL to modify.
+     * @param   protocol  the protocol name.
+     * @param   host      the remote host value for the URL.
+     * @param   port      the port on the remote machine.
+     * @param   authority the authority part for the URL.
+     * @param   userInfo the userInfo part of the URL.
+     * @param   path      the path component of the URL.
+     * @param   query     the query part for the URL.
+     * @param   ref       the reference.
+     * @exception       SecurityException       if the protocol handler of the URL is
+     *                                  different from this one
+     * @since 1.3
+     */
+       protected void setURL(URL u, String protocol, String host, int port,
+                             String authority, String userInfo, String path,
+                             String query, String ref) {
+        if (this != u.handler) {
+            throw new SecurityException("handler for url different from " +
+                                        "this handler");
+        }
+        // ensure that no one can reset the protocol on a given URL.
+        u.set(u.getProtocol(), host, port, authority, userInfo, path, query, ref);
+    }
+
+    /**
+     * Sets the fields of the {@code URL} argument to the indicated values.
+     * Only classes derived from URLStreamHandler are able
+     * to use this method to set the values of the URL fields.
+     *
+     * @param   u         the URL to modify.
+     * @param   protocol  the protocol name. This value is ignored since 1.2.
+     * @param   host      the remote host value for the URL.
+     * @param   port      the port on the remote machine.
+     * @param   file      the file.
+     * @param   ref       the reference.
+     * @exception       SecurityException       if the protocol handler of the URL is
+     *                                  different from this one
+     * @deprecated Use setURL(URL, String, String, int, String, String, String,
+     *             String);
+     */
+    @Deprecated
+    protected void setURL(URL u, String protocol, String host, int port,
+                          String file, String ref) {
+        /*
+         * Only old URL handlers call this, so assume that the host
+         * field might contain "user:passwd@host". Fix as necessary.
+         */
+        String authority = null;
+        String userInfo = null;
+        if (host != null && host.length() != 0) {
+            authority = (port == -1) ? host : host + ":" + port;
+            int at = host.lastIndexOf('@');
+            if (at != -1) {
+                userInfo = host.substring(0, at);
+                host = host.substring(at+1);
+            }
+        }
+
+        /*
+         * Assume file might contain query part. Fix as necessary.
+         */
+        String path = null;
+        String query = null;
+        if (file != null) {
+            int q = file.lastIndexOf('?');
+            if (q != -1) {
+                query = file.substring(q+1);
+                path = file.substring(0, q);
+            } else
+                path = file;
+        }
+        setURL(u, protocol, host, port, authority, userInfo, path, query, ref);
+    }
+}
diff --git a/java/net/URLStreamHandlerFactory.java b/java/net/URLStreamHandlerFactory.java
new file mode 100644
index 0000000..e46e028
--- /dev/null
+++ b/java/net/URLStreamHandlerFactory.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+/**
+ * This interface defines a factory for {@code URL} stream
+ * protocol handlers.
+ * <p>
+ * It is used by the {@code URL} class to create a
+ * {@code URLStreamHandler} for a specific protocol.
+ *
+ * @author  Arthur van Hoff
+ * @see     java.net.URL
+ * @see     java.net.URLStreamHandler
+ * @since   JDK1.0
+ */
+public interface URLStreamHandlerFactory {
+    /**
+     * Creates a new {@code URLStreamHandler} instance with the specified
+     * protocol.
+     *
+     * @param   protocol   the protocol ("{@code ftp}",
+     *                     "{@code http}", "{@code nntp}", etc.).
+     * @return  a {@code URLStreamHandler} for the specific protocol.
+     * @see     java.net.URLStreamHandler
+     */
+    URLStreamHandler createURLStreamHandler(String protocol);
+}
diff --git a/java/net/UnknownHostException.java b/java/net/UnknownHostException.java
new file mode 100644
index 0000000..21a9d14
--- /dev/null
+++ b/java/net/UnknownHostException.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Thrown to indicate that the IP address of a host could not be determined.
+ *
+ * @author  Jonathan Payne
+ * @since   JDK1.0
+ */
+public
+class UnknownHostException extends IOException {
+    private static final long serialVersionUID = -4639126076052875403L;
+
+    /**
+     * Constructs a new {@code UnknownHostException} with the
+     * specified detail message.
+     *
+     * @param   host   the detail message.
+     */
+    public UnknownHostException(String host) {
+        super(host);
+    }
+
+    /**
+     * Constructs a new {@code UnknownHostException} with no detail
+     * message.
+     */
+    public UnknownHostException() {
+    }
+}
diff --git a/java/net/UnknownServiceException.java b/java/net/UnknownServiceException.java
new file mode 100644
index 0000000..4eea4a7
--- /dev/null
+++ b/java/net/UnknownServiceException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.net;
+
+import java.io.IOException;
+
+/**
+ * Thrown to indicate that an unknown service exception has
+ * occurred. Either the MIME type returned by a URL connection does
+ * not make sense, or the application is attempting to write to a
+ * read-only URL connection.
+ *
+ * @author  unascribed
+ * @since   JDK1.0
+ */
+public class UnknownServiceException extends IOException {
+    private static final long serialVersionUID = -4169033248853639508L;
+
+    /**
+     * Constructs a new {@code UnknownServiceException} with no
+     * detail message.
+     */
+    public UnknownServiceException() {
+    }
+
+    /**
+     * Constructs a new {@code UnknownServiceException} with the
+     * specified detail message.
+     *
+     * @param   msg   the detail message.
+     */
+    public UnknownServiceException(String msg) {
+        super(msg);
+    }
+}
diff --git a/java/net/package-info.java b/java/net/package-info.java
new file mode 100644
index 0000000..fda2e4f
--- /dev/null
+++ b/java/net/package-info.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Provides the classes for implementing networking applications.
+ *
+ * <p> The java.net package can be roughly divided in two sections:</p>
+ * <ul>
+ *     <li><p><i>A Low Level API</i>, which deals with the
+ *               following abstractions:</p>
+ *     <ul>
+ *       <li><p><i>Addresses</i>, which are networking identifiers,
+ *              like IP addresses.</p></li>
+ *       <li><p><i>Sockets</i>, which are basic bidirectional data communication
+ *              mechanisms.</p></li>
+ *       <li><p><i>Interfaces</i>, which describe network interfaces. </p></li>
+ *     </ul></li>
+ *     <li> <p><i>A High Level API</i>, which deals with the following
+ *          abstractions:</p>
+ *     <ul>
+ *       <li><p><i>URIs</i>, which represent
+ *               Universal Resource Identifiers.</p></li>
+ *       <li><p><i>URLs</i>, which represent
+ *               Universal Resource Locators.</p></li>
+ *       <li><p><i>Connections</i>, which represents connections to the resource
+ *               pointed to by <i>URLs</i>.</p></li>
+ *       </ul></li>
+ * </ul>
+ * <h2>Addresses</h2>
+ * <p>Addresses are used throughout the java.net APIs as either host
+ *    identifiers, or socket endpoint identifiers.</p>
+ * <p>The {@link java.net.InetAddress} class is the abstraction representing an
+ *    IP (Internet Protocol) address.  It has two subclasses:
+ * <ul>
+ *       <li>{@link java.net.Inet4Address} for IPv4 addresses.</li>
+ *       <li>{@link java.net.Inet6Address} for IPv6 addresses.</li>
+ * </ul>
+ * <p>But, in most cases, there is no need to deal directly with the subclasses,
+ *    as the InetAddress abstraction should cover most of the needed
+ *    functionality.</p>
+ * <h3><b>About IPv6</b></h3>
+ * <p>Not all systems have support for the IPv6 protocol, and while the Java
+ *    networking stack will attempt to detect it and use it transparently when
+ *    available, it is also possible to disable its use with a system property.
+ *    In the case where IPv6 is not available, or explicitly disabled,
+ *    Inet6Address are not valid arguments for most networking operations any
+ *    more. While methods like {@link java.net.InetAddress#getByName} are
+ *    guaranteed not to return an Inet6Address when looking up host names, it
+ *    is possible, by passing literals, to create such an object. In which
+ *    case, most methods, when called with an Inet6Address will throw an
+ *    Exception.</p>
+ * <h2>Sockets</h2>
+ * <p>Sockets are means to establish a communication link between machines over
+ *    the network. The java.net package provides 4 kinds of Sockets:</p>
+ * <ul>
+ *       <li>{@link java.net.Socket} is a TCP client API, and will typically
+ *            be used to {@linkplain java.net.Socket#connect(SocketAddress)
+ *            connect} to a remote host.</li>
+ *       <li>{@link java.net.ServerSocket} is a TCP server API, and will
+ *            typically {@linkplain java.net.ServerSocket#accept accept}
+ *            connections from client sockets.</li>
+ *       <li>{@link java.net.DatagramSocket} is a UDP endpoint API and is used
+ *            to {@linkplain java.net.DatagramSocket#send send} and
+ *            {@linkplain java.net.DatagramSocket#receive receive}
+ *            {@linkplain java.net.DatagramPacket datagram packets}.</li>
+ *       <li>{@link java.net.MulticastSocket} is a subclass of
+ *            {@code DatagramSocket} used when dealing with multicast
+ *            groups.</li>
+ * </ul>
+ * <p>Sending and receiving with TCP sockets is done through InputStreams and
+ *    OutputStreams which can be obtained via the
+ *    {@link java.net.Socket#getInputStream} and
+ *    {@link java.net.Socket#getOutputStream} methods.</p>
+ * <h2>Interfaces</h2>
+ * <p>The {@link java.net.NetworkInterface} class provides APIs to browse and
+ *    query all the networking interfaces (e.g. ethernet connection or PPP
+ *    endpoint) of the local machine. It is through that class that you can
+ *    check if any of the local interfaces is configured to support IPv6.</p>
+ * <p>Note, all conforming implementations must support at least one
+ *    {@code NetworkInterface} object, which must either be connected to a
+ *    network, or be a "loopback" interface that can only communicate with
+ *    entities on the same machine.</p>
+ *
+ * <h2>High level API</h2>
+ * <p>A number of classes in the java.net package do provide for a much higher
+ *    level of abstraction and allow for easy access to resources on the
+ *    network. The classes are:
+ * <ul>
+ *       <li>{@link java.net.URI} is the class representing a
+ *            Universal Resource Identifier, as specified in RFC 2396.
+ *            As the name indicates, this is just an Identifier and doesn't
+ *            provide directly the means to access the resource.</li>
+ *       <li>{@link java.net.URL} is the class representing a
+ *            Universal Resource Locator, which is both an older concept for
+ *            URIs and a means to access the resources.</li>
+ *       <li>{@link java.net.URLConnection} is created from a URL and is the
+ *            communication link used to access the resource pointed by the
+ *            URL. This abstract class will delegate most of the work to the
+ *            underlying protocol handlers like http or https.</li>
+ *       <li>{@link java.net.HttpURLConnection} is a subclass of URLConnection
+ *            and provides some additional functionalities specific to the
+ *            HTTP protocol.</li>
+ * </ul>
+ * <p>The recommended usage is to use {@link java.net.URI} to identify
+ *    resources, then convert it into a {@link java.net.URL} when it is time to
+ *    access the resource. From that URL, you can either get the
+ *    {@link java.net.URLConnection} for fine control, or get directly the
+ *    InputStream.
+ * <p>Here is an example:</p>
+ * <pre>
+ * URI uri = new URI("http://java.sun.com/");
+ * URL url = uri.toURL();
+ * InputStream in = url.openStream();
+ * </pre>
+ * <h2>Protocol Handlers</h2>
+ * As mentioned, URL and URLConnection rely on protocol handlers which must be
+ * present, otherwise an Exception is thrown. This is the major difference with
+ * URIs which only identify resources, and therefore don't need to have access
+ * to the protocol handler. So, while it is possible to create an URI with any
+ * kind of protocol scheme (e.g. {@code myproto://myhost.mydomain/resource/}),
+ * a similar URL will try to instantiate the handler for the specified protocol;
+ * if it doesn't exist an exception will be thrown.
+ * <p>By default the protocol handlers are loaded dynamically from the default
+ *    location. It is, however, possible to add to the search path by setting
+ *    the {@code java.protocol.handler.pkgs} system property. For instance if
+ *    it is set to {@code myapp.protocols}, then the URL code will try, in the
+ *    case of http, first to load {@code myapp.protocols.http.Handler}, then,
+ *    if this fails, {@code http.Handler} from the default location.
+ * <p>Note that the Handler class <b>has to</b> be a subclass of the abstract
+ *    class {@link java.net.URLStreamHandler}.</p>
+ * <h2>Additional Specification</h2>
+ * <ul>
+ *       <li><a href="doc-files/net-properties.html">
+ *            Networking System Properties</a></li>
+ * </ul>
+ *
+ * @since JDK1.0
+ */
+package java.net;
