Merge "MethodHandles: Unhide java.lang.invoke.*"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index a9b7675..209e70c 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -210,8 +210,10 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
 	core-test-rules \
 	core-tests-support \
+	mockftpserver \
 	mockwebserver \
 	nist-pkix-tests \
+	slf4j-jdk14 \
 	sqlite-jdbc \
 	tzdata-testing
 LOCAL_JAVACFLAGS := $(local_javac_flags)
@@ -376,8 +378,10 @@
         okhttp-hostdex
     LOCAL_STATIC_JAVA_LIBRARIES := \
         core-test-rules-hostdex \
+        mockftpserver-hostdex \
         mockwebserver-host \
         nist-pkix-tests-host \
+        slf4j-jdk14-hostdex \
         sqlite-jdbc-host \
         tzdata-testing-hostdex
     LOCAL_JAVACFLAGS := $(local_javac_flags)
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
index 7523752..bb9e806 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/DatagramSocketTest.java
@@ -968,4 +968,28 @@
         ds.close();
         assertEquals(new String("01234"), new String(recvBuffer, 0, recvBuffer.length, "UTF-8"));
     }
+
+    // Receive twice reusing the same DatagramPacket.
+    // http://b/33957878
+    public void testReceiveTwice() throws Exception {
+        try (DatagramSocket ds = new DatagramSocket();
+             DatagramSocket sds = new DatagramSocket()) {
+            sds.connect(ds.getLocalSocketAddress());
+            DatagramPacket p = new DatagramPacket(new byte[16], 16);
+
+            byte[] smallPacketBytes = "01234".getBytes("UTF-8");
+            DatagramPacket smallPacket =
+                    new DatagramPacket(smallPacketBytes, smallPacketBytes.length);
+            sds.send(smallPacket);
+            ds.receive(p);
+            assertPacketDataEquals(smallPacket, p);
+
+            byte[] largePacketBytes = "0123456789".getBytes("UTF-8");
+            DatagramPacket largerPacket =
+                    new DatagramPacket(largePacketBytes, largePacketBytes.length);
+            sds.send(largerPacket);
+            ds.receive(p);
+            assertPacketDataEquals(largerPacket, p);
+        }
+    }
 }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index fb348bc..0c34d5e 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -35,6 +35,7 @@
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
 import java.net.PortUnreachableException;
+import java.net.SocketAddress;
 import java.net.SocketException;
 import java.net.SocketOptions;
 import java.net.SocketTimeoutException;
@@ -97,7 +98,12 @@
         try {
             Libcore.os.bind(fd, address, port);
         } catch (ErrnoException errnoException) {
-            throw new BindException(errnoException.getMessage(), errnoException);
+            if (errnoException.errno == EADDRINUSE || errnoException.errno == EADDRNOTAVAIL ||
+                errnoException.errno == EPERM || errnoException.errno == EACCES) {
+                throw new BindException(errnoException.getMessage(), errnoException);
+            } else {
+                throw new SocketException(errnoException.getMessage(), errnoException);
+            }
         }
     }
 
@@ -285,15 +291,14 @@
     private static Object getSocketOptionErrno(FileDescriptor fd, int option) throws ErrnoException, SocketException {
         switch (option) {
         case SocketOptions.IP_MULTICAST_IF:
-            // This is IPv4-only.
-            return Libcore.os.getsockoptInAddr(fd, IPPROTO_IP, IP_MULTICAST_IF);
         case SocketOptions.IP_MULTICAST_IF2:
-            // This is IPv6-only.
             return Libcore.os.getsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF);
         case SocketOptions.IP_MULTICAST_LOOP:
             // Since setting this from java.net always sets IPv4 and IPv6 to the same value,
             // it doesn't matter which we return.
-            return booleanFromInt(Libcore.os.getsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP));
+            // NOTE: getsockopt's return value means "isEnabled", while OpenJDK code java.net
+            // requires a value that means "isDisabled" so we NEGATE the system call value here.
+            return !booleanFromInt(Libcore.os.getsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP));
         case IoBridge.JAVA_IP_MULTICAST_TTL:
             // Since setting this from java.net always sets IPv4 and IPv6 to the same value,
             // it doesn't matter which we return.
@@ -328,6 +333,8 @@
             return (int) Libcore.os.getsockoptTimeval(fd, SOL_SOCKET, SO_RCVTIMEO).toMillis();
         case SocketOptions.TCP_NODELAY:
             return booleanFromInt(Libcore.os.getsockoptInt(fd, IPPROTO_TCP, TCP_NODELAY));
+        case SocketOptions.SO_BINDADDR:
+            return ((InetSocketAddress) Libcore.os.getsockname(fd)).getAddress();
         default:
             throw new SocketException("Unknown socket option: " + option);
         }
@@ -356,7 +363,15 @@
     private static void setSocketOptionErrno(FileDescriptor fd, int option, Object value) throws ErrnoException, SocketException {
         switch (option) {
         case SocketOptions.IP_MULTICAST_IF:
-            throw new UnsupportedOperationException("Use IP_MULTICAST_IF2 on Android");
+            NetworkInterface nif = NetworkInterface.getByInetAddress((InetAddress) value);
+            if (nif == null) {
+                throw new SocketException(
+                        "bad argument for IP_MULTICAST_IF : address not bound to any interface");
+            }
+            // Although IPv6 was cleaned up to use int, IPv4 uses an ip_mreqn containing an int.
+            Libcore.os.setsockoptIpMreqn(fd, IPPROTO_IP, IP_MULTICAST_IF, nif.getIndex());
+            Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, nif.getIndex());
+            return;
         case SocketOptions.IP_MULTICAST_IF2:
             // Although IPv6 was cleaned up to use int, IPv4 uses an ip_mreqn containing an int.
             Libcore.os.setsockoptIpMreqn(fd, IPPROTO_IP, IP_MULTICAST_IF, (Integer) value);
@@ -364,8 +379,11 @@
             return;
         case SocketOptions.IP_MULTICAST_LOOP:
             // Although IPv6 was cleaned up to use int, IPv4 multicast loopback uses a byte.
-            Libcore.os.setsockoptByte(fd, IPPROTO_IP, IP_MULTICAST_LOOP, booleanToInt((Boolean) value));
-            Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, booleanToInt((Boolean) value));
+            // NOTE: setsockopt's arguement value means "isEnabled", while OpenJDK code java.net
+            // uses a value that means "isDisabled" so we NEGATE the system call value here.
+            int enable = booleanToInt(!((Boolean) value));
+            Libcore.os.setsockoptByte(fd, IPPROTO_IP, IP_MULTICAST_LOOP, enable);
+            Libcore.os.setsockoptInt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, enable);
             return;
         case IoBridge.JAVA_IP_MULTICAST_TTL:
             // Although IPv6 was cleaned up to use int, and IPv4 non-multicast TTL uses int,
@@ -562,10 +580,11 @@
         return result;
     }
 
-    private static int maybeThrowAfterSendto(boolean isDatagram, ErrnoException errnoException) throws SocketException {
+    private static int maybeThrowAfterSendto(boolean isDatagram, ErrnoException errnoException)
+            throws IOException {
         if (isDatagram) {
-            if (errnoException.errno == ECONNRESET || errnoException.errno == ECONNREFUSED) {
-                return 0;
+            if (errnoException.errno == ECONNREFUSED) {
+                throw new PortUnreachableException("ICMP Port Unreachable");
             }
         } else {
             if (errnoException.errno == EAGAIN) {
@@ -574,7 +593,7 @@
                 return 0;
             }
         }
-        throw errnoException.rethrowAsSocketException();
+        throw errnoException.rethrowAsIOException();
     }
 
     public static int recvfrom(boolean isRead, FileDescriptor fd, byte[] bytes, int byteOffset, int byteCount, int flags, DatagramPacket packet, boolean isConnected) throws IOException {
@@ -607,8 +626,12 @@
         }
         if (packet != null) {
             packet.setReceivedLength(byteCount);
-            packet.setAddress(srcAddress.getAddress());
             packet.setPort(srcAddress.getPort());
+
+            // packet.address should only be changed when it is different from srcAddress.
+            if (!srcAddress.getAddress().equals(packet.getAddress())) {
+                packet.setAddress(srcAddress.getAddress());
+            }
         }
         return byteCount;
     }
@@ -622,7 +645,7 @@
             }
         } else {
             if (isConnected && errnoException.errno == ECONNREFUSED) {
-                throw new PortUnreachableException("", errnoException);
+                throw new PortUnreachableException("ICMP Port Unreachable", errnoException);
             } else if (errnoException.errno == EAGAIN) {
                 throw new SocketTimeoutException(errnoException);
             } else {
diff --git a/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java b/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
new file mode 100644
index 0000000..1e0c7b9
--- /dev/null
+++ b/luni/src/test/java/libcore/java/net/FtpURLConnectionTest.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2017 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 libcore.java.net;
+
+import junit.framework.TestCase;
+
+import org.mockftpserver.core.util.IoUtil;
+import org.mockftpserver.fake.FakeFtpServer;
+import org.mockftpserver.fake.UserAccount;
+import org.mockftpserver.fake.filesystem.DirectoryEntry;
+import org.mockftpserver.fake.filesystem.FileEntry;
+import org.mockftpserver.fake.filesystem.UnixFakeFileSystem;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.MalformedURLException;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Locale;
+import java.util.Random;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Tests URLConnections for ftp:// URLs.
+ */
+public class FtpURLConnectionTest extends TestCase {
+
+    private static final String FILE_PATH = "test/file/for/FtpURLConnectionTest.txt";
+    private static final String USER = "user";
+    private static final String PASSWORD = "password";
+    private static final String SERVER_HOSTNAME = "localhost";
+    private static final String USER_HOME_DIR = "/home/user";
+
+    private FakeFtpServer fakeFtpServer;
+    private UnixFakeFileSystem fileSystem;
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+        fakeFtpServer = new FakeFtpServer();
+        fakeFtpServer.setServerControlPort(0 /* allocate port number automatically */);
+        fakeFtpServer.addUserAccount(new UserAccount(USER, PASSWORD, USER_HOME_DIR));
+        fileSystem = new UnixFakeFileSystem();
+        fakeFtpServer.setFileSystem(fileSystem);
+        fileSystem.add(new DirectoryEntry(USER_HOME_DIR));
+        fakeFtpServer.start();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        fakeFtpServer.stop();
+        super.tearDown();
+    }
+
+    public void testInputUrl() throws Exception {
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        URL fileUrl = addFileEntry(FILE_PATH, fileContents);
+        URLConnection connection = fileUrl.openConnection();
+        assertContents(fileContents, connection.getInputStream());
+    }
+
+    public void testOutputUrl() throws Exception {
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        addFileEntry("test/output-url/existing file.txt", fileContents);
+        byte[] newFileContents = "contents of brand new file".getBytes(UTF_8);
+        String filePath = "test/output-url/file that is newly created.txt";
+        URL fileUrl = new URL(getFileUrlString(filePath));
+        URLConnection connection = fileUrl.openConnection();
+        connection.setDoInput(false);
+        connection.setDoOutput(true);
+        OutputStream os = connection.getOutputStream();
+        writeBytes(os, newFileContents);
+
+        assertContents(newFileContents, openFileSystemContents(filePath));
+    }
+
+    public void testConnectOverProxy_noProxy() throws Exception {
+        Proxy proxy = Proxy.NO_PROXY;
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        URL fileUrl = addFileEntry(FILE_PATH, fileContents);
+        URLConnection connection = fileUrl.openConnection(proxy);
+        assertContents(fileContents, connection.getInputStream());
+        // Sanity check that NO_PROXY covers the Type.DIRECT case
+        assertEquals(Proxy.Type.DIRECT, proxy.type());
+    }
+
+    /**
+     * Tests that the helper class {@link CountingProxy} correctly accepts and
+     * counts connection attempts to the address represented by {@code asProxy()}.
+     */
+    public void testCountingProxy() throws Exception {
+        CountingProxy countingProxy = CountingProxy.start();
+        try {
+            Proxy proxy = countingProxy.asProxy();
+            assertEquals(Proxy.Type.HTTP, proxy.type());
+            SocketAddress address = proxy.address();
+            Socket socket = new Socket();
+            socket.connect(address, /* timeout (msec) */ 10); // attempt one connection
+            socket.close();
+        } finally {
+            int numConnections = countingProxy.shutdownAndGetConnectionCount();
+            assertEquals(1, numConnections);
+        }
+    }
+
+    /**
+     * Tests that a HTTP proxy explicitly passed to {@link URL#openConnection(Proxy)}
+     * ignores HTTP proxies (since it doesn't support them) and attempts a direct
+     * connection instead.
+     */
+    public void testConnectOverProxy_explicit_http_uses_direct_connection() throws Exception {
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        URL fileUrl = addFileEntry(FILE_PATH, fileContents);
+        CountingProxy countingProxy = CountingProxy.start();
+        final int numConnections;
+        try {
+            Proxy proxy = countingProxy.asProxy();
+            URLConnection connection = fileUrl.openConnection(proxy);
+            // direct connection succeeds
+            assertContents(fileContents, connection.getInputStream());
+        } finally {
+            numConnections = countingProxy.shutdownAndGetConnectionCount();
+        }
+        assertEquals(0, numConnections);
+    }
+
+    /**
+     * Tests that if a ProxySelector is set, any HTTP proxies selected for
+     * ftp:// URLs will be rejected. A direct connection will
+     * be selected once the ProxySelector's proxies have failed.
+     */
+    public void testConnectOverProxy_implicit_http_fails() throws Exception {
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        URL fileUrl = addFileEntry(FILE_PATH, fileContents);
+        ProxySelector defaultProxySelector = ProxySelector.getDefault();
+        try {
+            CountingProxy countingProxy = CountingProxy.start();
+            try {
+                Proxy proxy = countingProxy.asProxy();
+                SingleProxySelector proxySelector = new SingleProxySelector(proxy);
+                ProxySelector.setDefault(proxySelector);
+                URLConnection connection = fileUrl.openConnection();
+                InputStream inputStream = connection.getInputStream();
+
+                IOException e = proxySelector.getLastException();
+                assertEquals("FTP connections over HTTP proxy not supported",
+                        e.getMessage());
+
+                // The direct connection is successful
+                assertContents(fileContents, inputStream);
+            } finally {
+                int numConnections = countingProxy.shutdownAndGetConnectionCount();
+                assertEquals(0, numConnections);
+            }
+        } finally {
+            ProxySelector.setDefault(defaultProxySelector);
+        }
+    }
+
+    public void testInputUrlWithSpaces() throws Exception {
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        URL url = addFileEntry("file with spaces.txt", fileContents);
+        URLConnection connection = url.openConnection();
+        assertContents(fileContents, connection.getInputStream());
+    }
+
+    public void testBinaryFileContents() throws Exception {
+        byte[] data = new byte[4096];
+        new Random(31337).nextBytes(data); // arbitrary pseudo-random but repeatable test data
+        URL url = addFileEntry("binaryfile.dat", data.clone());
+        assertContents(data, url.openConnection().getInputStream());
+    }
+
+    // https://code.google.com/p/android/issues/detail?id=160725
+    public void testInputUrlWithSpacesViaProxySelector() throws Exception {
+        byte[] fileContents = "abcdef 1234567890".getBytes(UTF_8);
+        ProxySelector defaultProxySelector = ProxySelector.getDefault();
+        try {
+            SingleProxySelector proxySelector = new SingleProxySelector(Proxy.NO_PROXY);
+            ProxySelector.setDefault(proxySelector);
+            URL url = addFileEntry("file with spaces.txt", fileContents);
+            assertContents(fileContents, url.openConnection().getInputStream());
+            assertNull(proxySelector.getLastException());
+        } finally {
+            ProxySelector.setDefault(defaultProxySelector);
+        }
+    }
+
+    private InputStream openFileSystemContents(String fileName) throws IOException {
+        String fullFileName = USER_HOME_DIR + "/" + fileName;
+        FileEntry entry = (FileEntry) fileSystem.getEntry(fullFileName);
+        assertNotNull("File must exist with name " + fullFileName, entry);
+        return entry.createInputStream();
+    }
+
+    private static void writeBytes(OutputStream os, byte[] fileContents) throws IOException {
+        os.write(fileContents);
+        os.close();
+    }
+
+    private static void assertContents(byte[] expectedContents, InputStream inputStream)
+            throws IOException {
+        try {
+            byte[] contentBytes = IoUtil.readBytes(inputStream);
+            if (!Arrays.equals(expectedContents, contentBytes)) {
+                // optimize the error message for the case of the content being character data
+                fail("Expected " + new String(expectedContents, UTF_8) + ", but got "
+                        + new String(contentBytes, UTF_8));
+            }
+        } finally {
+            inputStream.close();
+        }
+    }
+
+    private String getFileUrlString(String filePath) {
+        int serverPort = fakeFtpServer.getServerControlPort();
+        String urlString = String.format(Locale.US, "ftp://%s:%s@%s:%s/%s",
+                USER, PASSWORD, SERVER_HOSTNAME, serverPort, filePath);
+        return urlString;
+    }
+
+    private URL addFileEntry(String filePath, byte[] fileContents) {
+        FileEntry fileEntry = new FileEntry(USER_HOME_DIR + "/" + filePath);
+        fileEntry.setContents(fileContents);
+        fileSystem.add(fileEntry);
+        String urlString = getFileUrlString(filePath);
+        try {
+            return new URL(urlString);
+        } catch (MalformedURLException e) {
+            fail("Malformed URL: " + urlString);
+            throw new AssertionError("Can never happen");
+        }
+    }
+
+    /**
+     * A {@link ProxySelector} that selects the same (given) Proxy for all URIs.
+     */
+    static class SingleProxySelector extends ProxySelector {
+        private final Proxy proxy;
+        private IOException lastException = null;
+
+        public SingleProxySelector(Proxy proxy) {
+            this.proxy = proxy;
+        }
+
+        @Override
+        public List<Proxy> select(URI uri) {
+            assertNotNull(uri);
+            return Collections.singletonList(proxy);
+        }
+
+        @Override
+        public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
+            lastException = ioe;
+        }
+
+        public IOException getLastException() {
+            return lastException;
+        }
+    }
+
+    /**
+     * Counts the number of attempts to connect to a ServerSocket exposed
+     * {@link #asProxy() as a Proxy}. From {@link #start()} until
+     * {@link #shutdownAndGetConnectionCount()}, a background server thread
+     * accepts and counts connections on the socket but immediately closes
+     * them without reading any data.
+     */
+    static class CountingProxy {
+        class ServerThread extends Thread {
+            public ServerThread(String name) {
+                super(name);
+            }
+
+            @Override
+            public void run() {
+                while (true) {
+                    try {
+                        Socket socket = serverSocket.accept();
+                        connectionAttempts.incrementAndGet();
+                        socket.close();
+                    } catch (SocketException e) {
+                        shutdownLatch.countDown();
+                        return;
+                    } catch (IOException e) {
+                        // retry, unless shutdownLatch has reached 0
+                    }
+                }
+            }
+        }
+
+        // Signals that serverThread has gracefully completed shutdown (not crashed)
+        private final CountDownLatch shutdownLatch = new CountDownLatch(1);
+        private final ServerSocket serverSocket;
+        private final Proxy proxy;
+        private final Thread serverThread;
+        private final AtomicInteger connectionAttempts = new AtomicInteger(0);
+
+        private CountingProxy() throws IOException {
+            serverSocket = new ServerSocket(0 /* allocate port number automatically */);
+            SocketAddress socketAddress = serverSocket.getLocalSocketAddress();
+            proxy = new Proxy(Proxy.Type.HTTP, socketAddress);
+            String threadName = getClass().getSimpleName() + " @ " +
+                    serverSocket.getLocalSocketAddress();
+            serverThread = new ServerThread(threadName);
+        }
+
+        public static CountingProxy start() throws IOException {
+            CountingProxy result = new CountingProxy();
+            // only start the thread once the object has been properly constructed
+            result.serverThread.start();
+            return result;
+        }
+
+        /**
+         * Returns the HTTP {@link Proxy} that can represents the ServerSocket
+         * connections to which this class manages/counts.
+         */
+        public Proxy asProxy() {
+            return proxy;
+        }
+
+        /**
+         * Causes the ServerSocket represented by {@link #asProxy()} to stop accepting
+         * connections by shutting down the server thread.
+         *
+         * @return the number of connections that were attempted during the proxy's lifetime
+         */
+        public int shutdownAndGetConnectionCount() throws IOException, InterruptedException {
+            try {
+                serverSocket.close();
+                // Check that the server shuts down quickly and gracefully via the expected
+                // code path (as opposed to an uncaught exception).
+                shutdownLatch.await(1, TimeUnit.SECONDS);
+                serverThread.join(1000);
+                assertFalse("serverThread failed to shut down quickly", serverThread.isAlive());
+            } finally {
+                return connectionAttempts.get();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return serverThread.toString() ;
+        }
+    }
+
+}
diff --git a/luni/src/test/java/libcore/java/util/DateTest.java b/luni/src/test/java/libcore/java/util/DateTest.java
index d807007..6185f12 100644
--- a/luni/src/test/java/libcore/java/util/DateTest.java
+++ b/luni/src/test/java/libcore/java/util/DateTest.java
@@ -16,6 +16,7 @@
 
 package libcore.java.util;
 
+import java.time.Instant;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.Locale;
@@ -77,6 +78,84 @@
         assertEquals(
                 Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+05:00"),
                 Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+05"));
+    }
 
+    /**
+     * The minimum long value below which {@link Instant#toEpochMilli()} will
+     * throw is not clearly documented. This test discovers if that minimum
+     * value ever changes, and also checks that it is also the minimum Instant
+     * (at a millisecond boundary) that can be converted to a Date.
+     */
+    public void test_convertFromInstant_lowerBound() {
+        // smallest millisecond Instant that can be converted to Date
+        long minConvertible = -9223372036854775000L;
+
+        // show that this value is < 1 sec away from Long.MIN_VALUE
+        assertEquals(Long.MIN_VALUE + 808, minConvertible);
+
+        Instant inBound = Instant.ofEpochMilli(minConvertible);
+        assertEquals(new Date(minConvertible), Date.from(inBound));
+        assertEquals(minConvertible, inBound.toEpochMilli());
+
+        Instant outOfBound = Instant.ofEpochMilli(minConvertible - 1);
+        try {
+            Date.from(outOfBound);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            assertEquals(ArithmeticException.class, expected.getCause().getClass());
+        }
+
+        try {
+            outOfBound.toEpochMilli();
+            fail();
+        } catch (ArithmeticException expected) {
+
+        }
+    }
+
+    public void test_convertFromInstant_upperBound() {
+        Date.from(Instant.ofEpochMilli(Long.MAX_VALUE));
+
+        Date.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000, 0));
+        Date.from(Instant.ofEpochSecond(Long.MAX_VALUE / 1000, 999999999));
+        Instant outOfBound = Instant.ofEpochSecond(Long.MAX_VALUE / 1000 + 1, 0);
+        try {
+            Date.from(outOfBound);
+            fail();
+        } catch (IllegalArgumentException expected) {
+            assertEquals(ArithmeticException.class, expected.getCause().getClass());
+        }
+    }
+
+    /**
+     * Checks conversion between long, Date and Instant.
+     */
+    public void test_convertToInstantAndBack() {
+        check_convertToInstantAndBack(0);
+        check_convertToInstantAndBack(-1);
+        check_convertToInstantAndBack( 999999999);
+        check_convertToInstantAndBack(1000000000);
+        check_convertToInstantAndBack(1000000001);
+        check_convertToInstantAndBack(1000000002);
+        check_convertToInstantAndBack(1000000499);
+        check_convertToInstantAndBack(1000000500);
+        check_convertToInstantAndBack(1000000999);
+        check_convertToInstantAndBack(1000001000);
+        check_convertToInstantAndBack(Long.MIN_VALUE + 808); // minimum ofEpochMilli argument
+        check_convertToInstantAndBack(Long.MAX_VALUE);
+        check_convertToInstantAndBack(System.currentTimeMillis());
+        check_convertToInstantAndBack(Date.parse("Wed, 06 Jan 2016 11:55:59 GMT+0500"));
+    }
+
+    private static void check_convertToInstantAndBack(long millis) {
+        Date date = new Date(millis);
+        Instant instant = date.toInstant();
+        assertEquals(date, Date.from(instant));
+
+        assertEquals(instant, Instant.ofEpochMilli(millis));
+        assertEquals("Millis should be a millions of nanos", 0, instant.getNano() % 1000000);
+
+        assertEquals(millis, date.getTime());
+        assertEquals(millis, instant.toEpochMilli());
     }
 }
diff --git a/ojluni/src/main/java/java/net/DatagramPacket.java b/ojluni/src/main/java/java/net/DatagramPacket.java
index 1ce7cad..fcdfb1c 100644
--- a/ojluni/src/main/java/java/net/DatagramPacket.java
+++ b/ojluni/src/main/java/java/net/DatagramPacket.java
@@ -43,12 +43,13 @@
 public final
 class DatagramPacket {
 
-    /**
-     * Perform class initialization
-     */
-    static {
-        init();
-    }
+    // Android-removed: init method has been removed
+    // /**
+    //  * Perform class initialization
+    //  */
+    // static {
+    //     init();
+    // }
 
     /*
      * The fields of this class are package-private since DatagramSocketImpl
@@ -385,8 +386,9 @@
         this.bufLength = this.length;
     }
 
-    /**
-     * Perform class load-time initializations.
-     */
-    private native static void init();
+    // Android-removed: JNI has been removed
+    // /**
+    //  * Perform class load-time initializations.
+    //  */
+    // private native static void init();
 }
diff --git a/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java b/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
index ea45500..c6a44d5 100644
--- a/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
+++ b/ojluni/src/main/java/java/net/PlainDatagramSocketImpl.java
@@ -24,11 +24,27 @@
  */
 package java.net;
 
+import android.system.ErrnoException;
+import android.system.StructGroupReq;
+
 import java.io.IOException;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.Collections;
+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.*;
 
 /*
@@ -39,9 +55,10 @@
 
 class PlainDatagramSocketImpl extends AbstractPlainDatagramSocketImpl
 {
-    static {
-        init();
-    }
+    // 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)) {
@@ -78,47 +95,160 @@
         }
     }
 
-    protected synchronized native void bind0(int lport, InetAddress laddr)
-        throws SocketException;
+    protected synchronized void bind0(int lport, InetAddress laddr) throws SocketException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
 
-    protected native void send(DatagramPacket p) throws IOException;
+        IoBridge.bind(fd, laddr, lport);
 
-    protected synchronized native int peek(InetAddress i) throws IOException;
+        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 synchronized native int peekData(DatagramPacket p) throws IOException;
+    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");
+        }
 
-    protected synchronized native void receive0(DatagramPacket p)
-        throws IOException;
+        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 native void setTimeToLive(int ttl) throws IOException;
+    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 native int getTimeToLive() throws IOException;
+    protected synchronized int peekData(DatagramPacket p) throws IOException {
+        doRecv(p, MSG_PEEK);
+        return p.getPort();
+    }
 
-    protected native void setTTL(byte ttl) throws IOException;
+    protected synchronized void receive0(DatagramPacket p) throws IOException {
+        doRecv(p, 0);
+    }
 
-    protected native byte getTTL() throws IOException;
+    private void doRecv(DatagramPacket p, int flags) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
 
-    protected native void join(InetAddress inetaddr, NetworkInterface netIf)
-        throws IOException;
+        if (timeout != 0) {
+            IoBridge.poll(fd, POLLIN | POLLERR, timeout);
+        }
 
-    protected native void leave(InetAddress inetaddr, NetworkInterface netIf)
-        throws IOException;
+        IoBridge.recvfrom(false, fd, p.getData(), p.getOffset(), p.bufLength, flags, p,
+                connected);
+    }
 
-    protected native void datagramSocketCreate() throws SocketException;
+    protected void setTimeToLive(int ttl) throws IOException {
+        IoBridge.setSocketOption(fd, JAVA_IP_MULTICAST_TTL, ttl);
+    }
 
-    protected native void datagramSocketClose();
+    protected int getTimeToLive() throws IOException {
+        return (Integer) IoBridge.getSocketOption(fd, JAVA_IP_MULTICAST_TTL);
+    }
 
-    protected native void socketSetOption0(int opt, Object val)
-        throws SocketException;
+    protected void setTTL(byte ttl) throws IOException {
+        setTimeToLive((int) ttl & 0xff);
+    }
 
-    protected native Object socketGetOption(int opt) throws SocketException;
+    protected byte getTTL() throws IOException {
+        return (byte) getTimeToLive();
+    }
 
-    protected native void connect0(InetAddress address, int port) throws SocketException;
+    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 native void disconnect0(int family);
+    protected void join(InetAddress inetaddr, NetworkInterface netIf) throws IOException {
+        if (isClosed()) {
+            throw new SocketException("Socket closed");
+        }
 
-    /**
-     * Perform class load-time initializations.
-     */
-    private native static void init();
+        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) { }
+    }
+
+    // Android-removed: JNI has been removed
+    // /**
+    //  * Perform class load-time initializations.
+    //  */
+    // private native static void init();
 }
diff --git a/ojluni/src/main/java/java/nio/file/attribute/FileTime.java b/ojluni/src/main/java/java/nio/file/attribute/FileTime.java
index 988ad21..2f3399b 100644
--- a/ojluni/src/main/java/java/nio/file/attribute/FileTime.java
+++ b/ojluni/src/main/java/java/nio/file/attribute/FileTime.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -25,12 +25,10 @@
 
 package java.nio.file.attribute;
 
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-import java.util.Date;
-import java.util.Formatter;
-import java.util.Locale;
-import java.util.TimeZone;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneOffset;
+import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -51,14 +49,22 @@
     implements Comparable<FileTime>
 {
     /**
+     * The unit of granularity to interpret the value. Null if
+     * this {@code FileTime} is converted from an {@code Instant},
+     * the {@code value} and {@code unit} pair will not be used
+     * in this scenario.
+     */
+    private final TimeUnit unit;
+
+    /**
      * The value since the epoch; can be negative.
      */
     private final long value;
 
     /**
-     * The unit of granularity to interpret the value.
+     * The value as Instant (created lazily, if not from an instant)
      */
-    private final TimeUnit unit;
+    private Instant instant;
 
     /**
      * The value return by toString (created lazily)
@@ -66,27 +72,12 @@
     private String valueAsString;
 
     /**
-     * The value in days and excess nanos (created lazily)
-     */
-    private DaysAndNanos daysAndNanos;
-
-    /**
-     * Returns a DaysAndNanos object representing the value.
-     */
-    private DaysAndNanos asDaysAndNanos() {
-        if (daysAndNanos == null)
-            daysAndNanos = new DaysAndNanos(value, unit);
-        return daysAndNanos;
-    }
-
-    /**
      * Initializes a new instance of this class.
      */
-    private FileTime(long value, TimeUnit unit) {
-        if (unit == null)
-            throw new NullPointerException();
+    private FileTime(long value, TimeUnit unit, Instant instant) {
         this.value = value;
         this.unit = unit;
+        this.instant = instant;
     }
 
     /**
@@ -102,7 +93,8 @@
      * @return  a {@code FileTime} representing the given value
      */
     public static FileTime from(long value, TimeUnit unit) {
-        return new FileTime(value, unit);
+        Objects.requireNonNull(unit, "unit");
+        return new FileTime(value, unit, null);
     }
 
     /**
@@ -115,7 +107,22 @@
      * @return  a {@code FileTime} representing the given value
      */
     public static FileTime fromMillis(long value) {
-        return new FileTime(value, TimeUnit.MILLISECONDS);
+        return new FileTime(value, TimeUnit.MILLISECONDS, null);
+    }
+
+    /**
+     * Returns a {@code FileTime} representing the same point of time value
+     * on the time-line as the provided {@code Instant} object.
+     *
+     * @param   instant
+     *          the instant to convert
+     * @return  a {@code FileTime} representing the same point on the time-line
+     *          as the provided instant
+     * @since 1.8
+     */
+    public static FileTime from(Instant instant) {
+        Objects.requireNonNull(instant, "instant");
+        return new FileTime(0, null, instant);
     }
 
     /**
@@ -132,7 +139,22 @@
      *          since the epoch (1970-01-01T00:00:00Z); can be negative
      */
     public long to(TimeUnit unit) {
-        return unit.convert(this.value, this.unit);
+        Objects.requireNonNull(unit, "unit");
+        if (this.unit != null) {
+            return unit.convert(this.value, this.unit);
+        } else {
+            long secs = unit.convert(instant.getEpochSecond(), TimeUnit.SECONDS);
+            if (secs == Long.MIN_VALUE || secs == Long.MAX_VALUE) {
+                return secs;
+            }
+            long nanos = unit.convert(instant.getNano(), TimeUnit.NANOSECONDS);
+            long r = secs + nanos;
+            // Math.addExact() variant
+            if (((secs ^ r) & (nanos ^ r)) < 0) {
+                return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+            }
+            return r;
+        }
     }
 
     /**
@@ -145,7 +167,110 @@
      * @return  the value in milliseconds, since the epoch (1970-01-01T00:00:00Z)
      */
     public long toMillis() {
-        return unit.toMillis(value);
+        if (unit != null) {
+            return unit.toMillis(value);
+        } else {
+            long secs = instant.getEpochSecond();
+            int  nanos = instant.getNano();
+            // Math.multiplyExact() variant
+            long r = secs * 1000;
+            long ax = Math.abs(secs);
+            if (((ax | 1000) >>> 31 != 0)) {
+                if ((r / 1000) != secs) {
+                    return (secs < 0) ? Long.MIN_VALUE : Long.MAX_VALUE;
+                }
+            }
+            return r + nanos / 1000_000;
+        }
+    }
+
+    /**
+     * Time unit constants for conversion.
+     */
+    private static final long HOURS_PER_DAY      = 24L;
+    private static final long MINUTES_PER_HOUR   = 60L;
+    private static final long SECONDS_PER_MINUTE = 60L;
+    private static final long SECONDS_PER_HOUR   = SECONDS_PER_MINUTE * MINUTES_PER_HOUR;
+    private static final long SECONDS_PER_DAY    = SECONDS_PER_HOUR * HOURS_PER_DAY;
+    private static final long MILLIS_PER_SECOND  = 1000L;
+    private static final long MICROS_PER_SECOND  = 1000_000L;
+    private static final long NANOS_PER_SECOND   = 1000_000_000L;
+    private static final int  NANOS_PER_MILLI    = 1000_000;
+    private static final int  NANOS_PER_MICRO    = 1000;
+    // The epoch second of Instant.MIN.
+    private static final long MIN_SECOND = -31557014167219200L;
+    // The epoch second of Instant.MAX.
+    private static final long MAX_SECOND = 31556889864403199L;
+
+    /*
+     * Scale d by m, checking for overflow.
+     */
+    private static long scale(long d, long m, long over) {
+        if (d >  over) return Long.MAX_VALUE;
+        if (d < -over) return Long.MIN_VALUE;
+        return d * m;
+    }
+
+    /**
+     * Converts this {@code FileTime} object to an {@code Instant}.
+     *
+     * <p> The conversion creates an {@code Instant} that represents the
+     * same point on the time-line as this {@code FileTime}.
+     *
+     * <p> {@code FileTime} can store points on the time-line further in the
+     * future and further in the past than {@code Instant}. Conversion
+     * from such further time points saturates to {@link Instant#MIN} if
+     * earlier than {@code Instant.MIN} or {@link Instant#MAX} if later
+     * than {@code Instant.MAX}.
+     *
+     * @return  an instant representing the same point on the time-line as
+     *          this {@code FileTime} object
+     * @since 1.8
+     */
+    public Instant toInstant() {
+        if (instant == null) {
+            long secs = 0L;
+            int nanos = 0;
+            switch (unit) {
+                case DAYS:
+                    secs = scale(value, SECONDS_PER_DAY,
+                                 Long.MAX_VALUE/SECONDS_PER_DAY);
+                    break;
+                case HOURS:
+                    secs = scale(value, SECONDS_PER_HOUR,
+                                 Long.MAX_VALUE/SECONDS_PER_HOUR);
+                    break;
+                case MINUTES:
+                    secs = scale(value, SECONDS_PER_MINUTE,
+                                 Long.MAX_VALUE/SECONDS_PER_MINUTE);
+                    break;
+                case SECONDS:
+                    secs = value;
+                    break;
+                case MILLISECONDS:
+                    secs = Math.floorDiv(value, MILLIS_PER_SECOND);
+                    nanos = (int)Math.floorMod(value, MILLIS_PER_SECOND)
+                            * NANOS_PER_MILLI;
+                    break;
+                case MICROSECONDS:
+                    secs = Math.floorDiv(value, MICROS_PER_SECOND);
+                    nanos = (int)Math.floorMod(value, MICROS_PER_SECOND)
+                            * NANOS_PER_MICRO;
+                    break;
+                case NANOSECONDS:
+                    secs = Math.floorDiv(value, NANOS_PER_SECOND);
+                    nanos = (int)Math.floorMod(value, NANOS_PER_SECOND);
+                    break;
+                default : throw new AssertionError("Unit not handled");
+            }
+            if (secs <= MIN_SECOND)
+                instant = Instant.MIN;
+            else if (secs >= MAX_SECOND)
+                instant = Instant.MAX;
+            else
+                instant = Instant.ofEpochSecond(secs, nanos);
+        }
+        return instant;
     }
 
     /**
@@ -176,8 +301,25 @@
      */
     @Override
     public int hashCode() {
-        // hashcode of days/nanos representation to satisfy contract with equals
-        return asDaysAndNanos().hashCode();
+        // hashcode of instant representation to satisfy contract with equals
+        return toInstant().hashCode();
+    }
+
+    private long toDays() {
+        if (unit != null) {
+            return unit.toDays(value);
+        } else {
+            return TimeUnit.SECONDS.toDays(toInstant().getEpochSecond());
+        }
+    }
+
+    private long toExcessNanos(long days) {
+        if (unit != null) {
+            return unit.toNanos(value - unit.convert(days, TimeUnit.DAYS));
+        } else {
+            return TimeUnit.SECONDS.toNanos(toInstant().getEpochSecond()
+                                            - TimeUnit.DAYS.toSeconds(days));
+        }
     }
 
     /**
@@ -194,14 +336,52 @@
     @Override
     public int compareTo(FileTime other) {
         // same granularity
-        if (unit == other.unit) {
-            return (value < other.value) ? -1 : (value == other.value ? 0 : 1);
+        if (unit != null && unit == other.unit) {
+            return Long.compare(value, other.value);
         } else {
-            // compare using days/nanos representation when unit differs
-            return asDaysAndNanos().compareTo(other.asDaysAndNanos());
+            // compare using instant representation when unit differs
+            long secs = toInstant().getEpochSecond();
+            long secsOther = other.toInstant().getEpochSecond();
+            int cmp = Long.compare(secs, secsOther);
+            if (cmp != 0) {
+                return cmp;
+            }
+            cmp = Long.compare(toInstant().getNano(), other.toInstant().getNano());
+            if (cmp != 0) {
+                return cmp;
+            }
+            if (secs != MAX_SECOND && secs != MIN_SECOND) {
+                return 0;
+            }
+            // if both this and other's Instant reps are MIN/MAX,
+            // use daysSinceEpoch and nanosOfDays, which will not
+            // saturate during calculation.
+            long days = toDays();
+            long daysOther = other.toDays();
+            if (days == daysOther) {
+                return Long.compare(toExcessNanos(days), other.toExcessNanos(daysOther));
+            }
+            return Long.compare(days, daysOther);
         }
     }
 
+    // days in a 400 year cycle = 146097
+    // days in a 10,000 year cycle = 146097 * 25
+    // seconds per day = 86400
+    private static final long DAYS_PER_10000_YEARS = 146097L * 25L;
+    private static final long SECONDS_PER_10000_YEARS = 146097L * 25L * 86400L;
+    private static final long SECONDS_0000_TO_1970 = ((146097L * 5L) - (30L * 365L + 7L)) * 86400L;
+
+    // append year/month/day/hour/minute/second/nano with width and 0 padding
+    private StringBuilder append(StringBuilder sb, int w, int d) {
+        while (w > 0) {
+            sb.append((char)(d/w + '0'));
+            d = d % w;
+            w /= 10;
+        }
+        return sb;
+    }
+
     /**
      * Returns the string representation of this {@code FileTime}. The string
      * is returned in the <a
@@ -229,135 +409,67 @@
      */
     @Override
     public String toString() {
-        String v = valueAsString;
-        if (v == null) {
-            // overflow saturates to Long.MIN_VALUE or Long.MAX_VALUE so this
-            // limits the range:
-            // [-292275056-05-16T16:47:04.192Z,292278994-08-17T07:12:55.807Z]
-            long ms = toMillis();
-
-            // nothing to do when seconds/minutes/hours/days
-            String fractionAsString = "";
-            if (unit.compareTo(TimeUnit.SECONDS) < 0) {
-                long fraction = asDaysAndNanos().fractionOfSecondInNanos();
-                if (fraction != 0L) {
-                    // fraction must be positive
-                    if (fraction < 0L) {
-                        final long MAX_FRACTION_PLUS_1 = 1000L * 1000L * 1000L;
-                        fraction += MAX_FRACTION_PLUS_1;
-                        if (ms != Long.MIN_VALUE) ms--;
-                    }
-
-                    // convert to String, adding leading zeros as required and
-                    // stripping any trailing zeros
-                    String s = Long.toString(fraction);
-                    int len = s.length();
-                    int width = 9 - len;
-                    StringBuilder sb = new StringBuilder(".");
-                    while (width-- > 0) {
-                        sb.append('0');
-                    }
-                    if (s.charAt(len-1) == '0') {
-                        // drop trailing zeros
-                        len--;
-                        while (s.charAt(len-1) == '0')
-                            len--;
-                        sb.append(s.substring(0, len));
-                    } else {
-                        sb.append(s);
-                    }
-                    fractionAsString = sb.toString();
+        if (valueAsString == null) {
+            long secs = 0L;
+            int  nanos = 0;
+            if (instant == null && unit.compareTo(TimeUnit.SECONDS) >= 0) {
+                secs = unit.toSeconds(value);
+            } else {
+                secs = toInstant().getEpochSecond();
+                nanos = toInstant().getNano();
+            }
+            LocalDateTime ldt;
+            int year = 0;
+            if (secs >= -SECONDS_0000_TO_1970) {
+                // current era
+                long zeroSecs = secs - SECONDS_PER_10000_YEARS + SECONDS_0000_TO_1970;
+                long hi = Math.floorDiv(zeroSecs, SECONDS_PER_10000_YEARS) + 1;
+                long lo = Math.floorMod(zeroSecs, SECONDS_PER_10000_YEARS);
+                ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+                year = ldt.getYear() +  (int)hi * 10000;
+            } else {
+                // before current era
+                long zeroSecs = secs + SECONDS_0000_TO_1970;
+                long hi = zeroSecs / SECONDS_PER_10000_YEARS;
+                long lo = zeroSecs % SECONDS_PER_10000_YEARS;
+                ldt = LocalDateTime.ofEpochSecond(lo - SECONDS_0000_TO_1970, nanos, ZoneOffset.UTC);
+                year = ldt.getYear() + (int)hi * 10000;
+            }
+            if (year <= 0) {
+                year = year - 1;
+            }
+            int fraction = ldt.getNano();
+            StringBuilder sb = new StringBuilder(64);
+            sb.append(year < 0 ? "-" : "");
+            year = Math.abs(year);
+            if (year < 10000) {
+                append(sb, 1000, Math.abs(year));
+            } else {
+                sb.append(String.valueOf(year));
+            }
+            sb.append('-');
+            append(sb, 10, ldt.getMonthValue());
+            sb.append('-');
+            append(sb, 10, ldt.getDayOfMonth());
+            sb.append('T');
+            append(sb, 10, ldt.getHour());
+            sb.append(':');
+            append(sb, 10, ldt.getMinute());
+            sb.append(':');
+            append(sb, 10, ldt.getSecond());
+            if (fraction != 0) {
+                sb.append('.');
+                // adding leading zeros and stripping any trailing zeros
+                int w = 100_000_000;
+                while (fraction % 10 == 0) {
+                    fraction /= 10;
+                    w /= 10;
                 }
+                append(sb, w, fraction);
             }
-
-            // create calendar to use with formatter.
-            GregorianCalendar cal =
-                new GregorianCalendar(TimeZone.getTimeZone("UTC"), Locale.ROOT);
-            if (value < 0L)
-                cal.setGregorianChange(new Date(Long.MIN_VALUE));
-            cal.setTimeInMillis(ms);
-
-            // years are negative before common era
-            String sign = (cal.get(Calendar.ERA) == GregorianCalendar.BC) ? "-" : "";
-
-            // [-]YYYY-MM-DDThh:mm:ss[.s]Z
-            v = new Formatter(Locale.ROOT)
-                .format("%s%tFT%tR:%tS%sZ", sign, cal, cal, cal, fractionAsString)
-                .toString();
-            valueAsString = v;
+            sb.append('Z');
+            valueAsString = sb.toString();
         }
-        return v;
-    }
-
-    /**
-     * Represents a FileTime's value as two longs: the number of days since
-     * the epoch, and the excess (in nanoseconds). This is used for comparing
-     * values with different units of granularity.
-     */
-    private static class DaysAndNanos implements Comparable<DaysAndNanos> {
-        // constants for conversion
-        private static final long C0 = 1L;
-        private static final long C1 = C0 * 24L;
-        private static final long C2 = C1 * 60L;
-        private static final long C3 = C2 * 60L;
-        private static final long C4 = C3 * 1000L;
-        private static final long C5 = C4 * 1000L;
-        private static final long C6 = C5 * 1000L;
-
-        /**
-         * The value (in days) since the epoch; can be negative.
-         */
-        private final long days;
-
-        /**
-         * The excess (in nanoseconds); can be negative if days <= 0.
-         */
-        private final long excessNanos;
-
-        /**
-         * Initializes a new instance of this class.
-         */
-        DaysAndNanos(long value, TimeUnit unit) {
-            long scale;
-            switch (unit) {
-                case DAYS         : scale = C0; break;
-                case HOURS        : scale = C1; break;
-                case MINUTES      : scale = C2; break;
-                case SECONDS      : scale = C3; break;
-                case MILLISECONDS : scale = C4; break;
-                case MICROSECONDS : scale = C5; break;
-                case NANOSECONDS  : scale = C6; break;
-                default : throw new AssertionError("Unit not handled");
-            }
-            this.days = unit.toDays(value);
-            this.excessNanos = unit.toNanos(value - (this.days * scale));
-        }
-
-        /**
-         * Returns the fraction of a second, in nanoseconds.
-         */
-        long fractionOfSecondInNanos() {
-            return excessNanos % (1000L * 1000L * 1000L);
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            return (obj instanceof DaysAndNanos) ?
-                compareTo((DaysAndNanos)obj) == 0 : false;
-        }
-
-        @Override
-        public int hashCode() {
-            return (int)(days ^ (days >>> 32) ^
-                         excessNanos ^ (excessNanos >>> 32));
-        }
-
-        @Override
-        public int compareTo(DaysAndNanos other) {
-            if (this.days != other.days)
-                return (this.days < other.days) ? -1 : 1;
-            return (this.excessNanos < other.excessNanos) ? -1 :
-                   (this.excessNanos == other.excessNanos) ? 0 : 1;
-        }
+        return valueAsString;
     }
 }
diff --git a/ojluni/src/main/java/java/util/Date.java b/ojluni/src/main/java/java/util/Date.java
index 37f9aad..6ab763e 100644
--- a/ojluni/src/main/java/java/util/Date.java
+++ b/ojluni/src/main/java/java/util/Date.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 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
@@ -27,10 +27,12 @@
 package java.util;
 
 import java.text.DateFormat;
+import java.time.LocalDate;
 import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.ObjectInputStream;
 import java.lang.ref.SoftReference;
+import java.time.Instant;
 import sun.util.calendar.BaseCalendar;
 import sun.util.calendar.CalendarDate;
 import sun.util.calendar.CalendarSystem;
@@ -488,10 +490,12 @@
                 if ('0' <= c && c <= '9') {
                     n = c - '0';
                     while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
-                        n = (n * 10) + (c - '0');
+                        n = n * 10 + c - '0';
                         i++;
                     }
                     if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
+                        // Android-changed BEGIN: Android specific time zone logic
+
                         if (tzoffset != 0 && tzoffset != -1)
                             break syntax;
 
@@ -518,6 +522,7 @@
 
                         if (prevc == '+')   // plus means east of GMT
                             n = -n;
+                        // Android-changed END
 
                         tzoffset = n;
                     } else if (n >= 70)
@@ -788,7 +793,7 @@
      */
     @Deprecated
     public int getDay() {
-        return normalize().getDayOfWeek() - gcal.SUNDAY;
+        return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
     }
 
     /**
@@ -1000,8 +1005,9 @@
      * exclusive OR of the two halves of the primitive <tt>long</tt>
      * value returned by the {@link Date#getTime}
      * method. That is, the hash code is the value of the expression:
-     * <blockquote><pre>
-     * (int)(this.getTime()^(this.getTime() >>> 32))</pre></blockquote>
+     * <blockquote><pre>{@code
+     * (int)(this.getTime()^(this.getTime() >>> 32))
+     * }</pre></blockquote>
      *
      * @return  a hash code value for this object.
      */
@@ -1045,7 +1051,7 @@
         BaseCalendar.Date date = normalize();
         StringBuilder sb = new StringBuilder(28);
         int index = date.getDayOfWeek();
-        if (index == gcal.SUNDAY) {
+        if (index == BaseCalendar.SUNDAY) {
             index = 8;
         }
         convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
@@ -1057,7 +1063,7 @@
         CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
         TimeZone zi = date.getZone();
         if (zi != null) {
-            sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT, Locale.US)); // zzz
+            sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
         } else {
             sb.append("GMT");
         }
@@ -1101,7 +1107,7 @@
     /**
      * Creates a string representation of this <tt>Date</tt> object of
      * the form:
-     * <blockquote<pre>
+     * <blockquote><pre>
      * d mon yyyy hh:mm:ss GMT</pre></blockquote>
      * where:<ul>
      * <li><i>d</i> is the day of the month (<tt>1</tt> through <tt>31</tt>),
@@ -1183,6 +1189,7 @@
     public int getTimezoneOffset() {
         int zoneOffset;
         if (cdate == null) {
+            // Android-changed: Android specific time zone logic
             GregorianCalendar cal = new GregorianCalendar(fastTime);
             zoneOffset = (cal.get(Calendar.ZONE_OFFSET) + cal.get(Calendar.DST_OFFSET));
         } else {
@@ -1251,7 +1258,7 @@
             }
             GregorianCalendar gc = new GregorianCalendar(tz);
             gc.clear();
-            gc.set(gc.MILLISECOND, ms);
+            gc.set(GregorianCalendar.MILLISECOND, ms);
             gc.set(y, m-1, d, hh, mm, ss);
             fastTime = gc.getTimeInMillis();
             BaseCalendar cal = getCalendarSystem(fastTime);
@@ -1342,4 +1349,46 @@
     {
         fastTime = s.readLong();
     }
+
+    /**
+     * Obtains an instance of {@code Date} from an {@code Instant} object.
+     * <p>
+     * {@code Instant} uses a precision of nanoseconds, whereas {@code Date}
+     * uses a precision of milliseconds.  The conversion will trancate any
+     * excess precision information as though the amount in nanoseconds was
+     * subject to integer division by one million.
+     * <p>
+     * {@code Instant} can store points on the time-line further in the future
+     * and further in the past than {@code Date}. In this scenario, this method
+     * will throw an exception.
+     *
+     * @param instant  the instant to convert
+     * @return a {@code Date} representing the same point on the time-line as
+     *  the provided instant
+     * @exception NullPointerException if {@code instant} is null.
+     * @exception IllegalArgumentException if the instant is too large to
+     *  represent as a {@code Date}
+     * @since 1.8
+     */
+    public static Date from(Instant instant) {
+        try {
+            return new Date(instant.toEpochMilli());
+        } catch (ArithmeticException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+
+    /**
+     * Converts this {@code Date} object to an {@code Instant}.
+     * <p>
+     * The conversion creates an {@code Instant} that represents the same
+     * point on the time-line as this {@code Date}.
+     *
+     * @return an instant representing the same point on the time-line as
+     *  this {@code Date} object
+     * @since 1.8
+     */
+    public Instant toInstant() {
+        return Instant.ofEpochMilli(getTime());
+    }
 }
diff --git a/ojluni/src/main/java/java/util/LinkedHashMap.java b/ojluni/src/main/java/java/util/LinkedHashMap.java
index dd32423..858488e 100644
--- a/ojluni/src/main/java/java/util/LinkedHashMap.java
+++ b/ojluni/src/main/java/java/util/LinkedHashMap.java
@@ -30,6 +30,7 @@
 import java.util.function.BiFunction;
 import java.io.IOException;
 
+// Android-added: Note about spliterator order b/33945212 in Android N
 /**
  * <p>Hash table and linked list implementation of the <tt>Map</tt> interface,
  * with predictable iteration order.  This implementation differs from
@@ -138,6 +139,23 @@
  * returned by all of this class's collection view methods are
  * <em><a href="Spliterator.html#binding">late-binding</a></em>,
  * <em>fail-fast</em>, and additionally report {@link Spliterator#ORDERED}.
+ * <em>Note</em>: The implementation of these spliterators in Android Nougat
+ * (API levels 24 and 25) uses the wrong order (inconsistent with the
+ * iterators, which use the correct order), despite reporting
+ * {@link Spliterator#ORDERED}. You may use the following code fragments
+ * to obtain a correctly ordered Spliterator on API level 24 and 25:
+ * <ul>
+ *     <li>For a Collection view {@code c = lhm.keySet()},
+ *         {@code c = lhm.keySet()} or {@code c = lhm.values()}, use
+ *         {@code java.util.Spliterators.spliterator(c, c.spliterator().characteristics())}
+ *         instead of {@code c.spliterator()}.
+ *     <li>Instead of {@code lhm.stream()} or {@code lhm.parallelStream()}, use
+ *         {@code java.util.stream.StreamSupport.stream(spliterator, false)}
+ *         to construct a (nonparallel) {@link java.util.stream.Stream} from
+ *         such a {@code Spliterator}.
+ * </ul>
+ * Note that these workarounds are only suggested where {@code lhm} is a
+ * {@code LinkedHashMap}.
  *
  * <p>This class is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
diff --git a/ojluni/src/main/java/sun/net/www/MeteredStream.java b/ojluni/src/main/java/sun/net/www/MeteredStream.java
index 29b998a..17c8b83 100644
--- a/ojluni/src/main/java/sun/net/www/MeteredStream.java
+++ b/ojluni/src/main/java/sun/net/www/MeteredStream.java
@@ -29,7 +29,6 @@
 import java.util.*;
 import java.io.*;
 import sun.net.ProgressSource;
-import sun.net.www.http.ChunkedInputStream;
 
 
 public class MeteredStream extends FilterInputStream {
@@ -143,14 +142,15 @@
             return 0;
         }
 
-        if (in instanceof ChunkedInputStream) {
-            n = in.skip(n);
-        }
-        else {
+// Android-changed: Remove support for Android-removed class ChunkedInputSTream
+//        if (in instanceof ChunkedInputStream) {
+//            n = in.skip(n);
+//        }
+//        else {
             // just skip min(n, num_bytes_left)
             long min = (n > expected - count) ? expected - count: n;
             n = in.skip(min);
-        }
+//        }
         justRead(n);
         return n;
     }
diff --git a/ojluni/src/main/java/sun/net/www/http/ChunkedInputStream.java b/ojluni/src/main/java/sun/net/www/http/ChunkedInputStream.java
deleted file mode 100644
index af45752..0000000
--- a/ojluni/src/main/java/sun/net/www/http/ChunkedInputStream.java
+++ /dev/null
@@ -1,780 +0,0 @@
-/*
- * Copyright (c) 1999, 2006, 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 sun.net.www.http;
-
-import java.io.*;
-import java.util.*;
-
-import sun.net.*;
-import sun.net.www.*;
-
-/**
- * A <code>ChunkedInputStream</code> provides a stream for reading a body of
- * a http message that can be sent as a series of chunks, each with its own
- * size indicator. Optionally the last chunk can be followed by trailers
- * containing entity-header fields.
- * <p>
- * A <code>ChunkedInputStream</code> is also <code>Hurryable</code> so it
- * can be hurried to the end of the stream if the bytes are available on
- * the underlying stream.
- */
-public
-class ChunkedInputStream extends InputStream implements Hurryable {
-
-    /**
-     * The underlying stream
-     */
-    private InputStream in;
-
-    /**
-     * The <code>HttpClient</code> that should be notified when the chunked stream has
-     * completed.
-     */
-    private HttpClient hc;
-
-    /**
-     * The <code>MessageHeader</code> that is populated with any optional trailer
-     * that appear after the last chunk.
-     */
-    private MessageHeader responses;
-
-    /**
-     * The size, in bytes, of the chunk that is currently being read.
-     * This size is only valid if the current position in the underlying
-     * input stream is inside a chunk (ie: state == STATE_READING_CHUNK).
-     */
-    private int chunkSize;
-
-    /**
-     * The number of bytes read from the underlying stream for the current
-     * chunk. This value is always in the range <code>0</code> through to
-     * <code>chunkSize</code>
-     */
-    private int chunkRead;
-
-    /**
-     * The internal buffer array where chunk data is available for the
-     * application to read.
-     */
-    private byte chunkData[] = new byte[4096];
-
-    /**
-     * The current position in the buffer. It contains the index
-     * of the next byte to read from <code>chunkData</code>
-     */
-    private int chunkPos;
-
-    /**
-     * The index one greater than the index of the last valid byte in the
-     * buffer. This value is always in the range <code>0</code> through
-     * <code>chunkData.length</code>.
-     */
-    private int chunkCount;
-
-    /**
-     * The internal buffer where bytes from the underlying stream can be
-     * read. It may contain bytes representing chunk-size, chunk-data, or
-     * trailer fields.
-     */
-    private byte rawData[] = new byte[32];
-
-    /**
-     * The current position in the buffer. It contains the index
-     * of the next byte to read from <code>rawData</code>
-     */
-    private int rawPos;
-
-    /**
-     * The index one greater than the index of the last valid byte in the
-     * buffer. This value is always in the range <code>0</code> through
-     * <code>rawData.length</code>.
-     */
-    private int rawCount;
-
-    /**
-     * Indicates if an error was encountered when processing the chunked
-     * stream.
-     */
-    private boolean error;
-
-    /**
-     * Indicates if the chunked stream has been closed using the
-     * <code>close</code> method.
-     */
-    private boolean closed;
-
-    /*
-     * Maximum chunk header size of 2KB + 2 bytes for CRLF
-     */
-    private final static int MAX_CHUNK_HEADER_SIZE = 2050;
-
-    /**
-     * State to indicate that next field should be :-
-     *  chunk-size [ chunk-extension ] CRLF
-     */
-    static final int STATE_AWAITING_CHUNK_HEADER    = 1;
-
-    /**
-     * State to indicate that we are currently reading the chunk-data.
-     */
-    static final int STATE_READING_CHUNK            = 2;
-
-    /**
-     * Indicates that a chunk has been completely read and the next
-     * fields to be examine should be CRLF
-     */
-    static final int STATE_AWAITING_CHUNK_EOL       = 3;
-
-    /**
-     * Indicates that all chunks have been read and the next field
-     * should be optional trailers or an indication that the chunked
-     * stream is complete.
-     */
-    static final int STATE_AWAITING_TRAILERS        = 4;
-
-    /**
-     * State to indicate that the chunked stream is complete and
-     * no further bytes should be read from the underlying stream.
-     */
-    static final int STATE_DONE                     = 5;
-
-    /**
-     * Indicates the current state.
-     */
-    private int state;
-
-
-    /**
-     * Check to make sure that this stream has not been closed.
-     */
-    private void ensureOpen() throws IOException {
-        if (closed) {
-            throw new IOException("stream is closed");
-        }
-    }
-
-
-    /**
-     * Ensures there is <code>size</code> bytes available in
-     * <code>rawData</code>. This requires that we either
-     * shift the bytes in use to the begining of the buffer
-     * or allocate a large buffer with sufficient space available.
-     */
-    private void ensureRawAvailable(int size) {
-        if (rawCount + size > rawData.length) {
-            int used = rawCount - rawPos;
-            if (used + size > rawData.length) {
-                byte tmp[] = new byte[used + size];
-                if (used > 0) {
-                    System.arraycopy(rawData, rawPos, tmp, 0, used);
-                }
-                rawData = tmp;
-            } else {
-                if (used > 0) {
-                    System.arraycopy(rawData, rawPos, rawData, 0, used);
-                }
-            }
-            rawCount = used;
-            rawPos = 0;
-        }
-    }
-
-
-    /**
-     * Close the underlying input stream by either returning it to the
-     * keep alive cache or closing the stream.
-     * <p>
-     * As a chunked stream is inheritly persistent (see HTTP 1.1 RFC) the
-     * underlying stream can be returned to the keep alive cache if the
-     * stream can be completely read without error.
-     */
-    private void closeUnderlying() throws IOException {
-        if (in == null) {
-            return;
-        }
-
-        if (!error && state == STATE_DONE) {
-            hc.finished();
-        } else {
-            if (!hurry()) {
-                hc.closeServer();
-            }
-        }
-
-        in = null;
-    }
-
-    /**
-     * Attempt to read the remainder of a chunk directly into the
-     * caller's buffer.
-     * <p>
-     * Return the number of bytes read.
-     */
-    private int fastRead(byte[] b, int off, int len) throws IOException {
-
-        // assert state == STATE_READING_CHUNKS;
-
-        int remaining = chunkSize - chunkRead;
-        int cnt = (remaining < len) ? remaining : len;
-        if (cnt > 0) {
-            int nread;
-            try {
-                nread = in.read(b, off, cnt);
-            } catch (IOException e) {
-                error = true;
-                throw e;
-            }
-            if (nread > 0) {
-                chunkRead += nread;
-                if (chunkRead >= chunkSize) {
-                    state = STATE_AWAITING_CHUNK_EOL;
-                }
-                return nread;
-            }
-            error = true;
-            throw new IOException("Premature EOF");
-        } else {
-            return 0;
-        }
-    }
-
-    /**
-     * Process any outstanding bytes that have already been read into
-     * <code>rawData</code>.
-     * <p>
-     * The parsing of the chunked stream is performed as a state machine with
-     * <code>state</code> representing the current state of the processing.
-     * <p>
-     * Returns when either all the outstanding bytes in rawData have been
-     * processed or there is insufficient bytes available to continue
-     * processing. When the latter occurs <code>rawPos</code> will not have
-     * been updated and thus the processing can be restarted once further
-     * bytes have been read into <code>rawData</code>.
-     */
-    private void processRaw() throws IOException {
-        int pos;
-        int i;
-
-        while (state != STATE_DONE) {
-
-            switch (state) {
-
-                /**
-                 * We are awaiting a line with a chunk header
-                 */
-                case STATE_AWAITING_CHUNK_HEADER:
-                    /*
-                     * Find \n to indicate end of chunk header. If not found when there is
-                     * insufficient bytes in the raw buffer to parse a chunk header.
-                     */
-                    pos = rawPos;
-                    while (pos < rawCount) {
-                        if (rawData[pos] == '\n') {
-                            break;
-                        }
-                        pos++;
-                        if ((pos - rawPos) >= MAX_CHUNK_HEADER_SIZE) {
-                            error = true;
-                            throw new IOException("Chunk header too long");
-                        }
-                    }
-                    if (pos >= rawCount) {
-                        return;
-                    }
-
-                    /*
-                     * Extract the chunk size from the header (ignoring extensions).
-                     */
-                    String header = new String(rawData, rawPos, pos-rawPos+1, "US-ASCII");
-                    for (i=0; i < header.length(); i++) {
-                        if (Character.digit(header.charAt(i), 16) == -1)
-                            break;
-                    }
-                    try {
-                        chunkSize = Integer.parseInt(header.substring(0, i), 16);
-                    } catch (NumberFormatException e) {
-                        error = true;
-                        throw new IOException("Bogus chunk size");
-                    }
-
-                    /*
-                     * Chunk has been parsed so move rawPos to first byte of chunk
-                     * data.
-                     */
-                    rawPos = pos + 1;
-                    chunkRead = 0;
-
-                    /*
-                     * A chunk size of 0 means EOF.
-                     */
-                    if (chunkSize > 0) {
-                        state = STATE_READING_CHUNK;
-                    } else {
-                        state = STATE_AWAITING_TRAILERS;
-                    }
-                    break;
-
-
-                /**
-                 * We are awaiting raw entity data (some may have already been
-                 * read). chunkSize is the size of the chunk; chunkRead is the
-                 * total read from the underlying stream to date.
-                 */
-                case STATE_READING_CHUNK :
-                    /* no data available yet */
-                    if (rawPos >= rawCount) {
-                        return;
-                    }
-
-                    /*
-                     * Compute the number of bytes of chunk data available in the
-                     * raw buffer.
-                     */
-                    int copyLen = Math.min( chunkSize-chunkRead, rawCount-rawPos );
-
-                    /*
-                     * Expand or compact chunkData if needed.
-                     */
-                    if (chunkData.length < chunkCount + copyLen) {
-                        int cnt = chunkCount - chunkPos;
-                        if (chunkData.length < cnt + copyLen) {
-                            byte tmp[] = new byte[cnt + copyLen];
-                            System.arraycopy(chunkData, chunkPos, tmp, 0, cnt);
-                            chunkData = tmp;
-                        } else {
-                            System.arraycopy(chunkData, chunkPos, chunkData, 0, cnt);
-                        }
-                        chunkPos = 0;
-                        chunkCount = cnt;
-                    }
-
-                    /*
-                     * Copy the chunk data into chunkData so that it's available
-                     * to the read methods.
-                     */
-                    System.arraycopy(rawData, rawPos, chunkData, chunkCount, copyLen);
-                    rawPos += copyLen;
-                    chunkCount += copyLen;
-                    chunkRead += copyLen;
-
-                    /*
-                     * If all the chunk has been copied into chunkData then the next
-                     * token should be CRLF.
-                     */
-                    if (chunkSize - chunkRead <= 0) {
-                        state = STATE_AWAITING_CHUNK_EOL;
-                    } else {
-                        return;
-                    }
-                    break;
-
-
-                /**
-                 * Awaiting CRLF after the chunk
-                 */
-                case STATE_AWAITING_CHUNK_EOL:
-                    /* not available yet */
-                    if (rawPos + 1 >= rawCount) {
-                        return;
-                    }
-
-                    if (rawData[rawPos] != '\r') {
-                        error = true;
-                        throw new IOException("missing CR");
-                    }
-                    if (rawData[rawPos+1] != '\n') {
-                        error = true;
-                        throw new IOException("missing LF");
-                    }
-                    rawPos += 2;
-
-                    /*
-                     * Move onto the next chunk
-                     */
-                    state = STATE_AWAITING_CHUNK_HEADER;
-                    break;
-
-
-                /**
-                 * Last chunk has been read so not we're waiting for optional
-                 * trailers.
-                 */
-                case STATE_AWAITING_TRAILERS:
-
-                    /*
-                     * Do we have an entire line in the raw buffer?
-                     */
-                    pos = rawPos;
-                    while (pos < rawCount) {
-                        if (rawData[pos] == '\n') {
-                            break;
-                        }
-                        pos++;
-                    }
-                    if (pos >= rawCount) {
-                        return;
-                    }
-
-                    if (pos == rawPos) {
-                        error = true;
-                        throw new IOException("LF should be proceeded by CR");
-                    }
-                    if (rawData[pos-1] != '\r') {
-                        error = true;
-                        throw new IOException("LF should be proceeded by CR");
-                    }
-
-                    /*
-                     * Stream done so close underlying stream.
-                     */
-                    if (pos == (rawPos + 1)) {
-
-                        state = STATE_DONE;
-                        closeUnderlying();
-
-                        return;
-                    }
-
-                    /*
-                     * Extract any tailers and append them to the message
-                     * headers.
-                     */
-                    String trailer = new String(rawData, rawPos, pos-rawPos, "US-ASCII");
-                    i = trailer.indexOf(':');
-                    if (i == -1) {
-                        throw new IOException("Malformed tailer - format should be key:value");
-                    }
-                    String key = (trailer.substring(0, i)).trim();
-                    String value = (trailer.substring(i+1, trailer.length())).trim();
-
-                    responses.add(key, value);
-
-                    /*
-                     * Move onto the next trailer.
-                     */
-                    rawPos = pos+1;
-                    break;
-
-            } /* switch */
-        }
-    }
-
-
-    /**
-     * Reads any available bytes from the underlying stream into
-     * <code>rawData</code> and returns the number of bytes of
-     * chunk data available in <code>chunkData</code> that the
-     * application can read.
-     */
-    private int readAheadNonBlocking() throws IOException {
-
-        /*
-         * If there's anything available on the underlying stream then we read
-         * it into the raw buffer and process it. Processing ensures that any
-         * available chunk data is made available in chunkData.
-         */
-        int avail = in.available();
-        if (avail > 0) {
-
-            /* ensure that there is space in rawData to read the available */
-            ensureRawAvailable(avail);
-
-            int nread;
-            try {
-                nread = in.read(rawData, rawCount, avail);
-            } catch (IOException e) {
-                error = true;
-                throw e;
-            }
-            if (nread < 0) {
-                error = true;   /* premature EOF ? */
-                return -1;
-            }
-            rawCount += nread;
-
-            /*
-             * Process the raw bytes that have been read.
-             */
-            processRaw();
-        }
-
-        /*
-         * Return the number of chunked bytes available to read
-         */
-        return chunkCount - chunkPos;
-    }
-
-    /**
-     * Reads from the underlying stream until there is chunk data
-     * available in <code>chunkData</code> for the application to
-     * read.
-     */
-    private int readAheadBlocking() throws IOException {
-
-        do {
-            /*
-             * All of chunked response has been read to return EOF.
-             */
-            if (state == STATE_DONE) {
-                return -1;
-            }
-
-            /*
-             * We must read into the raw buffer so make sure there is space
-             * available. We use a size of 32 to avoid too much chunk data
-             * being read into the raw buffer.
-             */
-            ensureRawAvailable(32);
-            int nread;
-            try {
-                nread = in.read(rawData, rawCount, rawData.length-rawCount);
-            } catch (IOException e) {
-                error = true;
-                throw e;
-            }
-
-            /**
-             * If we hit EOF it means there's a problem as we should never
-             * attempt to read once the last chunk and trailers have been
-             * received.
-             */
-            if (nread < 0) {
-                error = true;
-                throw new IOException("Premature EOF");
-            }
-
-            /**
-             * Process the bytes from the underlying stream
-             */
-            rawCount += nread;
-            processRaw();
-
-        } while (chunkCount <= 0);
-
-        /*
-         * Return the number of chunked bytes available to read
-         */
-        return chunkCount - chunkPos;
-    }
-
-    /**
-     * Read ahead in either blocking or non-blocking mode. This method
-     * is typically used when we run out of available bytes in
-     * <code>chunkData</code> or we need to determine how many bytes
-     * are available on the input stream.
-     */
-    private int readAhead(boolean allowBlocking) throws IOException {
-
-        /*
-         * Last chunk already received - return EOF
-         */
-        if (state == STATE_DONE) {
-            return -1;
-        }
-
-        /*
-         * Reset position/count if data in chunkData is exhausted.
-         */
-        if (chunkPos >= chunkCount) {
-            chunkCount = 0;
-            chunkPos = 0;
-        }
-
-        /*
-         * Read ahead blocking or non-blocking
-         */
-        if (allowBlocking) {
-            return readAheadBlocking();
-        } else {
-            return readAheadNonBlocking();
-        }
-    }
-
-    /**
-     * Creates a <code>ChunkedInputStream</code> and saves its  arguments, for
-     * later use.
-     *
-     * @param   in   the underlying input stream.
-     * @param   hc   the HttpClient
-     * @param   responses   the MessageHeader that should be populated with optional
-     *                      trailers.
-     */
-    public ChunkedInputStream(InputStream in, HttpClient hc, MessageHeader responses) throws IOException {
-
-        /* save arguments */
-        this.in = in;
-        this.responses = responses;
-        this.hc = hc;
-
-        /*
-         * Set our initial state to indicate that we are first starting to
-         * look for a chunk header.
-         */
-        state = STATE_AWAITING_CHUNK_HEADER;
-    }
-
-    /**
-     * See
-     * the general contract of the <code>read</code>
-     * method of <code>InputStream</code>.
-     *
-     * @return     the next byte of data, or <code>-1</code> if the end of the
-     *             stream is reached.
-     * @exception  IOException  if an I/O error occurs.
-     * @see        java.io.FilterInputStream#in
-     */
-    public synchronized int read() throws IOException {
-        ensureOpen();
-        if (chunkPos >= chunkCount) {
-            if (readAhead(true) <= 0) {
-                return -1;
-            }
-        }
-        return chunkData[chunkPos++] & 0xff;
-    }
-
-
-    /**
-     * Reads bytes from this stream into the specified byte array, starting at
-     * the given offset.
-     *
-     * @param      b     destination buffer.
-     * @param      off   offset at which to start storing bytes.
-     * @param      len   maximum number of bytes to read.
-     * @return     the number of bytes read, or <code>-1</code> if the end of
-     *             the stream has been reached.
-     * @exception  IOException  if an I/O error occurs.
-     */
-    public synchronized int read(byte b[], int off, int len)
-        throws IOException
-    {
-        ensureOpen();
-        if ((off < 0) || (off > b.length) || (len < 0) ||
-            ((off + len) > b.length) || ((off + len) < 0)) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return 0;
-        }
-
-        int avail = chunkCount - chunkPos;
-        if (avail <= 0) {
-            /*
-             * Optimization: if we're in the middle of the chunk read
-             * directly from the underlying stream into the caller's
-             * buffer
-             */
-            if (state == STATE_READING_CHUNK) {
-                return fastRead( b, off, len );
-            }
-
-            /*
-             * We're not in the middle of a chunk so we must read ahead
-             * until there is some chunk data available.
-             */
-            avail = readAhead(true);
-            if (avail < 0) {
-                return -1;      /* EOF */
-            }
-        }
-        int cnt = (avail < len) ? avail : len;
-        System.arraycopy(chunkData, chunkPos, b, off, cnt);
-        chunkPos += cnt;
-
-        return cnt;
-    }
-
-    /**
-     * Returns the number of bytes that can be read from this input
-     * stream without blocking.
-     *
-     * @return     the number of bytes that can be read from this input
-     *             stream without blocking.
-     * @exception  IOException  if an I/O error occurs.
-     * @see        java.io.FilterInputStream#in
-     */
-    public synchronized int available() throws IOException {
-        ensureOpen();
-
-        int avail = chunkCount - chunkPos;
-        if(avail > 0) {
-            return avail;
-        }
-
-        avail = readAhead(false);
-
-        if (avail < 0) {
-            return 0;
-        } else  {
-            return avail;
-        }
-    }
-
-    /**
-     * Close the stream by either returning the connection to the
-     * keep alive cache or closing the underlying stream.
-     * <p>
-     * If the chunked response hasn't been completely read we
-     * try to "hurry" to the end of the response. If this is
-     * possible (without blocking) then the connection can be
-     * returned to the keep alive cache.
-     *
-     * @exception  IOException  if an I/O error occurs.
-     */
-    public synchronized void close() throws IOException {
-        if (closed) {
-            return;
-        }
-        closeUnderlying();
-        closed = true;
-    }
-
-    /**
-     * Hurry the input stream by reading everything from the underlying
-     * stream. If the last chunk (and optional trailers) can be read without
-     * blocking then the stream is considered hurried.
-     * <p>
-     * Note that if an error has occured or we can't get to last chunk
-     * without blocking then this stream can't be hurried and should be
-     * closed.
-     */
-    public synchronized boolean hurry() {
-        if (in == null || error) {
-            return false;
-        }
-
-        try {
-            readAhead(false);
-        } catch (Exception e) {
-            return false;
-        }
-
-        if (error) {
-            return false;
-        }
-
-        return (state == STATE_DONE);
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/ChunkedOutputStream.java b/ojluni/src/main/java/sun/net/www/http/ChunkedOutputStream.java
deleted file mode 100644
index 2a0e35a..0000000
--- a/ojluni/src/main/java/sun/net/www/http/ChunkedOutputStream.java
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright (c) 2004, 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 sun.net.www.http;
-
-import java.io.*;
-
-/**
- * OutputStream that sends the output to the underlying stream using chunked
- * encoding as specified in RFC 2068.
- */
-public class ChunkedOutputStream extends PrintStream {
-
-    /* Default chunk size (including chunk header) if not specified */
-    static final int DEFAULT_CHUNK_SIZE = 4096;
-    private static final byte[] CRLF = {'\r', '\n'};
-    private static final int CRLF_SIZE = CRLF.length;
-    private static final byte[] FOOTER = CRLF;
-    private static final int FOOTER_SIZE = CRLF_SIZE;
-    private static final byte[] EMPTY_CHUNK_HEADER = getHeader(0);
-    private static final int EMPTY_CHUNK_HEADER_SIZE = getHeaderSize(0);
-
-    /* internal buffer */
-    private byte buf[];
-    /* size of data (excluding footers and headers) already stored in buf */
-    private int size;
-    /* current index in buf (i.e. buf[count] */
-    private int count;
-    /* number of bytes to be filled up to complete a data chunk
-     * currently being built */
-    private int spaceInCurrentChunk;
-
-    /* underlying stream */
-    private PrintStream out;
-
-    /* the chunk size we use */
-    private int preferredChunkDataSize;
-    private int preferedHeaderSize;
-    private int preferredChunkGrossSize;
-    /* header for a complete Chunk */
-    private byte[] completeHeader;
-
-    /* return the size of the header for a particular chunk size */
-    private static int getHeaderSize(int size) {
-        return (Integer.toHexString(size)).length() + CRLF_SIZE;
-    }
-
-    /* return a header for a particular chunk size */
-    private static byte[] getHeader(int size){
-        try {
-            String hexStr =  Integer.toHexString(size);
-            byte[] hexBytes = hexStr.getBytes("US-ASCII");
-            byte[] header = new byte[getHeaderSize(size)];
-            for (int i=0; i<hexBytes.length; i++)
-                header[i] = hexBytes[i];
-            header[hexBytes.length] = CRLF[0];
-            header[hexBytes.length+1] = CRLF[1];
-            return header;
-        } catch (java.io.UnsupportedEncodingException e) {
-            /* This should never happen */
-            throw new InternalError(e.getMessage());
-        }
-    }
-
-    public ChunkedOutputStream(PrintStream o) {
-        this(o, DEFAULT_CHUNK_SIZE);
-    }
-
-    public ChunkedOutputStream(PrintStream o, int size) {
-        super(o);
-        out = o;
-
-        if (size <= 0) {
-            size = DEFAULT_CHUNK_SIZE;
-        }
-
-        /* Adjust the size to cater for the chunk header - eg: if the
-         * preferred chunk size is 1k this means the chunk size should
-         * be 1017 bytes (differs by 7 from preferred size because of
-         * 3 bytes for chunk size in hex and CRLF (header) and CRLF (footer)).
-         *
-         * If headerSize(adjusted_size) is shorter then headerSize(size)
-         * then try to use the extra byte unless headerSize(adjusted_size+1)
-         * increases back to headerSize(size)
-         */
-        if (size > 0) {
-            int adjusted_size = size - getHeaderSize(size) - FOOTER_SIZE;
-            if (getHeaderSize(adjusted_size+1) < getHeaderSize(size)){
-                adjusted_size++;
-            }
-            size = adjusted_size;
-        }
-
-        if (size > 0) {
-            preferredChunkDataSize = size;
-        } else {
-            preferredChunkDataSize = DEFAULT_CHUNK_SIZE -
-                    getHeaderSize(DEFAULT_CHUNK_SIZE) - FOOTER_SIZE;
-        }
-
-        preferedHeaderSize = getHeaderSize(preferredChunkDataSize);
-        preferredChunkGrossSize = preferedHeaderSize + preferredChunkDataSize
-                + FOOTER_SIZE;
-        completeHeader = getHeader(preferredChunkDataSize);
-
-        /* start with an initial buffer */
-        buf = new byte[preferredChunkDataSize + 32];
-        reset();
-    }
-
-    /*
-     * Flush a buffered, completed chunk to an underlying stream. If the data in
-     * the buffer is insufficient to build up a chunk of "preferredChunkSize"
-     * then the data do not get flushed unless flushAll is true. If flushAll is
-     * true then the remaining data builds up a last chunk which size is smaller
-     * than preferredChunkSize, and then the last chunk gets flushed to
-     * underlying stream. If flushAll is true and there is no data in a buffer
-     * at all then an empty chunk (containing a header only) gets flushed to
-     * underlying stream.
-     */
-     private void flush(boolean flushAll) {
-        if (spaceInCurrentChunk == 0) {
-            /* flush a completed chunk to underlying stream */
-            out.write(buf, 0, preferredChunkGrossSize);
-            out.flush();
-            reset();
-        } else if (flushAll){
-            /* complete the last chunk and flush it to underlying stream */
-            if (size > 0){
-                /* adjust a header start index in case the header of the last
-                 * chunk is shorter then preferedHeaderSize */
-
-                int adjustedHeaderStartIndex = preferedHeaderSize -
-                        getHeaderSize(size);
-
-                /* write header */
-                System.arraycopy(getHeader(size), 0, buf,
-                        adjustedHeaderStartIndex, getHeaderSize(size));
-
-                /* write footer */
-                buf[count++] = FOOTER[0];
-                buf[count++] = FOOTER[1];
-
-                //send the last chunk to underlying stream
-                out.write(buf, adjustedHeaderStartIndex, count - adjustedHeaderStartIndex);
-            } else {
-                //send an empty chunk (containing just a header) to underlying stream
-                out.write(EMPTY_CHUNK_HEADER, 0, EMPTY_CHUNK_HEADER_SIZE);
-            }
-
-            out.flush();
-            reset();
-         }
-    }
-
-    @Override
-    public boolean checkError() {
-        return out.checkError();
-    }
-
-    /* Check that the output stream is still open */
-    private void ensureOpen() {
-        if (out == null)
-            setError();
-    }
-
-   /*
-    * Writes data from b[] to an internal buffer and stores the data as data
-    * chunks of a following format: {Data length in Hex}{CRLF}{data}{CRLF}
-    * The size of the data is preferredChunkSize. As soon as a completed chunk
-    * is read from b[] a process of reading from b[] suspends, the chunk gets
-    * flushed to the underlying stream and then the reading process from b[]
-    * continues. When there is no more sufficient data in b[] to build up a
-    * chunk of preferredChunkSize size the data get stored as an incomplete
-    * chunk of a following format: {space for data length}{CRLF}{data}
-    * The size of the data is of course smaller than preferredChunkSize.
-    */
-    @Override
-    public synchronized void write(byte b[], int off, int len) {
-        ensureOpen();
-        if ((off < 0) || (off > b.length) || (len < 0) ||
-            ((off + len) > b.length) || ((off + len) < 0)) {
-            throw new IndexOutOfBoundsException();
-        } else if (len == 0) {
-            return;
-        }
-
-        /* if b[] contains enough data then one loop cycle creates one complete
-         * data chunk with a header, body and a footer, and then flushes the
-         * chunk to the underlying stream. Otherwise, the last loop cycle
-         * creates incomplete data chunk with empty header and with no footer
-         * and stores this incomplete chunk in an internal buffer buf[]
-         */
-        int bytesToWrite = len;
-        int inputIndex = off;  /* the index of the byte[] currently being written */
-
-        do {
-            /* enough data to complete a chunk */
-            if (bytesToWrite >= spaceInCurrentChunk) {
-
-                /* header */
-                for (int i=0; i<completeHeader.length; i++)
-                    buf[i] = completeHeader[i];
-
-                /* data */
-                System.arraycopy(b, inputIndex, buf, count, spaceInCurrentChunk);
-                inputIndex += spaceInCurrentChunk;
-                bytesToWrite -= spaceInCurrentChunk;
-                count += spaceInCurrentChunk;
-
-                /* footer */
-                buf[count++] = FOOTER[0];
-                buf[count++] = FOOTER[1];
-                spaceInCurrentChunk = 0; //chunk is complete
-
-                flush(false);
-                if (checkError()){
-                    break;
-                }
-            }
-
-            /* not enough data to build a chunk */
-            else {
-                /* header */
-                /* do not write header if not enough bytes to build a chunk yet */
-
-                /* data */
-                System.arraycopy(b, inputIndex, buf, count, bytesToWrite);
-                count += bytesToWrite;
-                size += bytesToWrite;
-                spaceInCurrentChunk -= bytesToWrite;
-                bytesToWrite = 0;
-
-                /* footer */
-                /* do not write header if not enough bytes to build a chunk yet */
-            }
-        } while (bytesToWrite > 0);
-    }
-
-    @Override
-    public synchronized void write(int _b) {
-        byte b[] = {(byte)_b};
-        write(b, 0, 1);
-    }
-
-    public synchronized void reset() {
-        count = preferedHeaderSize;
-        size = 0;
-        spaceInCurrentChunk = preferredChunkDataSize;
-    }
-
-    public int size() {
-        return size;
-    }
-
-    @Override
-    public synchronized void close() {
-        ensureOpen();
-
-        /* if we have buffer a chunked send it */
-        if (size > 0) {
-            flush(true);
-        }
-
-        /* send a zero length chunk */
-        flush(true);
-
-        /* don't close the underlying stream */
-        out = null;
-    }
-
-    @Override
-    public synchronized void flush() {
-        ensureOpen();
-        if (size > 0) {
-            flush(true);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/HttpCapture.java b/ojluni/src/main/java/sun/net/www/http/HttpCapture.java
deleted file mode 100644
index 7035295..0000000
--- a/ojluni/src/main/java/sun/net/www/http/HttpCapture.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.http;
-
-import java.io.*;
-import java.util.ArrayList;
-import java.util.regex.*;
-import sun.net.NetProperties;
-import sun.util.logging.PlatformLogger;
-
-/**
- * Main class of the HTTP traffic capture tool.
- * Captures are triggered by the sun.net.http.captureRules system property.
- * If set, it should point to a file containing the capture rules.
- * Format for the file is simple:
- * - 1 rule per line
- * - Lines starting with a # are considered comments and ignored
- * - a rule is a pair of a regular expression and file pattern, separated by a comma
- * - The regular expression is applied to URLs, if it matches, the traffic for
- *   that URL will be captured in the associated file.
- * - if the file name contains a '%d', then that sequence will be replaced by a
- *   unique random number for each URL. This allow for multi-threaded captures
- *   of URLs matching the same pattern.
- * - Rules are checked in sequence, in the same order as in the file, until a
- *   match is found or the end of the list is reached.
- *
- * Examples of rules:
- * www\.sun\.com , sun%d.log
- * yahoo\.com\/.*asf , yahoo.log
- *
- * @author jccollet
- */
-public class HttpCapture {
-    private File file = null;
-    private boolean incoming = true;
-    private BufferedWriter out = null;
-    private static boolean initialized = false;
-    private static volatile ArrayList<Pattern> patterns = null;
-    private static volatile ArrayList<String> capFiles = null;
-
-    private static synchronized void init() {
-        initialized = true;
-        String rulesFile = java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<String>() {
-                public String run() {
-                    return NetProperties.get("sun.net.http.captureRules");
-                }
-            });
-        if (rulesFile != null && !rulesFile.isEmpty()) {
-            BufferedReader in;
-            try {
-                in = new BufferedReader(new FileReader(rulesFile));
-            } catch (FileNotFoundException ex) {
-                return;
-            }
-            try {
-                String line = in.readLine();
-                while (line != null) {
-                    line = line.trim();
-                    if (!line.startsWith("#")) {
-                        // skip line if it's a comment
-                        String[] s = line.split(",");
-                        if (s.length == 2) {
-                            if (patterns == null) {
-                                patterns = new ArrayList<Pattern>();
-                                capFiles = new ArrayList<String>();
-                            }
-                            patterns.add(Pattern.compile(s[0].trim()));
-                            capFiles.add(s[1].trim());
-                        }
-                    }
-                    line = in.readLine();
-                }
-            } catch (IOException ioe) {
-
-            } finally {
-                try {
-                    in.close();
-                } catch (IOException ex) {
-                }
-            }
-        }
-    }
-
-    private static synchronized boolean isInitialized() {
-        return initialized;
-    }
-
-    private HttpCapture(File f, java.net.URL url) {
-        file = f;
-        try {
-            out = new BufferedWriter(new FileWriter(file, true));
-            out.write("URL: " + url + "\n");
-        } catch (IOException ex) {
-            PlatformLogger.getLogger(HttpCapture.class.getName()).severe(null, ex);
-        }
-    }
-
-    public synchronized void sent(int c) throws IOException {
-        if (incoming) {
-            out.write("\n------>\n");
-            incoming = false;
-            out.flush();
-        }
-        out.write(c);
-    }
-
-    public synchronized void received(int c) throws IOException {
-        if (!incoming) {
-            out.write("\n<------\n");
-            incoming = true;
-            out.flush();
-        }
-        out.write(c);
-    }
-
-    public synchronized void flush() throws IOException {
-        out.flush();
-    }
-
-    public static HttpCapture getCapture(java.net.URL url) {
-        if (!isInitialized()) {
-            init();
-        }
-        if (patterns == null || patterns.isEmpty()) {
-            return null;
-        }
-        String s = url.toString();
-        for (int i = 0; i < patterns.size(); i++) {
-            Pattern p = patterns.get(i);
-            if (p.matcher(s).find()) {
-                String f = capFiles.get(i);
-                File fi;
-                if (f.indexOf("%d") >= 0) {
-                    java.util.Random rand = new java.util.Random();
-                    do {
-                        String f2 = f.replace("%d", Integer.toString(rand.nextInt()));
-                        fi = new File(f2);
-                    } while (fi.exists());
-                } else {
-                    fi = new File(f);
-                }
-                return new HttpCapture(fi, url);
-            }
-        }
-        return null;
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/HttpCaptureInputStream.java b/ojluni/src/main/java/sun/net/www/http/HttpCaptureInputStream.java
deleted file mode 100644
index ff0edf5..0000000
--- a/ojluni/src/main/java/sun/net/www/http/HttpCaptureInputStream.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.http;
-import java.io.*;
-
-/**
- * A Simple FilterInputStream subclass to capture HTTP traffic.
- * Every byte read is also passed to the HttpCapture class.
- *
- * @author jccollet
- */
-public class HttpCaptureInputStream extends FilterInputStream {
-    private HttpCapture capture = null;
-
-    public HttpCaptureInputStream(InputStream in, HttpCapture cap) {
-        super(in);
-        capture = cap;
-    }
-
-    @Override
-    public int read() throws IOException {
-        int i = super.read();
-        capture.received(i);
-        return i;
-    }
-
-    @Override
-    public void close() throws IOException {
-        try {
-            capture.flush();
-        } catch (IOException iOException) {
-        }
-        super.close();
-    }
-
-    @Override
-    public int read(byte[] b) throws IOException {
-        int ret = super.read(b);
-        for (int i = 0; i < ret; i++) {
-            capture.received(b[i]);
-        }
-        return ret;
-    }
-
-    @Override
-    public int read(byte[] b, int off, int len) throws IOException {
-        int ret = super.read(b, off, len);
-        for (int i = 0; i < ret; i++) {
-            capture.received(b[off+i]);
-        }
-        return ret;
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/HttpCaptureOutputStream.java b/ojluni/src/main/java/sun/net/www/http/HttpCaptureOutputStream.java
deleted file mode 100644
index e402c1c..0000000
--- a/ojluni/src/main/java/sun/net/www/http/HttpCaptureOutputStream.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.http;
-import java.io.*;
-
-/**
- * A Simple FilterOutputStream subclass to capture HTTP traffic.
- * Every byte written is also passed to the HttpCapture class.
- *
- * @author jccollet
- */
-public class HttpCaptureOutputStream extends FilterOutputStream {
-    private HttpCapture capture = null;
-
-    public HttpCaptureOutputStream(OutputStream out, HttpCapture cap) {
-        super(out);
-        capture = cap;
-    }
-
-    @Override
-    public void write(int b) throws IOException {
-        capture.sent(b);
-        out.write(b);
-    }
-
-    @Override
-    public void write(byte[] ba) throws IOException {
-        for (byte b : ba) {
-            capture.sent(b);
-        }
-        out.write(ba);
-    }
-
-    @Override
-    public void write(byte[] b, int off, int len) throws IOException {
-        for (int i = off; i < len; i++) {
-            capture.sent(b[i]);
-        }
-        out.write(b, off, len);
-    }
-
-    @Override
-    public void flush() throws IOException {
-        try {
-            capture.flush();
-        } catch (IOException iOException) {
-        }
-        super.flush();
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/HttpClient.java b/ojluni/src/main/java/sun/net/www/http/HttpClient.java
deleted file mode 100644
index 09e0dbb..0000000
--- a/ojluni/src/main/java/sun/net/www/http/HttpClient.java
+++ /dev/null
@@ -1,995 +0,0 @@
-/*
- * Copyright (c) 1994, 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 sun.net.www.http;
-
-import java.io.*;
-import java.net.*;
-import java.util.Locale;
-import sun.net.NetworkClient;
-import sun.net.ProgressSource;
-import sun.net.www.MessageHeader;
-import sun.net.www.HeaderParser;
-import sun.net.www.MeteredStream;
-import sun.net.www.ParseUtil;
-import sun.net.www.protocol.http.HttpURLConnection;
-import sun.util.logging.PlatformLogger;
-import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*;
-
-/**
- * @author Herb Jellinek
- * @author Dave Brown
- */
-public class HttpClient extends NetworkClient {
-    // whether this httpclient comes from the cache
-    protected boolean cachedHttpClient = false;
-
-    protected boolean inCache;
-
-    // Http requests we send
-    MessageHeader requests;
-
-    // Http data we send with the headers
-    PosterOutputStream poster = null;
-
-    // true if we are in streaming mode (fixed length or chunked)
-    boolean streaming;
-
-    // if we've had one io error
-    boolean failedOnce = false;
-
-    /** Response code for CONTINUE */
-    private boolean ignoreContinue = true;
-    private static final int    HTTP_CONTINUE = 100;
-
-    /** Default port number for http daemons. REMIND: make these private */
-    static final int    httpPortNumber = 80;
-
-    /** return default port number (subclasses may override) */
-    protected int getDefaultPort () { return httpPortNumber; }
-
-    static private int getDefaultPort(String proto) {
-        if ("http".equalsIgnoreCase(proto))
-            return 80;
-        if ("https".equalsIgnoreCase(proto))
-            return 443;
-        return -1;
-    }
-
-    /* All proxying (generic as well as instance-specific) may be
-     * disabled through use of this flag
-     */
-    protected boolean proxyDisabled;
-
-    // are we using proxy in this instance?
-    public boolean usingProxy = false;
-    // target host, port for the URL
-    protected String host;
-    protected int port;
-
-    /* where we cache currently open, persistent connections */
-    protected static KeepAliveCache kac = new KeepAliveCache();
-
-    private static boolean keepAliveProp = true;
-
-    // retryPostProp is true by default so as to preserve behavior
-    // from previous releases.
-    private static boolean retryPostProp = true;
-
-    volatile boolean keepingAlive = false;     /* this is a keep-alive connection */
-    int keepAliveConnections = -1;    /* number of keep-alives left */
-
-    /**Idle timeout value, in milliseconds. Zero means infinity,
-     * iff keepingAlive=true.
-     * Unfortunately, we can't always believe this one.  If I'm connected
-     * through a Netscape proxy to a server that sent me a keep-alive
-     * time of 15 sec, the proxy unilaterally terminates my connection
-     * after 5 sec.  So we have to hard code our effective timeout to
-     * 4 sec for the case where we're using a proxy. *SIGH*
-     */
-    int keepAliveTimeout = 0;
-
-    /** whether the response is to be cached */
-    private CacheRequest cacheRequest = null;
-
-    /** Url being fetched. */
-    protected URL       url;
-
-    /* if set, the client will be reused and must not be put in cache */
-    public boolean reuse = false;
-
-    // Traffic capture tool, if configured. See HttpCapture class for info
-    private HttpCapture capture = null;
-
-    private static final PlatformLogger logger = HttpURLConnection.getHttpLogger();
-    private static void logFinest(String msg) {
-        if (logger.isLoggable(PlatformLogger.FINEST)) {
-            logger.finest(msg);
-        }
-    }
-
-    /**
-     * A NOP method kept for backwards binary compatibility
-     * @deprecated -- system properties are no longer cached.
-     */
-    @Deprecated
-    public static synchronized void resetProperties() {
-    }
-
-    int getKeepAliveTimeout() {
-        return keepAliveTimeout;
-    }
-
-    static {
-        String keepAlive = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.keepAlive"));
-
-        String retryPost = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("sun.net.http.retryPost"));
-
-        if (keepAlive != null) {
-            keepAliveProp = Boolean.parseBoolean(keepAlive);
-        } else {
-            keepAliveProp = true;
-        }
-
-        if (retryPost != null) {
-            retryPostProp = Boolean.parseBoolean(retryPost);
-        } else
-            retryPostProp = true;
-
-    }
-
-    /**
-     * @return true iff http keep alive is set (i.e. enabled).  Defaults
-     *          to true if the system property http.keepAlive isn't set.
-     */
-    public boolean getHttpKeepAliveSet() {
-        return keepAliveProp;
-    }
-
-
-    protected HttpClient() {
-    }
-
-    private HttpClient(URL url)
-    throws IOException {
-        this(url, (String)null, -1, false);
-    }
-
-    protected HttpClient(URL url,
-                         boolean proxyDisabled) throws IOException {
-        this(url, null, -1, proxyDisabled);
-    }
-
-    /* This package-only CTOR should only be used for FTP piggy-backed on HTTP
-     * HTTP URL's that use this won't take advantage of keep-alive.
-     * Additionally, this constructor may be used as a last resort when the
-     * first HttpClient gotten through New() failed (probably b/c of a
-     * Keep-Alive mismatch).
-     *
-     * XXX That documentation is wrong ... it's not package-private any more
-     */
-    public HttpClient(URL url, String proxyHost, int proxyPort)
-    throws IOException {
-        this(url, proxyHost, proxyPort, false);
-    }
-
-    protected HttpClient(URL url, Proxy p, int to) throws IOException {
-        proxy = (p == null) ? Proxy.NO_PROXY : p;
-        this.host = url.getHost();
-        this.url = url;
-        port = url.getPort();
-        if (port == -1) {
-            port = getDefaultPort();
-        }
-        setConnectTimeout(to);
-
-        capture = HttpCapture.getCapture(url);
-        openServer();
-    }
-
-    static protected Proxy newHttpProxy(String proxyHost, int proxyPort,
-                                      String proto) {
-        if (proxyHost == null || proto == null)
-            return Proxy.NO_PROXY;
-        int pport = proxyPort < 0 ? getDefaultPort(proto) : proxyPort;
-        InetSocketAddress saddr = InetSocketAddress.createUnresolved(proxyHost, pport);
-        return new Proxy(Proxy.Type.HTTP, saddr);
-    }
-
-    /*
-     * This constructor gives "ultimate" flexibility, including the ability
-     * to bypass implicit proxying.  Sometimes we need to be using tunneling
-     * (transport or network level) instead of proxying (application level),
-     * for example when we don't want the application level data to become
-     * visible to third parties.
-     *
-     * @param url               the URL to which we're connecting
-     * @param proxy             proxy to use for this URL (e.g. forwarding)
-     * @param proxyPort         proxy port to use for this URL
-     * @param proxyDisabled     true to disable default proxying
-     */
-    private HttpClient(URL url, String proxyHost, int proxyPort,
-                       boolean proxyDisabled)
-        throws IOException {
-        this(url, proxyDisabled ? Proxy.NO_PROXY :
-             newHttpProxy(proxyHost, proxyPort, "http"), -1);
-    }
-
-    public HttpClient(URL url, String proxyHost, int proxyPort,
-                       boolean proxyDisabled, int to)
-        throws IOException {
-        this(url, proxyDisabled ? Proxy.NO_PROXY :
-             newHttpProxy(proxyHost, proxyPort, "http"), to);
-    }
-
-    /* This class has no public constructor for HTTP.  This method is used to
-     * get an HttpClient to the specifed URL.  If there's currently an
-     * active HttpClient to that server/port, you'll get that one.
-     */
-    public static HttpClient New(URL url)
-    throws IOException {
-        return HttpClient.New(url, Proxy.NO_PROXY, -1, true, null);
-    }
-
-    public static HttpClient New(URL url, boolean useCache)
-        throws IOException {
-        return HttpClient.New(url, Proxy.NO_PROXY, -1, useCache, null);
-    }
-
-    public static HttpClient New(URL url, Proxy p, int to, boolean useCache,
-        HttpURLConnection httpuc) throws IOException
-    {
-        if (p == null) {
-            p = Proxy.NO_PROXY;
-        }
-        HttpClient ret = null;
-        /* see if one's already around */
-        if (useCache) {
-            ret = kac.get(url, null);
-            if (ret != null && httpuc != null &&
-                httpuc.streaming() &&
-                httpuc.getRequestMethod() == "POST") {
-                if (!ret.available()) {
-                    ret.inCache = false;
-                    ret.closeServer();
-                    ret = null;
-                }
-            }
-
-            if (ret != null) {
-                if ((ret.proxy != null && ret.proxy.equals(p)) ||
-                    (ret.proxy == null && p == null)) {
-                    synchronized (ret) {
-                        ret.cachedHttpClient = true;
-                        assert ret.inCache;
-                        ret.inCache = false;
-                        if (httpuc != null && ret.needsTunneling())
-                            httpuc.setTunnelState(TUNNELING);
-                        logFinest("KeepAlive stream retrieved from the cache, " + ret);
-                    }
-                } else {
-                    // We cannot return this connection to the cache as it's
-                    // KeepAliveTimeout will get reset. We simply close the connection.
-                    // This should be fine as it is very rare that a connection
-                    // to the same host will not use the same proxy.
-                    synchronized(ret) {
-                        ret.inCache = false;
-                        ret.closeServer();
-                    }
-                    ret = null;
-                }
-            }
-        }
-        if (ret == null) {
-            ret = new HttpClient(url, p, to);
-        } else {
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) {
-                    security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort());
-                } else {
-                    security.checkConnect(url.getHost(), url.getPort());
-                }
-            }
-            ret.url = url;
-        }
-        return ret;
-    }
-
-    public static HttpClient New(URL url, Proxy p, int to,
-        HttpURLConnection httpuc) throws IOException
-    {
-        return New(url, p, to, true, httpuc);
-    }
-
-    public static HttpClient New(URL url, String proxyHost, int proxyPort,
-                                 boolean useCache)
-        throws IOException {
-        return New(url, newHttpProxy(proxyHost, proxyPort, "http"),
-            -1, useCache, null);
-    }
-
-    public static HttpClient New(URL url, String proxyHost, int proxyPort,
-                                 boolean useCache, int to,
-                                 HttpURLConnection httpuc)
-        throws IOException {
-        return New(url, newHttpProxy(proxyHost, proxyPort, "http"),
-            to, useCache, httpuc);
-    }
-
-    /* return it to the cache as still usable, if:
-     * 1) It's keeping alive, AND
-     * 2) It still has some connections left, AND
-     * 3) It hasn't had a error (PrintStream.checkError())
-     * 4) It hasn't timed out
-     *
-     * If this client is not keepingAlive, it should have been
-     * removed from the cache in the parseHeaders() method.
-     */
-
-    public void finished() {
-        if (reuse) /* will be reused */
-            return;
-        keepAliveConnections--;
-        poster = null;
-        if (keepAliveConnections > 0 && isKeepingAlive() &&
-               !(serverOutput.checkError())) {
-            /* This connection is keepingAlive && still valid.
-             * Return it to the cache.
-             */
-            putInKeepAliveCache();
-        } else {
-            closeServer();
-        }
-    }
-
-    protected synchronized boolean available() {
-        boolean available = true;
-        int old = -1;
-
-        try {
-            try {
-                old = serverSocket.getSoTimeout();
-                serverSocket.setSoTimeout(1);
-                BufferedInputStream tmpbuf =
-                        new BufferedInputStream(serverSocket.getInputStream());
-                int r = tmpbuf.read();
-                if (r == -1) {
-                    logFinest("HttpClient.available(): " +
-                            "read returned -1: not available");
-                    available = false;
-                }
-            } catch (SocketTimeoutException e) {
-                logFinest("HttpClient.available(): " +
-                        "SocketTimeout: its available");
-            } finally {
-                if (old != -1)
-                    serverSocket.setSoTimeout(old);
-            }
-        } catch (IOException e) {
-            logFinest("HttpClient.available(): " +
-                        "SocketException: not available");
-            available = false;
-        }
-        return available;
-    }
-
-    protected synchronized void putInKeepAliveCache() {
-        if (inCache) {
-            assert false : "Duplicate put to keep alive cache";
-            return;
-        }
-        inCache = true;
-        kac.put(url, null, this);
-    }
-
-    protected synchronized boolean isInKeepAliveCache() {
-        return inCache;
-    }
-
-    /*
-     * Close an idle connection to this URL (if it exists in the
-     * cache).
-     */
-    public void closeIdleConnection() {
-        HttpClient http = kac.get(url, null);
-        if (http != null) {
-            http.closeServer();
-        }
-    }
-
-    /* We're very particular here about what our InputStream to the server
-     * looks like for reasons that are apparent if you can decipher the
-     * method parseHTTP().  That's why this method is overidden from the
-     * superclass.
-     */
-    @Override
-    public void openServer(String server, int port) throws IOException {
-        serverSocket = doConnect(server, port);
-        try {
-            OutputStream out = serverSocket.getOutputStream();
-            if (capture != null) {
-                out = new HttpCaptureOutputStream(out, capture);
-            }
-            serverOutput = new PrintStream(
-                new BufferedOutputStream(out),
-                                         false, encoding);
-        } catch (UnsupportedEncodingException e) {
-            throw new InternalError(encoding+" encoding not found");
-        }
-        serverSocket.setTcpNoDelay(true);
-    }
-
-    /*
-     * Returns true if the http request should be tunneled through proxy.
-     * An example where this is the case is Https.
-     */
-    public boolean needsTunneling() {
-        return false;
-    }
-
-    /*
-     * Returns true if this httpclient is from cache
-     */
-    public synchronized boolean isCachedConnection() {
-        return cachedHttpClient;
-    }
-
-    /*
-     * Finish any work left after the socket connection is
-     * established.  In the normal http case, it's a NO-OP. Subclass
-     * may need to override this. An example is Https, where for
-     * direct connection to the origin server, ssl handshake needs to
-     * be done; for proxy tunneling, the socket needs to be converted
-     * into an SSL socket before ssl handshake can take place.
-     */
-    public void afterConnect() throws IOException, UnknownHostException {
-        // NO-OP. Needs to be overwritten by HttpsClient
-    }
-
-    /*
-     * call openServer in a privileged block
-     */
-    private synchronized void privilegedOpenServer(final InetSocketAddress server)
-         throws IOException
-    {
-        try {
-            java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedExceptionAction<Void>() {
-                    public Void run() throws IOException {
-                    openServer(server.getHostString(), server.getPort());
-                    return null;
-                }
-            });
-        } catch (java.security.PrivilegedActionException pae) {
-            throw (IOException) pae.getException();
-        }
-    }
-
-    /*
-     * call super.openServer
-     */
-    private void superOpenServer(final String proxyHost,
-                                 final int proxyPort)
-        throws IOException, UnknownHostException
-    {
-        super.openServer(proxyHost, proxyPort);
-    }
-
-    /*
-     */
-    protected synchronized void openServer() throws IOException {
-
-        SecurityManager security = System.getSecurityManager();
-
-        if (security != null) {
-            security.checkConnect(host, port);
-        }
-
-        if (keepingAlive) { // already opened
-            return;
-        }
-
-        if (url.getProtocol().equals("http") ||
-            url.getProtocol().equals("https") ) {
-
-            if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) {
-                sun.net.www.URLConnection.setProxiedHost(host);
-                privilegedOpenServer((InetSocketAddress) proxy.address());
-                usingProxy = true;
-                return;
-            } else {
-                // make direct connection
-                openServer(host, port);
-                usingProxy = false;
-                return;
-            }
-
-        } else {
-            /* we're opening some other kind of url, most likely an
-             * ftp url.
-             */
-            if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) {
-                sun.net.www.URLConnection.setProxiedHost(host);
-                privilegedOpenServer((InetSocketAddress) proxy.address());
-                usingProxy = true;
-                return;
-            } else {
-                // make direct connection
-                super.openServer(host, port);
-                usingProxy = false;
-                return;
-            }
-        }
-    }
-
-    public String getURLFile() throws IOException {
-
-        String fileName = url.getFile();
-        if ((fileName == null) || (fileName.length() == 0))
-            fileName = "/";
-
-        /**
-         * proxyDisabled is set by subclass HttpsClient!
-         */
-        if (usingProxy && !proxyDisabled) {
-            // Do not use URLStreamHandler.toExternalForm as the fragment
-            // should not be part of the RequestURI. It should be an
-            // absolute URI which does not have a fragment part.
-            StringBuffer result = new StringBuffer(128);
-            result.append(url.getProtocol());
-            result.append(":");
-            if (url.getAuthority() != null && url.getAuthority().length() > 0) {
-                result.append("//");
-                result.append(url.getAuthority());
-            }
-            if (url.getPath() != null) {
-                result.append(url.getPath());
-            }
-            if (url.getQuery() != null) {
-                result.append('?');
-                result.append(url.getQuery());
-            }
-
-            fileName =  result.toString();
-        }
-        if (fileName.indexOf('\n') == -1)
-            return fileName;
-        else
-            throw new java.net.MalformedURLException("Illegal character in URL");
-    }
-
-    /**
-     * @deprecated
-     */
-    @Deprecated
-    public void writeRequests(MessageHeader head) {
-        requests = head;
-        requests.print(serverOutput);
-        serverOutput.flush();
-    }
-
-    public void writeRequests(MessageHeader head,
-                              PosterOutputStream pos) throws IOException {
-        requests = head;
-        requests.print(serverOutput);
-        poster = pos;
-        if (poster != null)
-            poster.writeTo(serverOutput);
-        serverOutput.flush();
-    }
-
-    public void writeRequests(MessageHeader head,
-                              PosterOutputStream pos,
-                              boolean streaming) throws IOException {
-        this.streaming = streaming;
-        writeRequests(head, pos);
-    }
-
-    /** Parse the first line of the HTTP request.  It usually looks
-        something like: "HTTP/1.0 <number> comment\r\n". */
-
-    public boolean parseHTTP(MessageHeader responses, ProgressSource pi, HttpURLConnection httpuc)
-    throws IOException {
-        /* If "HTTP/*" is found in the beginning, return true.  Let
-         * HttpURLConnection parse the mime header itself.
-         *
-         * If this isn't valid HTTP, then we don't try to parse a header
-         * out of the beginning of the response into the responses,
-         * and instead just queue up the output stream to it's very beginning.
-         * This seems most reasonable, and is what the NN browser does.
-         */
-
-        try {
-            serverInput = serverSocket.getInputStream();
-            if (capture != null) {
-                serverInput = new HttpCaptureInputStream(serverInput, capture);
-            }
-            serverInput = new BufferedInputStream(serverInput);
-            return (parseHTTPHeader(responses, pi, httpuc));
-        } catch (SocketTimeoutException stex) {
-            // We don't want to retry the request when the app. sets a timeout
-            // but don't close the server if timeout while waiting for 100-continue
-            if (ignoreContinue) {
-                closeServer();
-            }
-            throw stex;
-        } catch (IOException e) {
-            closeServer();
-            cachedHttpClient = false;
-            if (!failedOnce && requests != null) {
-                failedOnce = true;
-                if (getRequestMethod().equals("CONNECT") ||
-                    (httpuc.getRequestMethod().equals("POST") &&
-                    (!retryPostProp || streaming))) {
-                    // do not retry the request
-                }  else {
-                    // try once more
-                    openServer();
-                    if (needsTunneling()) {
-                        httpuc.doTunneling();
-                    }
-                    afterConnect();
-                    writeRequests(requests, poster);
-                    return parseHTTP(responses, pi, httpuc);
-                }
-            }
-            throw e;
-        }
-
-    }
-
-    private boolean parseHTTPHeader(MessageHeader responses, ProgressSource pi, HttpURLConnection httpuc)
-    throws IOException {
-        /* If "HTTP/*" is found in the beginning, return true.  Let
-         * HttpURLConnection parse the mime header itself.
-         *
-         * If this isn't valid HTTP, then we don't try to parse a header
-         * out of the beginning of the response into the responses,
-         * and instead just queue up the output stream to it's very beginning.
-         * This seems most reasonable, and is what the NN browser does.
-         */
-
-        keepAliveConnections = -1;
-        keepAliveTimeout = 0;
-
-        boolean ret = false;
-        byte[] b = new byte[8];
-
-        try {
-            int nread = 0;
-            serverInput.mark(10);
-            while (nread < 8) {
-                int r = serverInput.read(b, nread, 8 - nread);
-                if (r < 0) {
-                    break;
-                }
-                nread += r;
-            }
-            String keep=null;
-            ret = b[0] == 'H' && b[1] == 'T'
-                    && b[2] == 'T' && b[3] == 'P' && b[4] == '/' &&
-                b[5] == '1' && b[6] == '.';
-            serverInput.reset();
-            if (ret) { // is valid HTTP - response started w/ "HTTP/1."
-                responses.parseHeader(serverInput);
-
-                // we've finished parsing http headers
-                // check if there are any applicable cookies to set (in cache)
-                CookieHandler cookieHandler = httpuc.getCookieHandler();
-                if (cookieHandler != null) {
-                    URI uri = ParseUtil.toURI(url);
-                    // NOTE: That cast from Map shouldn't be necessary but
-                    // a bug in javac is triggered under certain circumstances
-                    // So we do put the cast in as a workaround until
-                    // it is resolved.
-                    if (uri != null)
-                        cookieHandler.put(uri, responses.getHeaders());
-                }
-
-                /* decide if we're keeping alive:
-                 * This is a bit tricky.  There's a spec, but most current
-                 * servers (10/1/96) that support this differ in dialects.
-                 * If the server/client misunderstand each other, the
-                 * protocol should fall back onto HTTP/1.0, no keep-alive.
-                 */
-                if (usingProxy) { // not likely a proxy will return this
-                    keep = responses.findValue("Proxy-Connection");
-                }
-                if (keep == null) {
-                    keep = responses.findValue("Connection");
-                }
-                if (keep != null && keep.toLowerCase(Locale.US).equals("keep-alive")) {
-                    /* some servers, notably Apache1.1, send something like:
-                     * "Keep-Alive: timeout=15, max=1" which we should respect.
-                     */
-                    HeaderParser p = new HeaderParser(
-                            responses.findValue("Keep-Alive"));
-                    if (p != null) {
-                        /* default should be larger in case of proxy */
-                        keepAliveConnections = p.findInt("max", usingProxy?50:5);
-                        keepAliveTimeout = p.findInt("timeout", usingProxy?60:5);
-                    }
-                } else if (b[7] != '0') {
-                    /*
-                     * We're talking 1.1 or later. Keep persistent until
-                     * the server says to close.
-                     */
-                    if (keep != null) {
-                        /*
-                         * The only Connection token we understand is close.
-                         * Paranoia: if there is any Connection header then
-                         * treat as non-persistent.
-                         */
-                        keepAliveConnections = 1;
-                    } else {
-                        keepAliveConnections = 5;
-                    }
-                }
-            } else if (nread != 8) {
-                if (!failedOnce && requests != null) {
-                    failedOnce = true;
-                    if (getRequestMethod().equals("CONNECT") ||
-                        (httpuc.getRequestMethod().equals("POST") &&
-                        (!retryPostProp || streaming))) {
-                        // do not retry the request
-                    } else {
-                        closeServer();
-                        cachedHttpClient = false;
-                        openServer();
-                        if (needsTunneling()) {
-                            httpuc.doTunneling();
-                        }
-                        afterConnect();
-                        writeRequests(requests, poster);
-                        return parseHTTP(responses, pi, httpuc);
-                    }
-                }
-                throw new SocketException("Unexpected end of file from server");
-            } else {
-                // we can't vouche for what this is....
-                responses.set("Content-type", "unknown/unknown");
-            }
-        } catch (IOException e) {
-            throw e;
-        }
-
-        int code = -1;
-        try {
-            String resp;
-            resp = responses.getValue(0);
-            /* should have no leading/trailing LWS
-             * expedite the typical case by assuming it has
-             * form "HTTP/1.x <WS> 2XX <mumble>"
-             */
-            int ind;
-            ind = resp.indexOf(' ');
-            while(resp.charAt(ind) == ' ')
-                ind++;
-            code = Integer.parseInt(resp.substring(ind, ind + 3));
-        } catch (Exception e) {}
-
-        if (code == HTTP_CONTINUE && ignoreContinue) {
-            responses.reset();
-            return parseHTTPHeader(responses, pi, httpuc);
-        }
-
-        long cl = -1;
-
-        /*
-         * Set things up to parse the entity body of the reply.
-         * We should be smarter about avoid pointless work when
-         * the HTTP method and response code indicate there will be
-         * no entity body to parse.
-         */
-        String te = responses.findValue("Transfer-Encoding");
-        if (te != null && te.equalsIgnoreCase("chunked")) {
-            serverInput = new ChunkedInputStream(serverInput, this, responses);
-
-            /*
-             * If keep alive not specified then close after the stream
-             * has completed.
-             */
-            if (keepAliveConnections <= 1) {
-                keepAliveConnections = 1;
-                keepingAlive = false;
-            } else {
-                keepingAlive = true;
-            }
-            failedOnce = false;
-        } else {
-
-            /*
-             * If it's a keep alive connection then we will keep
-             * (alive if :-
-             * 1. content-length is specified, or
-             * 2. "Not-Modified" or "No-Content" responses - RFC 2616 states that
-             *    204 or 304 response must not include a message body.
-             */
-            String cls = responses.findValue("content-length");
-            if (cls != null) {
-                try {
-                    cl = Long.parseLong(cls);
-                } catch (NumberFormatException e) {
-                    cl = -1;
-                }
-            }
-            String requestLine = requests.getKey(0);
-
-            if ((requestLine != null &&
-                 (requestLine.startsWith("HEAD"))) ||
-                code == HttpURLConnection.HTTP_NOT_MODIFIED ||
-                code == HttpURLConnection.HTTP_NO_CONTENT) {
-                cl = 0;
-            }
-
-            if (keepAliveConnections > 1 &&
-                (cl >= 0 ||
-                 code == HttpURLConnection.HTTP_NOT_MODIFIED ||
-                 code == HttpURLConnection.HTTP_NO_CONTENT)) {
-                keepingAlive = true;
-                failedOnce = false;
-            } else if (keepingAlive) {
-                /* Previously we were keeping alive, and now we're not.  Remove
-                 * this from the cache (but only here, once) - otherwise we get
-                 * multiple removes and the cache count gets messed up.
-                 */
-                keepingAlive=false;
-            }
-        }
-
-        /* wrap a KeepAliveStream/MeteredStream around it if appropriate */
-
-        if (cl > 0) {
-            // In this case, content length is well known, so it is okay
-            // to wrap the input stream with KeepAliveStream/MeteredStream.
-
-            if (pi != null) {
-                // Progress monitor is enabled
-                pi.setContentType(responses.findValue("content-type"));
-            }
-
-            if (isKeepingAlive())   {
-                // Wrap KeepAliveStream if keep alive is enabled.
-                logFinest("KeepAlive stream used: " + url);
-                serverInput = new KeepAliveStream(serverInput, pi, cl, this);
-                failedOnce = false;
-            }
-            else        {
-                serverInput = new MeteredStream(serverInput, pi, cl);
-            }
-        }
-        else if (cl == -1)  {
-            // In this case, content length is unknown - the input
-            // stream would simply be a regular InputStream or
-            // ChunkedInputStream.
-
-            if (pi != null) {
-                // Progress monitoring is enabled.
-
-                pi.setContentType(responses.findValue("content-type"));
-
-                // Wrap MeteredStream for tracking indeterministic
-                // progress, even if the input stream is ChunkedInputStream.
-                serverInput = new MeteredStream(serverInput, pi, cl);
-            }
-            else    {
-                // Progress monitoring is disabled, and there is no
-                // need to wrap an unknown length input stream.
-
-                // ** This is an no-op **
-            }
-        }
-        else    {
-            if (pi != null)
-                pi.finishTracking();
-        }
-
-        return ret;
-    }
-
-    public synchronized InputStream getInputStream() {
-        return serverInput;
-    }
-
-    public OutputStream getOutputStream() {
-        return serverOutput;
-    }
-
-    @Override
-    public String toString() {
-        return getClass().getName()+"("+url+")";
-    }
-
-    public final boolean isKeepingAlive() {
-        return getHttpKeepAliveSet() && keepingAlive;
-    }
-
-    public void setCacheRequest(CacheRequest cacheRequest) {
-        this.cacheRequest = cacheRequest;
-    }
-
-    CacheRequest getCacheRequest() {
-        return cacheRequest;
-    }
-
-    String getRequestMethod() {
-        if (requests != null) {
-            String requestLine = requests.getKey(0);
-            if (requestLine != null) {
-                return requestLine.split("\\s+")[0];
-            }
-        }
-        return "";
-    }
-
-    @Override
-    protected void finalize() throws Throwable {
-        // This should do nothing.  The stream finalizer will
-        // close the fd.
-    }
-
-    public void setDoNotRetry(boolean value) {
-        // failedOnce is used to determine if a request should be retried.
-        failedOnce = value;
-    }
-
-    public void setIgnoreContinue(boolean value) {
-        ignoreContinue = value;
-    }
-
-    /* Use only on connections in error. */
-    @Override
-    public void closeServer() {
-        try {
-            keepingAlive = false;
-            serverSocket.close();
-        } catch (Exception e) {}
-    }
-
-    /**
-     * @return the proxy host being used for this client, or null
-     *          if we're not going through a proxy
-     */
-    public String getProxyHostUsed() {
-        if (!usingProxy) {
-            return null;
-        } else {
-            return ((InetSocketAddress)proxy.address()).getHostString();
-        }
-    }
-
-    /**
-     * @return the proxy port being used for this client.  Meaningless
-     *          if getProxyHostUsed() gives null.
-     */
-    public int getProxyPortUsed() {
-        if (usingProxy)
-            return ((InetSocketAddress)proxy.address()).getPort();
-        return -1;
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/Hurryable.java b/ojluni/src/main/java/sun/net/www/http/Hurryable.java
deleted file mode 100644
index 49a74fc..0000000
--- a/ojluni/src/main/java/sun/net/www/http/Hurryable.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.http;
-
-/**
- * A <code>Hurryable</code> is a class that has been instructed to complete
- * its input processing so as to make resource associated with that input
- * available to others.
- */
-public interface Hurryable {
-
-    /**
-     * @return a <code>boolean</code> indicating if the stream has been
-     *         hurried or not.
-     */
-    boolean hurry();
-
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/KeepAliveCache.java b/ojluni/src/main/java/sun/net/www/http/KeepAliveCache.java
deleted file mode 100644
index 16f02d7..0000000
--- a/ojluni/src/main/java/sun/net/www/http/KeepAliveCache.java
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Copyright (c) 1996, 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 sun.net.www.http;
-
-import java.io.IOException;
-import java.io.NotSerializableException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.net.URL;
-
-/**
- * A class that implements a cache of idle Http connections for keep-alive
- *
- * @author Stephen R. Pietrowicz (NCSA)
- * @author Dave Brown
- */
-public class KeepAliveCache
-    extends HashMap<KeepAliveKey, ClientVector>
-    implements Runnable {
-    private static final long serialVersionUID = -2937172892064557949L;
-
-    /* maximum # keep-alive connections to maintain at once
-     * This should be 2 by the HTTP spec, but because we don't support pipe-lining
-     * a larger value is more appropriate. So we now set a default of 5, and the value
-     * refers to the number of idle connections per destination (in the cache) only.
-     * It can be reset by setting system property "http.maxConnections".
-     */
-    static final int MAX_CONNECTIONS = 5;
-    static int result = -1;
-    static int getMaxConnections() {
-        if (result == -1) {
-            result = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction("http.maxConnections",
-                                                         MAX_CONNECTIONS))
-                .intValue();
-            if (result <= 0)
-                result = MAX_CONNECTIONS;
-        }
-            return result;
-    }
-
-    static final int LIFETIME = 5000;
-
-    private Thread keepAliveTimer = null;
-
-    /**
-     * Constructor
-     */
-    public KeepAliveCache() {}
-
-    /**
-     * Register this URL and HttpClient (that supports keep-alive) with the cache
-     * @param url  The URL contains info about the host and port
-     * @param http The HttpClient to be cached
-     */
-    public synchronized void put(final URL url, Object obj, HttpClient http) {
-        boolean startThread = (keepAliveTimer == null);
-        if (!startThread) {
-            if (!keepAliveTimer.isAlive()) {
-                startThread = true;
-            }
-        }
-        if (startThread) {
-            clear();
-            /* Unfortunately, we can't always believe the keep-alive timeout we got
-             * back from the server.  If I'm connected through a Netscape proxy
-             * to a server that sent me a keep-alive
-             * time of 15 sec, the proxy unilaterally terminates my connection
-             * The robustness to get around this is in HttpClient.parseHTTP()
-             */
-            final KeepAliveCache cache = this;
-            java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<Void>() {
-                public Void run() {
-                   // We want to create the Keep-Alive-Timer in the
-                    // system threadgroup
-                    ThreadGroup grp = Thread.currentThread().getThreadGroup();
-                    ThreadGroup parent = null;
-                    while ((parent = grp.getParent()) != null) {
-                        grp = parent;
-                    }
-
-                    keepAliveTimer = new Thread(grp, cache, "Keep-Alive-Timer");
-                    keepAliveTimer.setDaemon(true);
-                    keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2);
-                    // Set the context class loader to null in order to avoid
-                    // keeping a strong reference to an application classloader.
-                    keepAliveTimer.setContextClassLoader(null);
-                    keepAliveTimer.start();
-                    return null;
-                }
-            });
-        }
-
-        KeepAliveKey key = new KeepAliveKey(url, obj);
-        ClientVector v = super.get(key);
-
-        if (v == null) {
-            int keepAliveTimeout = http.getKeepAliveTimeout();
-            v = new ClientVector(keepAliveTimeout > 0?
-                                 keepAliveTimeout*1000 : LIFETIME);
-            v.put(http);
-            super.put(key, v);
-        } else {
-            v.put(http);
-        }
-    }
-
-    /* remove an obsolete HttpClient from its VectorCache */
-    public synchronized void remove (HttpClient h, Object obj) {
-        KeepAliveKey key = new KeepAliveKey(h.url, obj);
-        ClientVector v = super.get(key);
-        if (v != null) {
-            v.remove(h);
-            if (v.empty()) {
-                removeVector(key);
-            }
-        }
-    }
-
-    /* called by a clientVector thread when all its connections have timed out
-     * and that vector of connections should be removed.
-     */
-    synchronized void removeVector(KeepAliveKey k) {
-        super.remove(k);
-    }
-
-    /**
-     * Check to see if this URL has a cached HttpClient
-     */
-    public synchronized HttpClient get(URL url, Object obj) {
-
-        KeepAliveKey key = new KeepAliveKey(url, obj);
-        ClientVector v = super.get(key);
-        if (v == null) { // nothing in cache yet
-            return null;
-        }
-        return v.get();
-    }
-
-    /* Sleeps for an alloted timeout, then checks for timed out connections.
-     * Errs on the side of caution (leave connections idle for a relatively
-     * short time).
-     */
-    @Override
-    public void run() {
-        do {
-            try {
-                Thread.sleep(LIFETIME);
-            } catch (InterruptedException e) {}
-            synchronized (this) {
-                /* Remove all unused HttpClients.  Starting from the
-                 * bottom of the stack (the least-recently used first).
-                 * REMIND: It'd be nice to not remove *all* connections
-                 * that aren't presently in use.  One could have been added
-                 * a second ago that's still perfectly valid, and we're
-                 * needlessly axing it.  But it's not clear how to do this
-                 * cleanly, and doing it right may be more trouble than it's
-                 * worth.
-                 */
-
-                long currentTime = System.currentTimeMillis();
-
-                ArrayList<KeepAliveKey> keysToRemove
-                    = new ArrayList<KeepAliveKey>();
-
-                for (KeepAliveKey key : keySet()) {
-                    ClientVector v = get(key);
-                    synchronized (v) {
-                        int i;
-
-                        for (i = 0; i < v.size(); i++) {
-                            KeepAliveEntry e = v.elementAt(i);
-                            if ((currentTime - e.idleStartTime) > v.nap) {
-                                HttpClient h = e.hc;
-                                h.closeServer();
-                            } else {
-                                break;
-                            }
-                        }
-                        v.subList(0, i).clear();
-
-                        if (v.size() == 0) {
-                            keysToRemove.add(key);
-                        }
-                    }
-                }
-
-                for (KeepAliveKey key : keysToRemove) {
-                    removeVector(key);
-                }
-            }
-        } while (size() > 0);
-
-        return;
-    }
-
-    /*
-     * Do not serialize this class!
-     */
-    private void writeObject(java.io.ObjectOutputStream stream)
-    throws IOException {
-        throw new NotSerializableException();
-    }
-
-    private void readObject(java.io.ObjectInputStream stream)
-    throws IOException, ClassNotFoundException {
-        throw new NotSerializableException();
-    }
-}
-
-/* FILO order for recycling HttpClients, should run in a thread
- * to time them out.  If > maxConns are in use, block.
- */
-
-
-class ClientVector extends java.util.Stack<KeepAliveEntry> {
-    private static final long serialVersionUID = -8680532108106489459L;
-
-    // sleep time in milliseconds, before cache clear
-    int nap;
-
-
-
-    ClientVector (int nap) {
-        this.nap = nap;
-    }
-
-    synchronized HttpClient get() {
-        if (empty()) {
-            return null;
-        } else {
-            // Loop until we find a connection that has not timed out
-            HttpClient hc = null;
-            long currentTime = System.currentTimeMillis();
-            do {
-                KeepAliveEntry e = pop();
-                if ((currentTime - e.idleStartTime) > nap) {
-                    e.hc.closeServer();
-                } else {
-                    hc = e.hc;
-                }
-            } while ((hc== null) && (!empty()));
-            return hc;
-        }
-    }
-
-    /* return a still valid, unused HttpClient */
-    synchronized void put(HttpClient h) {
-        if (size() >= KeepAliveCache.getMaxConnections()) {
-            h.closeServer(); // otherwise the connection remains in limbo
-        } else {
-            push(new KeepAliveEntry(h, System.currentTimeMillis()));
-        }
-    }
-
-    /*
-     * Do not serialize this class!
-     */
-    private void writeObject(java.io.ObjectOutputStream stream)
-    throws IOException {
-        throw new NotSerializableException();
-    }
-
-    private void readObject(java.io.ObjectInputStream stream)
-    throws IOException, ClassNotFoundException {
-        throw new NotSerializableException();
-    }
-}
-
-
-class KeepAliveKey {
-    private String      protocol = null;
-    private String      host = null;
-    private int         port = 0;
-    private Object      obj = null; // additional key, such as socketfactory
-
-    /**
-     * Constructor
-     *
-     * @param url the URL containing the protocol, host and port information
-     */
-    public KeepAliveKey(URL url, Object obj) {
-        this.protocol = url.getProtocol();
-        this.host = url.getHost();
-        this.port = url.getPort();
-        this.obj = obj;
-    }
-
-    /**
-     * Determine whether or not two objects of this type are equal
-     */
-    @Override
-    public boolean equals(Object obj) {
-        if ((obj instanceof KeepAliveKey) == false)
-            return false;
-        KeepAliveKey kae = (KeepAliveKey)obj;
-        return host.equals(kae.host)
-            && (port == kae.port)
-            && protocol.equals(kae.protocol)
-            && this.obj == kae.obj;
-    }
-
-    /**
-     * The hashCode() for this object is the string hashCode() of
-     * concatenation of the protocol, host name and port.
-     */
-    @Override
-    public int hashCode() {
-        String str = protocol+host+port;
-        return this.obj == null? str.hashCode() :
-            str.hashCode() + this.obj.hashCode();
-    }
-}
-
-class KeepAliveEntry {
-    HttpClient hc;
-    long idleStartTime;
-
-    KeepAliveEntry(HttpClient hc, long idleStartTime) {
-        this.hc = hc;
-        this.idleStartTime = idleStartTime;
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/KeepAliveStream.java b/ojluni/src/main/java/sun/net/www/http/KeepAliveStream.java
deleted file mode 100644
index 5d7bb57..0000000
--- a/ojluni/src/main/java/sun/net/www/http/KeepAliveStream.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (c) 1996, 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 sun.net.www.http;
-
-import java.io.*;
-import sun.net.ProgressSource;
-import sun.net.www.MeteredStream;
-
-/**
- * A stream that has the property of being able to be kept alive for
- * multiple downloads from the same server.
- *
- * @author Stephen R. Pietrowicz (NCSA)
- * @author Dave Brown
- */
-public
-class KeepAliveStream extends MeteredStream implements Hurryable {
-
-    // instance variables
-    HttpClient hc;
-
-    boolean hurried;
-
-    // has this KeepAliveStream been put on the queue for asynchronous cleanup.
-    protected boolean queuedForCleanup = false;
-
-    private static final KeepAliveStreamCleaner queue = new KeepAliveStreamCleaner();
-    private static Thread cleanerThread; // null
-
-    /**
-     * Constructor
-     */
-    public KeepAliveStream(InputStream is, ProgressSource pi, long expected, HttpClient hc)  {
-        super(is, pi, expected);
-        this.hc = hc;
-    }
-
-    /**
-     * Attempt to cache this connection
-     */
-    public void close() throws IOException  {
-        // If the inputstream is closed already, just return.
-        if (closed) {
-            return;
-        }
-
-        // If this stream has already been queued for cleanup.
-        if (queuedForCleanup) {
-            return;
-        }
-
-        // Skip past the data that's left in the Inputstream because
-        // some sort of error may have occurred.
-        // Do this ONLY if the skip won't block. The stream may have
-        // been closed at the beginning of a big file and we don't want
-        // to hang around for nothing. So if we can't skip without blocking
-        // we just close the socket and, therefore, terminate the keepAlive
-        // NOTE: Don't close super class
-        try {
-            if (expected > count) {
-                long nskip = (long) (expected - count);
-                if (nskip <= available()) {
-                    long n = 0;
-                    while (n < nskip) {
-                        nskip = nskip - n;
-                        n = skip(nskip);
-                    }
-                } else if (expected <= KeepAliveStreamCleaner.MAX_DATA_REMAINING && !hurried) {
-                    //put this KeepAliveStream on the queue so that the data remaining
-                    //on the socket can be cleanup asyncronously.
-                    queueForCleanup(new KeepAliveCleanerEntry(this, hc));
-                } else {
-                    hc.closeServer();
-                }
-            }
-            if (!closed && !hurried && !queuedForCleanup) {
-                hc.finished();
-            }
-        } finally {
-            if (pi != null)
-                pi.finishTracking();
-
-            if (!queuedForCleanup) {
-                // nulling out the underlying inputstream as well as
-                // httpClient to let gc collect the memories faster
-                in = null;
-                hc = null;
-                closed = true;
-            }
-        }
-    }
-
-    /* we explicitly do not support mark/reset */
-
-    public boolean markSupported()  {
-        return false;
-    }
-
-    public void mark(int limit) {}
-
-    public void reset() throws IOException {
-        throw new IOException("mark/reset not supported");
-    }
-
-    public synchronized boolean hurry() {
-        try {
-            /* CASE 0: we're actually already done */
-            if (closed || count >= expected) {
-                return false;
-            } else if (in.available() < (expected - count)) {
-                /* CASE I: can't meet the demand */
-                return false;
-            } else {
-                /* CASE II: fill our internal buffer
-                 * Remind: possibly check memory here
-                 */
-                int size = (int) (expected - count);
-                byte[] buf = new byte[size];
-                DataInputStream dis = new DataInputStream(in);
-                dis.readFully(buf);
-                in = new ByteArrayInputStream(buf);
-                hurried = true;
-                return true;
-            }
-        } catch (IOException e) {
-            // e.printStackTrace();
-            return false;
-        }
-    }
-
-    private static void queueForCleanup(KeepAliveCleanerEntry kace) {
-        synchronized(queue) {
-            if(!kace.getQueuedForCleanup()) {
-                if (!queue.offer(kace)) {
-                    kace.getHttpClient().closeServer();
-                    return;
-                }
-
-                kace.setQueuedForCleanup();
-                queue.notifyAll();
-            }
-
-            boolean startCleanupThread = (cleanerThread == null);
-            if (!startCleanupThread) {
-                if (!cleanerThread.isAlive()) {
-                    startCleanupThread = true;
-                }
-            }
-
-            if (startCleanupThread) {
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedAction<Void>() {
-                    public Void run() {
-                        // We want to create the Keep-Alive-SocketCleaner in the
-                        // system threadgroup
-                        ThreadGroup grp = Thread.currentThread().getThreadGroup();
-                        ThreadGroup parent = null;
-                        while ((parent = grp.getParent()) != null) {
-                            grp = parent;
-                        }
-
-                        cleanerThread = new Thread(grp, queue, "Keep-Alive-SocketCleaner");
-                        cleanerThread.setDaemon(true);
-                        cleanerThread.setPriority(Thread.MAX_PRIORITY - 2);
-                        // Set the context class loader to null in order to avoid
-                        // keeping a strong reference to an application classloader.
-                        cleanerThread.setContextClassLoader(null);
-                        cleanerThread.start();
-                        return null;
-                    }
-                });
-            }
-        } // queue
-    }
-
-    protected long remainingToRead() {
-        return expected - count;
-    }
-
-    protected void setClosed() {
-        in = null;
-        hc = null;
-        closed = true;
-    }
-}
-
-
-class KeepAliveCleanerEntry
-{
-    KeepAliveStream kas;
-    HttpClient hc;
-
-    public KeepAliveCleanerEntry(KeepAliveStream kas, HttpClient hc) {
-        this.kas = kas;
-        this.hc = hc;
-    }
-
-    protected KeepAliveStream getKeepAliveStream() {
-        return kas;
-    }
-
-    protected HttpClient getHttpClient() {
-        return hc;
-    }
-
-    protected void setQueuedForCleanup() {
-        kas.queuedForCleanup = true;
-    }
-
-    protected boolean getQueuedForCleanup() {
-        return kas.queuedForCleanup;
-    }
-
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/KeepAliveStreamCleaner.java b/ojluni/src/main/java/sun/net/www/http/KeepAliveStreamCleaner.java
deleted file mode 100644
index 87f0d09..0000000
--- a/ojluni/src/main/java/sun/net/www/http/KeepAliveStreamCleaner.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (c) 2005, 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 sun.net.www.http;
-
-import java.io.IOException;
-import java.util.LinkedList;
-import sun.net.NetProperties;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * This class is used to cleanup any remaining data that may be on a KeepAliveStream
- * so that the connection can be cached in the KeepAliveCache.
- * Instances of this class can be used as a FIFO queue for KeepAliveCleanerEntry objects.
- * Executing this Runnable removes each KeepAliveCleanerEntry from the Queue, reads
- * the reamining bytes on its KeepAliveStream, and if successful puts the connection in
- * the KeepAliveCache.
- *
- * @author Chris Hegarty
- */
-
-@SuppressWarnings("serial")  // never serialized
-class KeepAliveStreamCleaner
-    extends LinkedList<KeepAliveCleanerEntry>
-    implements Runnable
-{
-    // maximum amount of remaining data that we will try to cleanup
-    protected static int MAX_DATA_REMAINING = 512;
-
-    // maximum amount of KeepAliveStreams to be queued
-    protected static int MAX_CAPACITY = 10;
-
-    // timeout for both socket and poll on the queue
-    protected static final int TIMEOUT = 5000;
-
-    // max retries for skipping data
-    private static final int MAX_RETRIES = 5;
-
-    static {
-        final String maxDataKey = "http.KeepAlive.remainingData";
-        int maxData = AccessController.doPrivileged(
-            new PrivilegedAction<Integer>() {
-                public Integer run() {
-                    return NetProperties.getInteger(maxDataKey, MAX_DATA_REMAINING);
-                }}).intValue() * 1024;
-        MAX_DATA_REMAINING = maxData;
-
-        final String maxCapacityKey = "http.KeepAlive.queuedConnections";
-        int maxCapacity = AccessController.doPrivileged(
-            new PrivilegedAction<Integer>() {
-                public Integer run() {
-                    return NetProperties.getInteger(maxCapacityKey, MAX_CAPACITY);
-                }}).intValue();
-        MAX_CAPACITY = maxCapacity;
-
-    }
-
-
-    @Override
-    public boolean offer(KeepAliveCleanerEntry e) {
-        if (size() >= MAX_CAPACITY)
-            return false;
-
-        return super.offer(e);
-    }
-
-    @Override
-    public void run()
-    {
-        KeepAliveCleanerEntry kace = null;
-
-        do {
-            try {
-                synchronized(this) {
-                    long before = System.currentTimeMillis();
-                    long timeout = TIMEOUT;
-                    while ((kace = poll()) == null) {
-                        this.wait(timeout);
-
-                        long after = System.currentTimeMillis();
-                        long elapsed = after - before;
-                        if (elapsed > timeout) {
-                            /* one last try */
-                            kace = poll();
-                            break;
-                        }
-                        before = after;
-                        timeout -= elapsed;
-                    }
-                }
-
-                if(kace == null)
-                    break;
-
-                KeepAliveStream kas = kace.getKeepAliveStream();
-
-                if (kas != null) {
-                    synchronized(kas) {
-                        HttpClient hc = kace.getHttpClient();
-                        try {
-                            if (hc != null && !hc.isInKeepAliveCache()) {
-                                int oldTimeout = hc.getReadTimeout();
-                                hc.setReadTimeout(TIMEOUT);
-                                long remainingToRead = kas.remainingToRead();
-                                if (remainingToRead > 0) {
-                                    long n = 0;
-                                    int retries = 0;
-                                    while (n < remainingToRead && retries < MAX_RETRIES) {
-                                        remainingToRead = remainingToRead - n;
-                                        n = kas.skip(remainingToRead);
-                                        if (n == 0)
-                                            retries++;
-                                    }
-                                    remainingToRead = remainingToRead - n;
-                                }
-                                if (remainingToRead == 0) {
-                                    hc.setReadTimeout(oldTimeout);
-                                    hc.finished();
-                                } else
-                                    hc.closeServer();
-                            }
-                        } catch (IOException ioe) {
-                            hc.closeServer();
-                        } finally {
-                            kas.setClosed();
-                        }
-                    }
-                }
-            } catch (InterruptedException ie) { }
-        } while (kace != null);
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/http/PosterOutputStream.java b/ojluni/src/main/java/sun/net/www/http/PosterOutputStream.java
deleted file mode 100644
index eedd77e..0000000
--- a/ojluni/src/main/java/sun/net/www/http/PosterOutputStream.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.http;
-
-import java.io.*;
-import java.net.*;
-
-/**
- * Instances of this class are returned to applications for the purpose of
- * sending user data for a HTTP POST or PUT request. This class is used
- * when the content-length will be specified in the header of the request.
- * The semantics of ByteArrayOutputStream are extended so that
- * when close() is called, it is no longer possible to write
- * additional data to the stream. From this point the content length of
- * the request is fixed and cannot change.
- *
- * @author Michael McMahon
- */
-
-public class PosterOutputStream extends ByteArrayOutputStream {
-
-    private boolean closed;
-
-    /**
-     * Creates a new output stream for POST user data
-     */
-    public PosterOutputStream () {
-        super (256);
-    }
-
-    /**
-     * Writes the specified byte to this output stream.
-     *
-     * @param   b   the byte to be written.
-     */
-    public synchronized void write(int b) {
-        if (closed) {
-            return;
-        }
-        super.write (b);
-    }
-
-    /**
-     * Writes <code>len</code> bytes from the specified byte array
-     * starting at offset <code>off</code> to this output stream.
-     *
-     * @param   b     the data.
-     * @param   off   the start offset in the data.
-     * @param   len   the number of bytes to write.
-     */
-    public synchronized void write(byte b[], int off, int len) {
-        if (closed) {
-            return;
-        }
-        super.write (b, off, len);
-    }
-
-    /**
-     * Resets the <code>count</code> field of this output
-     * stream to zero, so that all currently accumulated output in the
-     * ouput stream is discarded. The output stream can be used again,
-     * reusing the already allocated buffer space. If the output stream
-     * has been closed, then this method has no effect.
-     *
-     * @see     java.io.ByteArrayInputStream#count
-     */
-    public synchronized void reset() {
-        if (closed) {
-            return;
-        }
-        super.reset ();
-    }
-
-    /**
-     * After close() has been called, it is no longer possible to write
-     * to this stream. Further calls to write will have no effect.
-     */
-    public synchronized void close() throws IOException {
-        closed = true;
-        super.close ();
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java
index e2b7fa1..24f2f3b 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java
@@ -52,7 +52,6 @@
 import sun.net.www.MessageHeader;
 import sun.net.www.MeteredStream;
 import sun.net.www.URLConnection;
-import sun.net.www.protocol.http.HttpURLConnection;
 import sun.net.ftp.FtpClient;
 import sun.net.ftp.FtpProtocolException;
 import sun.net.ProgressSource;
@@ -82,8 +81,10 @@
  */
 public class FtpURLConnection extends URLConnection {
 
-    // In case we have to use proxies, we use HttpURLConnection
-    HttpURLConnection http = null;
+// Android-changed: Removed support for proxying FTP over HTTP since it
+// relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+//    // In case we have to use proxies, we use HttpURLConnection
+//    HttpURLConnection http = null;
     private Proxy instProxy;
 
     InputStream is = null;
@@ -245,42 +246,50 @@
                         continue;
                     }
                     // OK, we have an http proxy
-                    InetSocketAddress paddr = (InetSocketAddress) p.address();
-                    try {
-                        http = new HttpURLConnection(url, p);
-                        http.setDoInput(getDoInput());
-                        http.setDoOutput(getDoOutput());
-                        if (connectTimeout >= 0) {
-                            http.setConnectTimeout(connectTimeout);
-                        }
-                        if (readTimeout >= 0) {
-                            http.setReadTimeout(readTimeout);
-                        }
-                        http.connect();
-                        connected = true;
-                        return;
-                    } catch (IOException ioe) {
-                        sel.connectFailed(uri, paddr, ioe);
-                        http = null;
-                    }
+                    // Android-changed: Removed support for proxying FTP over HTTP since it
+                    // relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+                    sel.connectFailed(uri, p.address(), new IOException("FTP connections over HTTP proxy not supported"));
+                    continue;
+//                    InetSocketAddress paddr = (InetSocketAddress) p.address();
+//                    try {
+//                        http = new HttpURLConnection(url, p);
+//                        http.setDoInput(getDoInput());
+//                        http.setDoOutput(getDoOutput());
+//                        if (connectTimeout >= 0) {
+//                            http.setConnectTimeout(connectTimeout);
+//                        }
+//                        if (readTimeout >= 0) {
+//                            http.setReadTimeout(readTimeout);
+//                        }
+//                        http.connect();
+//                        connected = true;
+//                        return;
+//                    } catch (IOException ioe) {
+//                        sel.connectFailed(uri, paddr, ioe);
+//                        http = null;
+//                    }
                 }
             }
         } else { // per connection proxy specified
             p = instProxy;
-            if (p.type() == Proxy.Type.HTTP) {
-                http = new HttpURLConnection(url, instProxy);
-                http.setDoInput(getDoInput());
-                http.setDoOutput(getDoOutput());
-                if (connectTimeout >= 0) {
-                    http.setConnectTimeout(connectTimeout);
-                }
-                if (readTimeout >= 0) {
-                    http.setReadTimeout(readTimeout);
-                }
-                http.connect();
-                connected = true;
-                return;
-            }
+// Android-changed: Removed support for proxying FTP over HTTP since it
+// relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+// As specified in the documentation for URL.openConnection(Proxy), we
+// ignore the unsupported proxy and attempt a normal (direct) connection
+//            if (p.type() == Proxy.Type.HTTP) {
+//                http = new HttpURLConnection(url, instProxy);
+//                http.setDoInput(getDoInput());
+//                http.setDoOutput(getDoOutput());
+//                if (connectTimeout >= 0) {
+//                    http.setConnectTimeout(connectTimeout);
+//                }
+//                if (readTimeout >= 0) {
+//                    http.setReadTimeout(readTimeout);
+//                }
+//                http.connect();
+//                connected = true;
+//                return;
+//            }
         }
 
         if (user == null) {
@@ -401,10 +410,11 @@
         if (!connected) {
             connect();
         }
-
-        if (http != null) {
-            return http.getInputStream();
-        }
+        // Android-changed: Removed support for proxying FTP over HTTP since it
+        // relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+//        if (http != null) {
+//            return http.getInputStream();
+//        }
 
         if (os != null) {
             throw new IOException("Already opened for output");
@@ -515,14 +525,15 @@
         if (!connected) {
             connect();
         }
-
-        if (http != null) {
-            OutputStream out = http.getOutputStream();
-            // getInputStream() is neccessary to force a writeRequests()
-            // on the http client.
-            http.getInputStream();
-            return out;
-        }
+// Android-changed: Removed support for proxying FTP over HTTP since it
+// relies on the removed sun.net.www.protocol.http.HttpURLConnection API.
+//        if (http != null) {
+//            OutputStream out = http.getOutputStream();
+//            // getInputStream() is neccessary to force a writeRequests()
+//            // on the http client.
+//            http.getInputStream();
+//            return out;
+//        }
 
         if (is != null) {
             throw new IOException("Already opened for input");
diff --git a/ojluni/src/main/java/sun/net/www/protocol/ftp/Handler.java b/ojluni/src/main/java/sun/net/www/protocol/ftp/Handler.java
index f5caad6..72143d9 100644
--- a/ojluni/src/main/java/sun/net/www/protocol/ftp/Handler.java
+++ b/ojluni/src/main/java/sun/net/www/protocol/ftp/Handler.java
@@ -30,12 +30,8 @@
 package sun.net.www.protocol.ftp;
 
 import java.io.IOException;
-import java.net.URL;
 import java.net.Proxy;
-import java.util.Map;
-import java.util.HashMap;
-import sun.net.ftp.FtpClient;
-import sun.net.www.protocol.http.HttpURLConnection;
+import java.net.URL;
 
 /** open an ftp connection given a URL */
 public class Handler extends java.net.URLStreamHandler {
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/AuthCache.java b/ojluni/src/main/java/sun/net/www/protocol/http/AuthCache.java
deleted file mode 100644
index 6af6dd6..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/AuthCache.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.net.www.protocol.http;
-
-/**
- * @author Michael McMahon
- *
- * Interface provided by internal http authentication cache.
- * NB. This API will be replaced in a future release, and should
- * not be made public.
- */
-
-public interface AuthCache {
-
-    /**
-     * Put an entry in the cache. pkey is a string specified as follows:
-     *
-     * A:[B:]C:D:E[:F]   Between 4 and 6 fields separated by ":"
-     *          where the fields have the following meaning:
-     * A is "s" or "p" for server or proxy authentication respectively
-     * B is optional and is the {@link AuthScheme}, e.g. BASIC, DIGEST, NTLM, etc
-     * C is either "http" or "https"
-     * D is the hostname
-     * E is the port number
-     * F is optional and if present is the realm
-     *
-     * Generally, two entries are created for each AuthCacheValue,
-     * one including the realm and one without the realm.
-     * Also, for some schemes (digest) multiple entries may be created
-     * with the same pkey, but with a different path value in
-     * the AuthCacheValue.
-     */
-    public void put (String pkey, AuthCacheValue value);
-
-    /**
-     * Get an entry from the cache based on pkey as described above, but also
-     * using a pathname (skey) and the cache must return an entry
-     * if skey is a sub-path of the AuthCacheValue.path field.
-     */
-    public AuthCacheValue get (String pkey, String skey);
-
-    /**
-     * remove the entry from the cache whose pkey is specified and
-     * whose path is equal to entry.path. If entry is null then
-     * all entries with the same pkey should be removed.
-     */
-    public void remove (String pkey, AuthCacheValue entry);
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheImpl.java b/ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheImpl.java
deleted file mode 100644
index c2ebf42..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheImpl.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.net.www.protocol.http;
-
-import java.io.IOException;
-import java.net.URL;
-import java.util.Hashtable;
-import java.util.LinkedList;
-import java.util.ListIterator;
-import java.util.Enumeration;
-import java.util.HashMap;
-
-/**
- * @author Michael McMahon
- */
-
-public class AuthCacheImpl implements AuthCache {
-    HashMap hashtable;
-
-    public AuthCacheImpl () {
-        hashtable = new HashMap ();
-    }
-
-    public void setMap (HashMap map) {
-        hashtable = map;
-    }
-
-    // put a value in map according to primary key + secondary key which
-    // is the path field of AuthenticationInfo
-
-    public synchronized void put (String pkey, AuthCacheValue value) {
-        LinkedList list = (LinkedList) hashtable.get (pkey);
-        String skey = value.getPath();
-        if (list == null) {
-            list = new LinkedList ();
-            hashtable.put (pkey, list);
-        }
-        // Check if the path already exists or a super-set of it exists
-        ListIterator iter = list.listIterator();
-        while (iter.hasNext()) {
-            AuthenticationInfo inf = (AuthenticationInfo)iter.next();
-            if (inf.path == null || inf.path.startsWith (skey)) {
-                iter.remove ();
-            }
-        }
-        iter.add (value);
-    }
-
-    // get a value from map checking both primary
-    // and secondary (urlpath) key
-
-    public synchronized AuthCacheValue get (String pkey, String skey) {
-        AuthenticationInfo result = null;
-        LinkedList list = (LinkedList) hashtable.get (pkey);
-        if (list == null || list.size() == 0) {
-            return null;
-        }
-        if (skey == null) {
-            // list should contain only one element
-            return (AuthenticationInfo)list.get (0);
-        }
-        ListIterator iter = list.listIterator();
-        while (iter.hasNext()) {
-            AuthenticationInfo inf = (AuthenticationInfo)iter.next();
-            if (skey.startsWith (inf.path)) {
-                return inf;
-            }
-        }
-        return null;
-    }
-
-    public synchronized void remove (String pkey, AuthCacheValue entry) {
-        LinkedList list = (LinkedList) hashtable.get (pkey);
-        if (list == null) {
-            return;
-        }
-        if (entry == null) {
-            list.clear();
-            return;
-        }
-        ListIterator iter = list.listIterator ();
-        while (iter.hasNext()) {
-            AuthenticationInfo inf = (AuthenticationInfo)iter.next();
-            if (entry.equals(inf)) {
-                iter.remove ();
-            }
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheValue.java b/ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheValue.java
deleted file mode 100644
index d2c003e..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheValue.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2003, 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 sun.net.www.protocol.http;
-
-import java.io.Serializable;
-import java.net.PasswordAuthentication;
-
-/**
- * AuthCacheValue: interface to minimise exposure to authentication cache
- * for external users (ie. plugin)
- *
- * @author Michael McMahon
- */
-
-public abstract class AuthCacheValue implements Serializable {
-
-    public enum Type {
-        Proxy,
-        Server
-    };
-
-    /**
-     * Caches authentication info entered by user.  See cacheKey()
-     */
-    static protected AuthCache cache = new AuthCacheImpl();
-
-    public static void setAuthCache (AuthCache map) {
-        cache = map;
-    }
-
-    /* Package private ctor to prevent extension outside package */
-
-    AuthCacheValue() {}
-
-    /**
-     * Proxy or Server
-     */
-    abstract Type getAuthType ();
-
-    /**
-     * Authentication scheme
-     */
-    abstract AuthScheme getAuthScheme();
-
-   /**
-    * name of server/proxy
-    */
-    abstract String getHost ();
-
-   /**
-    * portnumber of server/proxy
-    */
-    abstract int getPort();
-
-   /**
-    * realm of authentication if known
-    */
-    abstract String getRealm();
-
-    /**
-     * root path of realm or the request path if the root
-     * is not known yet.
-     */
-    abstract String getPath();
-
-    /**
-     * returns http or https
-     */
-    abstract String getProtocolScheme();
-
-    /**
-     * the credentials associated with this authentication
-     */
-    abstract PasswordAuthentication credentials();
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/AuthScheme.java b/ojluni/src/main/java/sun/net/www/protocol/http/AuthScheme.java
deleted file mode 100644
index 2c56632..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/AuthScheme.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.protocol.http;
-
-/* Authentication schemes supported by the http implementation. New schemes, if
- * supported, should be defined here.
- */
-public enum AuthScheme {
-    BASIC,
-    DIGEST,
-    NTLM,
-    NEGOTIATE,
-    KERBEROS,
-    UNKNOWN;
-}
-
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationHeader.java b/ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationHeader.java
deleted file mode 100644
index eee2579..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationHeader.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (c) 2002, 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 sun.net.www.protocol.http;
-
-import sun.net.www.*;
-import java.util.Iterator;
-import java.util.HashMap;
-
-/**
- * This class is used to parse the information in WWW-Authenticate: and Proxy-Authenticate:
- * headers. It searches among multiple header lines and within each header line
- * for the best currently supported scheme. It can also return a HeaderParser
- * containing the challenge data for that particular scheme.
- *
- * Some examples:
- *
- * WWW-Authenticate: Basic realm="foo" Digest realm="bar" NTLM
- *  Note the realm parameter must be associated with the particular scheme.
- *
- * or
- *
- * WWW-Authenticate: Basic realm="foo"
- * WWW-Authenticate: Digest realm="foo",qop="auth",nonce="thisisanunlikelynonce"
- * WWW-Authenticate: NTLM
- *
- * or
- *
- * WWW-Authenticate: Basic realm="foo"
- * WWW-Authenticate: NTLM ASKAJK9893289889QWQIOIONMNMN
- *
- * The last example shows how NTLM breaks the rules of rfc2617 for the structure of
- * the authentication header. This is the reason why the raw header field is used for ntlm.
- *
- * At present, the class chooses schemes in following order :
- *      1. Negotiate (if supported)
- *      2. Kerberos (if supported)
- *      3. Digest
- *      4. NTLM (if supported)
- *      5. Basic
- *
- * This choice can be modified by setting a system property:
- *
- *      -Dhttp.auth.preference="scheme"
- *
- * which in this case, specifies that "scheme" should be used as the auth scheme when offered
- * disregarding the default prioritisation. If scheme is not offered then the default priority
- * is used.
- *
- * Attention: when http.auth.preference is set as SPNEGO or Kerberos, it's actually "Negotiate
- * with SPNEGO" or "Negotiate with Kerberos", which means the user will prefer the Negotiate
- * scheme with GSS/SPNEGO or GSS/Kerberos mechanism.
- *
- * This also means that the real "Kerberos" scheme can never be set as a preference.
- */
-
-public class AuthenticationHeader {
-
-    MessageHeader rsp; // the response to be parsed
-    HeaderParser preferred;
-    String preferred_r; // raw Strings
-    private final HttpCallerInfo hci;   // un-schemed, need check
-
-    // When set true, do not use Negotiate even if the response
-    // headers suggest so.
-    boolean dontUseNegotiate = false;
-    static String authPref=null;
-
-    public String toString() {
-        return "AuthenticationHeader: prefer " + preferred_r;
-    }
-
-    static {
-        authPref = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetPropertyAction("http.auth.preference"));
-
-        // http.auth.preference can be set to SPNEGO or Kerberos.
-        // In fact they means "Negotiate with SPNEGO" and "Negotiate with
-        // Kerberos" separately, so here they are all translated into
-        // Negotiate. Read NegotiateAuthentication.java to see how they
-        // were used later.
-
-        if (authPref != null) {
-            authPref = authPref.toLowerCase();
-            if(authPref.equals("spnego") || authPref.equals("kerberos")) {
-                authPref = "negotiate";
-            }
-        }
-    }
-
-    String hdrname; // Name of the header to look for
-
-    /**
-     * parse a set of authentication headers and choose the preferred scheme
-     * that we support for a given host
-     */
-    public AuthenticationHeader (String hdrname, MessageHeader response,
-            HttpCallerInfo hci, boolean dontUseNegotiate) {
-        this.hci = hci;
-        this.dontUseNegotiate = dontUseNegotiate;
-        rsp = response;
-        this.hdrname = hdrname;
-        schemes = new HashMap();
-        parse();
-    }
-
-    public HttpCallerInfo getHttpCallerInfo() {
-        return hci;
-    }
-    /* we build up a map of scheme names mapped to SchemeMapValue objects */
-    static class SchemeMapValue {
-        SchemeMapValue (HeaderParser h, String r) {raw=r; parser=h;}
-        String raw;
-        HeaderParser parser;
-    }
-
-    HashMap schemes;
-
-    /* Iterate through each header line, and then within each line.
-     * If multiple entries exist for a particular scheme (unlikely)
-     * then the last one will be used. The
-     * preferred scheme that we support will be used.
-     */
-    private void parse () {
-        Iterator iter = rsp.multiValueIterator (hdrname);
-        while (iter.hasNext()) {
-            String raw = (String)iter.next();
-            HeaderParser hp = new HeaderParser (raw);
-            Iterator keys = hp.keys();
-            int i, lastSchemeIndex;
-            for (i=0, lastSchemeIndex = -1; keys.hasNext(); i++) {
-                keys.next();
-                if (hp.findValue(i) == null) { /* found a scheme name */
-                    if (lastSchemeIndex != -1) {
-                        HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
-                        String scheme = hpn.findKey(0);
-                        schemes.put (scheme, new SchemeMapValue (hpn, raw));
-                    }
-                    lastSchemeIndex = i;
-                }
-            }
-            if (i > lastSchemeIndex) {
-                HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
-                String scheme = hpn.findKey(0);
-                schemes.put (scheme, new SchemeMapValue (hpn, raw));
-            }
-        }
-
-        /* choose the best of them, the order is
-         * negotiate -> kerberos -> digest -> ntlm -> basic
-         */
-        SchemeMapValue v = null;
-        if (authPref == null || (v=(SchemeMapValue)schemes.get (authPref)) == null) {
-
-            if(v == null && !dontUseNegotiate) {
-                SchemeMapValue tmp = (SchemeMapValue)schemes.get("negotiate");
-                if(tmp != null) {
-                    if(hci == null || !NegotiateAuthentication.isSupported(new HttpCallerInfo(hci, "Negotiate"))) {
-                        tmp = null;
-                    }
-                    v = tmp;
-                }
-            }
-
-            if(v == null && !dontUseNegotiate) {
-                SchemeMapValue tmp = (SchemeMapValue)schemes.get("kerberos");
-                if(tmp != null) {
-                    // the Kerberos scheme is only observed in MS ISA Server. In
-                    // fact i think it's a Kerberos-mechnism-only Negotiate.
-                    // Since the Kerberos scheme is always accompanied with the
-                    // Negotiate scheme, so it seems impossible to reach this
-                    // line. Even if the user explicitly set http.auth.preference
-                    // as Kerberos, it means Negotiate with Kerberos, and the code
-                    // will still tried to use Negotiate at first.
-                    //
-                    // The only chance this line get executed is that the server
-                    // only suggest the Kerberos scheme.
-                    if(hci == null || !NegotiateAuthentication.isSupported(new HttpCallerInfo(hci, "Kerberos"))) {
-                        tmp = null;
-                    }
-                    v = tmp;
-                }
-            }
-
-            if(v == null) {
-                if ((v=(SchemeMapValue)schemes.get ("digest")) == null) {
-                    if (((v=(SchemeMapValue)schemes.get("ntlm"))==null)) {
-                        v = (SchemeMapValue)schemes.get ("basic");
-                    }
-                }
-            }
-        } else {    // authPref != null && it's found in reponses'
-            if (dontUseNegotiate && authPref.equals("negotiate")) {
-                v = null;
-            }
-        }
-
-        if (v != null) {
-            preferred = v.parser;
-            preferred_r = v.raw;
-        }
-    }
-
-    /**
-     * return a header parser containing the preferred authentication scheme (only).
-     * The preferred scheme is the strongest of the schemes proposed by the server.
-     * The returned HeaderParser will contain the relevant parameters for that scheme
-     */
-    public HeaderParser headerParser() {
-        return preferred;
-    }
-
-    /**
-     * return the name of the preferred scheme
-     */
-    public String scheme() {
-        if (preferred != null) {
-            return preferred.findKey(0);
-        } else {
-            return null;
-        }
-    }
-
-    /* return the raw header field for the preferred/chosen scheme */
-
-    public String raw () {
-        return preferred_r;
-    }
-
-    /**
-     * returns true is the header exists and contains a recognised scheme
-     */
-    public boolean isPresent () {
-        return preferred != null;
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationInfo.java b/ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationInfo.java
deleted file mode 100644
index 23e84ba..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationInfo.java
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Copyright (c) 1995, 2010, 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 sun.net.www.protocol.http;
-
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.net.PasswordAuthentication;
-import java.net.URL;
-import java.util.HashMap;
-
-import sun.net.www.HeaderParser;
-
-
-/**
- * AuthenticationInfo: Encapsulate the information needed to
- * authenticate a user to a server.
- *
- * @author Jon Payne
- * @author Herb Jellinek
- * @author Bill Foote
- */
-// REMIND:  It would be nice if this class understood about partial matching.
-//      If you're authorized for foo.com, chances are high you're also
-//      authorized for baz.foo.com.
-// NB:  When this gets implemented, be careful about the uncaching
-//      policy in HttpURLConnection.  A failure on baz.foo.com shouldn't
-//      uncache foo.com!
-
-public abstract class AuthenticationInfo extends AuthCacheValue implements Cloneable {
-
-    // Constants saying what kind of authroization this is.  This determines
-    // the namespace in the hash table lookup.
-    public static final char SERVER_AUTHENTICATION = 's';
-    public static final char PROXY_AUTHENTICATION = 'p';
-
-    /**
-     * If true, then simultaneous authentication requests to the same realm/proxy
-     * are serialized, in order to avoid a user having to type the same username/passwords
-     * repeatedly, via the Authenticator. Default is false, which means that this
-     * behavior is switched off.
-     */
-    static boolean serializeAuth;
-
-    static {
-        serializeAuth = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetBooleanAction(
-                "http.auth.serializeRequests")).booleanValue();
-    }
-
-    /* AuthCacheValue: */
-
-    transient protected PasswordAuthentication pw;
-
-    public PasswordAuthentication credentials() {
-        return pw;
-    }
-
-    public AuthCacheValue.Type getAuthType() {
-        return type == SERVER_AUTHENTICATION ?
-            AuthCacheValue.Type.Server:
-            AuthCacheValue.Type.Proxy;
-    }
-
-    AuthScheme getAuthScheme() {
-        return authScheme;
-    }
-
-    public String getHost() {
-        return host;
-    }
-    public int getPort() {
-        return port;
-    }
-    public String getRealm() {
-        return realm;
-    }
-    public String getPath() {
-        return path;
-    }
-    public String getProtocolScheme() {
-        return protocol;
-    }
-
-    /**
-     * requests is used to ensure that interaction with the
-     * Authenticator for a particular realm is single threaded.
-     * ie. if multiple threads need to get credentials from the user
-     * at the same time, then all but the first will block until
-     * the first completes its authentication.
-     */
-    static private HashMap<String,Thread> requests = new HashMap<>();
-
-    /* check if a request for this destination is in progress
-     * return false immediately if not. Otherwise block until
-     * request is finished and return true
-     */
-    static private boolean requestIsInProgress (String key) {
-        if (!serializeAuth) {
-            /* behavior is disabled. Revert to concurrent requests */
-            return false;
-        }
-        synchronized (requests) {
-            Thread t, c;
-            c = Thread.currentThread();
-            if ((t = requests.get(key)) == null) {
-                requests.put (key, c);
-                return false;
-            }
-            if (t == c) {
-                return false;
-            }
-            while (requests.containsKey(key)) {
-                try {
-                    requests.wait ();
-                } catch (InterruptedException e) {}
-            }
-        }
-        /* entry may be in cache now. */
-        return true;
-    }
-
-    /* signal completion of an authentication (whether it succeeded or not)
-     * so that other threads can continue.
-     */
-    static private void requestCompleted (String key) {
-        synchronized (requests) {
-            Thread thread = requests.get(key);
-            if (thread != null && thread == Thread.currentThread()) {
-                boolean waspresent = requests.remove(key) != null;
-                assert waspresent;
-            }
-            requests.notifyAll();
-        }
-    }
-
-    //public String toString () {
-        //return ("{"+type+":"+authScheme+":"+protocol+":"+host+":"+port+":"+realm+":"+path+"}");
-    //}
-
-    // REMIND:  This cache just grows forever.  We should put in a bounded
-    //          cache, or maybe something using WeakRef's.
-
-    /** The type (server/proxy) of authentication this is.  Used for key lookup */
-    char type;
-
-    /** The authentication scheme (basic/digest). Also used for key lookup */
-    AuthScheme authScheme;
-
-    /** The protocol/scheme (i.e. http or https ). Need to keep the caches
-     *  logically separate for the two protocols. This field is only used
-     *  when constructed with a URL (the normal case for server authentication)
-     *  For proxy authentication the protocol is not relevant.
-     */
-    String protocol;
-
-    /** The host we're authenticating against. */
-    String host;
-
-    /** The port on the host we're authenticating against. */
-    int port;
-
-    /** The realm we're authenticating against. */
-    String realm;
-
-    /** The shortest path from the URL we authenticated against. */
-    String path;
-
-    /** Use this constructor only for proxy entries */
-    public AuthenticationInfo(char type, AuthScheme authScheme, String host, int port, String realm) {
-        this.type = type;
-        this.authScheme = authScheme;
-        this.protocol = "";
-        this.host = host.toLowerCase();
-        this.port = port;
-        this.realm = realm;
-        this.path = null;
-    }
-
-    public Object clone() {
-        try {
-            return super.clone ();
-        } catch (CloneNotSupportedException e) {
-            // Cannot happen because Cloneable implemented by AuthenticationInfo
-            return null;
-        }
-    }
-
-    /*
-     * Constructor used to limit the authorization to the path within
-     * the URL. Use this constructor for origin server entries.
-     */
-    public AuthenticationInfo(char type, AuthScheme authScheme, URL url, String realm) {
-        this.type = type;
-        this.authScheme = authScheme;
-        this.protocol = url.getProtocol().toLowerCase();
-        this.host = url.getHost().toLowerCase();
-        this.port = url.getPort();
-        if (this.port == -1) {
-            this.port = url.getDefaultPort();
-        }
-        this.realm = realm;
-
-        String urlPath = url.getPath();
-        if (urlPath.length() == 0)
-            this.path = urlPath;
-        else {
-            this.path = reducePath (urlPath);
-        }
-
-    }
-
-    /*
-     * reduce the path to the root of where we think the
-     * authorization begins. This could get shorter as
-     * the url is traversed up following a successful challenge.
-     */
-    static String reducePath (String urlPath) {
-        int sepIndex = urlPath.lastIndexOf('/');
-        int targetSuffixIndex = urlPath.lastIndexOf('.');
-        if (sepIndex != -1)
-            if (sepIndex < targetSuffixIndex)
-                return urlPath.substring(0, sepIndex+1);
-            else
-                return urlPath;
-        else
-            return urlPath;
-    }
-
-    /**
-     * Returns info for the URL, for an HTTP server auth.  Used when we
-     * don't yet know the realm
-     * (i.e. when we're preemptively setting the auth).
-     */
-    static AuthenticationInfo getServerAuth(URL url) {
-        int port = url.getPort();
-        if (port == -1) {
-            port = url.getDefaultPort();
-        }
-        String key = SERVER_AUTHENTICATION + ":" + url.getProtocol().toLowerCase()
-                + ":" + url.getHost().toLowerCase() + ":" + port;
-        return getAuth(key, url);
-    }
-
-    /**
-     * Returns info for the URL, for an HTTP server auth.  Used when we
-     * do know the realm (i.e. when we're responding to a challenge).
-     * In this case we do not use the path because the protection space
-     * is identified by the host:port:realm only
-     */
-    static String getServerAuthKey(URL url, String realm, AuthScheme scheme) {
-        int port = url.getPort();
-        if (port == -1) {
-            port = url.getDefaultPort();
-        }
-        String key = SERVER_AUTHENTICATION + ":" + scheme + ":" + url.getProtocol().toLowerCase()
-                     + ":" + url.getHost().toLowerCase() + ":" + port + ":" + realm;
-        return key;
-    }
-
-    static AuthenticationInfo getServerAuth(String key) {
-        AuthenticationInfo cached = getAuth(key, null);
-        if ((cached == null) && requestIsInProgress (key)) {
-            /* check the cache again, it might contain an entry */
-            cached = getAuth(key, null);
-        }
-        return cached;
-    }
-
-
-    /**
-     * Return the AuthenticationInfo object from the cache if it's path is
-     * a substring of the supplied URLs path.
-     */
-    static AuthenticationInfo getAuth(String key, URL url) {
-        if (url == null) {
-            return (AuthenticationInfo)cache.get (key, null);
-        } else {
-            return (AuthenticationInfo)cache.get (key, url.getPath());
-        }
-    }
-
-    /**
-     * Returns a firewall authentication, for the given host/port.  Used
-     * for preemptive header-setting. Note, the protocol field is always
-     * blank for proxies.
-     */
-    static AuthenticationInfo getProxyAuth(String host, int port) {
-        String key = PROXY_AUTHENTICATION + "::" + host.toLowerCase() + ":" + port;
-        AuthenticationInfo result = (AuthenticationInfo) cache.get(key, null);
-        return result;
-    }
-
-    /**
-     * Returns a firewall authentication, for the given host/port and realm.
-     * Used in response to a challenge. Note, the protocol field is always
-     * blank for proxies.
-     */
-    static String getProxyAuthKey(String host, int port, String realm, AuthScheme scheme) {
-        String key = PROXY_AUTHENTICATION + ":" + scheme + "::" + host.toLowerCase()
-                        + ":" + port + ":" + realm;
-        return key;
-    }
-
-    static AuthenticationInfo getProxyAuth(String key) {
-        AuthenticationInfo cached = (AuthenticationInfo) cache.get(key, null);
-        if ((cached == null) && requestIsInProgress (key)) {
-            /* check the cache again, it might contain an entry */
-            cached = (AuthenticationInfo) cache.get(key, null);
-        }
-        return cached;
-    }
-
-
-    /**
-     * Add this authentication to the cache
-     */
-    void addToCache() {
-        String key = cacheKey(true);
-        cache.put(key, this);
-        if (supportsPreemptiveAuthorization()) {
-            cache.put(cacheKey(false), this);
-        }
-        endAuthRequest(key);
-    }
-
-    static void endAuthRequest (String key) {
-        if (!serializeAuth) {
-            return;
-        }
-        synchronized (requests) {
-            requestCompleted(key);
-        }
-    }
-
-    /**
-     * Remove this authentication from the cache
-     */
-    void removeFromCache() {
-        cache.remove(cacheKey(true), this);
-        if (supportsPreemptiveAuthorization()) {
-            cache.remove(cacheKey(false), this);
-        }
-    }
-
-    /**
-     * @return true if this authentication supports preemptive authorization
-     */
-    public abstract boolean supportsPreemptiveAuthorization();
-
-    /**
-     * @return the name of the HTTP header this authentication wants set.
-     *          This is used for preemptive authorization.
-     */
-    public String getHeaderName() {
-        if (type == SERVER_AUTHENTICATION) {
-            return "Authorization";
-        } else {
-            return "Proxy-authorization";
-        }
-    }
-
-    /**
-     * Calculates and returns the authentication header value based
-     * on the stored authentication parameters. If the calculation does not depend
-     * on the URL or the request method then these parameters are ignored.
-     * @param url The URL
-     * @param method The request method
-     * @return the value of the HTTP header this authentication wants set.
-     *          Used for preemptive authorization.
-     */
-    public abstract String getHeaderValue(URL url, String method);
-
-    /**
-     * Set header(s) on the given connection.  Subclasses must override
-     * This will only be called for
-     * definitive (i.e. non-preemptive) authorization.
-     * @param conn The connection to apply the header(s) to
-     * @param p A source of header values for this connection, if needed.
-     * @param raw The raw header field (if needed)
-     * @return true if all goes well, false if no headers were set.
-     */
-    public abstract boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw);
-
-    /**
-     * Check if the header indicates that the current auth. parameters are stale.
-     * If so, then replace the relevant field with the new value
-     * and return true. Otherwise return false.
-     * returning true means the request can be retried with the same userid/password
-     * returning false means we have to go back to the user to ask for a new
-     * username password.
-     */
-    public abstract boolean isAuthorizationStale (String header);
-
-    /**
-     * Give a key for hash table lookups.
-     * @param includeRealm if you want the realm considered.  Preemptively
-     *          setting an authorization is done before the realm is known.
-     */
-    String cacheKey(boolean includeRealm) {
-        // This must be kept in sync with the getXXXAuth() methods in this
-        // class.
-        if (includeRealm) {
-            return type + ":" + authScheme + ":" + protocol + ":"
-                        + host + ":" + port + ":" + realm;
-        } else {
-            return type + ":" + protocol + ":" + host + ":" + port;
-        }
-    }
-
-    String s1, s2;  /* used for serialization of pw */
-
-    private void readObject(ObjectInputStream s)
-        throws IOException, ClassNotFoundException
-    {
-        s.defaultReadObject ();
-        pw = new PasswordAuthentication (s1, s2.toCharArray());
-        s1 = null; s2= null;
-    }
-
-    private synchronized void writeObject(java.io.ObjectOutputStream s)
-        throws IOException
-    {
-        s1 = pw.getUserName();
-        s2 = new String (pw.getPassword());
-        s.defaultWriteObject ();
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/BasicAuthentication.java b/ojluni/src/main/java/sun/net/www/protocol/http/BasicAuthentication.java
deleted file mode 100644
index 7060372..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/BasicAuthentication.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (c) 1997, 2010, 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 sun.net.www.protocol.http;
-
-import java.net.URL;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.PasswordAuthentication;
-import java.io.IOException;
-import java.io.OutputStream;
-import sun.net.www.HeaderParser;
-import sun.misc.BASE64Encoder;
-
-/**
- * BasicAuthentication: Encapsulate an http server authentication using
- * the "basic" scheme.
- *
- * @author Bill Foote
- */
-
-
-class BasicAuthentication extends AuthenticationInfo {
-
-    private static final long serialVersionUID = 100L;
-
-    /** The authentication string for this host, port, and realm.  This is
-        a simple BASE64 encoding of "login:password".    */
-    String auth;
-
-    /**
-     * Create a BasicAuthentication
-     */
-    public BasicAuthentication(boolean isProxy, String host, int port,
-                               String realm, PasswordAuthentication pw) {
-        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              AuthScheme.BASIC, host, port, realm);
-        String plain = pw.getUserName() + ":";
-        byte[] nameBytes = null;
-        try {
-            nameBytes = plain.getBytes("ISO-8859-1");
-        } catch (java.io.UnsupportedEncodingException uee) {
-            assert false;
-        }
-
-        // get password bytes
-        char[] passwd = pw.getPassword();
-        byte[] passwdBytes = new byte[passwd.length];
-        for (int i=0; i<passwd.length; i++)
-            passwdBytes[i] = (byte)passwd[i];
-
-        // concatenate user name and password bytes and encode them
-        byte[] concat = new byte[nameBytes.length + passwdBytes.length];
-        System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
-        System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
-                         passwdBytes.length);
-        this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
-        this.pw = pw;
-    }
-
-    /**
-     * Create a BasicAuthentication
-     */
-    public BasicAuthentication(boolean isProxy, String host, int port,
-                               String realm, String auth) {
-        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              AuthScheme.BASIC, host, port, realm);
-        this.auth = "Basic " + auth;
-    }
-
-    /**
-     * Create a BasicAuthentication
-     */
-    public BasicAuthentication(boolean isProxy, URL url, String realm,
-                                   PasswordAuthentication pw) {
-        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              AuthScheme.BASIC, url, realm);
-        String plain = pw.getUserName() + ":";
-        byte[] nameBytes = null;
-        try {
-            nameBytes = plain.getBytes("ISO-8859-1");
-        } catch (java.io.UnsupportedEncodingException uee) {
-            assert false;
-        }
-
-        // get password bytes
-        char[] passwd = pw.getPassword();
-        byte[] passwdBytes = new byte[passwd.length];
-        for (int i=0; i<passwd.length; i++)
-            passwdBytes[i] = (byte)passwd[i];
-
-        // concatenate user name and password bytes and encode them
-        byte[] concat = new byte[nameBytes.length + passwdBytes.length];
-        System.arraycopy(nameBytes, 0, concat, 0, nameBytes.length);
-        System.arraycopy(passwdBytes, 0, concat, nameBytes.length,
-                         passwdBytes.length);
-        this.auth = "Basic " + (new BasicBASE64Encoder()).encode(concat);
-        this.pw = pw;
-    }
-
-    /**
-     * Create a BasicAuthentication
-     */
-    public BasicAuthentication(boolean isProxy, URL url, String realm,
-                                   String auth) {
-        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              AuthScheme.BASIC, url, realm);
-        this.auth = "Basic " + auth;
-    }
-
-    /**
-     * @return true if this authentication supports preemptive authorization
-     */
-    @Override
-    public boolean supportsPreemptiveAuthorization() {
-        return true;
-    }
-
-    /**
-     * Set header(s) on the given connection. This will only be called for
-     * definitive (i.e. non-preemptive) authorization.
-     * @param conn The connection to apply the header(s) to
-     * @param p A source of header values for this connection, if needed.
-     * @param raw The raw header values for this connection, if needed.
-     * @return true if all goes well, false if no headers were set.
-     */
-    @Override
-    public boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
-        conn.setAuthenticationProperty(getHeaderName(), getHeaderValue(null,null));
-        return true;
-    }
-
-    /**
-     * @return the value of the HTTP header this authentication wants set
-     */
-    @Override
-    public String getHeaderValue(URL url, String method) {
-        /* For Basic the authorization string does not depend on the request URL
-         * or the request method
-         */
-        return auth;
-    }
-
-    /**
-     * For Basic Authentication, the security parameters can never be stale.
-     * In other words there is no possibility to reuse the credentials.
-     * They are always either valid or invalid.
-     */
-    @Override
-    public boolean isAuthorizationStale (String header) {
-        return false;
-    }
-
-    /**
-     * @return the common root path between npath and path.
-     * This is used to detect when we have an authentication for two
-     * paths and the root of th authentication space is the common root.
-     */
-
-    static String getRootPath(String npath, String opath) {
-        int index = 0;
-        int toindex;
-
-        /* Must normalize so we don't get confused by ../ and ./ segments */
-        try {
-            npath = new URI (npath).normalize().getPath();
-            opath = new URI (opath).normalize().getPath();
-        } catch (URISyntaxException e) {
-            /* ignore error and use the old value */
-        }
-
-        while (index < opath.length()) {
-            toindex = opath.indexOf('/', index+1);
-            if (toindex != -1 && opath.regionMatches(0, npath, 0, toindex+1))
-                index = toindex;
-            else
-                return opath.substring(0, index+1);
-        }
-        /*should not reach here. If we do simply return npath*/
-        return npath;
-    }
-
-    /* It is never expected that the header value will exceed the bytesPerLine */
-    private class BasicBASE64Encoder extends BASE64Encoder {
-        @Override
-        protected int bytesPerLine() {
-            return (10000);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/DigestAuthentication.java b/ojluni/src/main/java/sun/net/www/protocol/http/DigestAuthentication.java
deleted file mode 100644
index 981967b..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/DigestAuthentication.java
+++ /dev/null
@@ -1,513 +0,0 @@
-/*
- * Copyright (c) 1997, 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 sun.net.www.protocol.http;
-
-import java.io.*;
-import java.net.URL;
-import java.net.ProtocolException;
-import java.net.PasswordAuthentication;
-import java.util.Arrays;
-import java.util.StringTokenizer;
-import java.util.Random;
-
-import sun.net.www.HeaderParser;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import static sun.net.www.protocol.http.HttpURLConnection.HTTP_CONNECT;
-
-/**
- * DigestAuthentication: Encapsulate an http server authentication using
- * the "Digest" scheme, as described in RFC2069 and updated in RFC2617
- *
- * @author Bill Foote
- */
-
-class DigestAuthentication extends AuthenticationInfo {
-
-    private static final long serialVersionUID = 100L;
-
-    private String authMethod;
-
-    // Authentication parameters defined in RFC2617.
-    // One instance of these may be shared among several DigestAuthentication
-    // instances as a result of a single authorization (for multiple domains)
-
-    static class Parameters implements java.io.Serializable {
-        private static final long serialVersionUID = -3584543755194526252L;
-
-        private boolean serverQop; // server proposed qop=auth
-        private String opaque;
-        private String cnonce;
-        private String nonce;
-        private String algorithm;
-        private int NCcount=0;
-
-        // The H(A1) string used for MD5-sess
-        private String  cachedHA1;
-
-        // Force the HA1 value to be recalculated because the nonce has changed
-        private boolean redoCachedHA1 = true;
-
-        private static final int cnonceRepeat = 5;
-
-        private static final int cnoncelen = 40; /* number of characters in cnonce */
-
-        private static Random   random;
-
-        static {
-            random = new Random();
-        }
-
-        Parameters () {
-            serverQop = false;
-            opaque = null;
-            algorithm = null;
-            cachedHA1 = null;
-            nonce = null;
-            setNewCnonce();
-        }
-
-        boolean authQop () {
-            return serverQop;
-        }
-        synchronized void incrementNC() {
-            NCcount ++;
-        }
-        synchronized int getNCCount () {
-            return NCcount;
-        }
-
-        int cnonce_count = 0;
-
-        /* each call increments the counter */
-        synchronized String getCnonce () {
-            if (cnonce_count >= cnonceRepeat) {
-                setNewCnonce();
-            }
-            cnonce_count++;
-            return cnonce;
-        }
-        synchronized void setNewCnonce () {
-            byte bb[] = new byte [cnoncelen/2];
-            char cc[] = new char [cnoncelen];
-            random.nextBytes (bb);
-            for (int  i=0; i<(cnoncelen/2); i++) {
-                int x = bb[i] + 128;
-                cc[i*2]= (char) ('A'+ x/16);
-                cc[i*2+1]= (char) ('A'+ x%16);
-            }
-            cnonce = new String (cc, 0, cnoncelen);
-            cnonce_count = 0;
-            redoCachedHA1 = true;
-        }
-
-        synchronized void setQop (String qop) {
-            if (qop != null) {
-                StringTokenizer st = new StringTokenizer (qop, " ");
-                while (st.hasMoreTokens()) {
-                    if (st.nextToken().equalsIgnoreCase ("auth")) {
-                        serverQop = true;
-                        return;
-                    }
-                }
-            }
-            serverQop = false;
-        }
-
-        synchronized String getOpaque () { return opaque;}
-        synchronized void setOpaque (String s) { opaque=s;}
-
-        synchronized String getNonce () { return nonce;}
-
-        synchronized void setNonce (String s) {
-            if (!s.equals(nonce)) {
-                nonce=s;
-                NCcount = 0;
-                redoCachedHA1 = true;
-            }
-        }
-
-        synchronized String getCachedHA1 () {
-            if (redoCachedHA1) {
-                return null;
-            } else {
-                return cachedHA1;
-            }
-        }
-
-        synchronized void setCachedHA1 (String s) {
-            cachedHA1=s;
-            redoCachedHA1=false;
-        }
-
-        synchronized String getAlgorithm () { return algorithm;}
-        synchronized void setAlgorithm (String s) { algorithm=s;}
-    }
-
-    Parameters params;
-
-    /**
-     * Create a DigestAuthentication
-     */
-    public DigestAuthentication(boolean isProxy, URL url, String realm,
-                                String authMethod, PasswordAuthentication pw,
-                                Parameters params) {
-        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              AuthScheme.DIGEST,
-              url,
-              realm);
-        this.authMethod = authMethod;
-        this.pw = pw;
-        this.params = params;
-    }
-
-    public DigestAuthentication(boolean isProxy, String host, int port, String realm,
-                                String authMethod, PasswordAuthentication pw,
-                                Parameters params) {
-        super(isProxy ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              AuthScheme.DIGEST,
-              host,
-              port,
-              realm);
-        this.authMethod = authMethod;
-        this.pw = pw;
-        this.params = params;
-    }
-
-    /**
-     * @return true if this authentication supports preemptive authorization
-     */
-    @Override
-    public boolean supportsPreemptiveAuthorization() {
-        return true;
-    }
-
-    /**
-     * Reclaculates the request-digest and returns it.
-     *
-     * <P> Used in the common case where the requestURI is simply the
-     * abs_path.
-     *
-     * @param  url
-     *         the URL
-     *
-     * @param  method
-     *         the HTTP method
-     *
-     * @return the value of the HTTP header this authentication wants set
-     */
-    @Override
-    public String getHeaderValue(URL url, String method) {
-        return getHeaderValueImpl(url.getFile(), method);
-    }
-
-    /**
-     * Reclaculates the request-digest and returns it.
-     *
-     * <P> Used when the requestURI is not the abs_path. The exact
-     * requestURI can be passed as a String.
-     *
-     * @param  requestURI
-     *         the Request-URI from the HTTP request line
-     *
-     * @param  method
-     *         the HTTP method
-     *
-     * @return the value of the HTTP header this authentication wants set
-     */
-    String getHeaderValue(String requestURI, String method) {
-        return getHeaderValueImpl(requestURI, method);
-    }
-
-    /**
-     * Check if the header indicates that the current auth. parameters are stale.
-     * If so, then replace the relevant field with the new value
-     * and return true. Otherwise return false.
-     * returning true means the request can be retried with the same userid/password
-     * returning false means we have to go back to the user to ask for a new
-     * username password.
-     */
-    @Override
-    public boolean isAuthorizationStale (String header) {
-        HeaderParser p = new HeaderParser (header);
-        String s = p.findValue ("stale");
-        if (s == null || !s.equals("true"))
-            return false;
-        String newNonce = p.findValue ("nonce");
-        if (newNonce == null || "".equals(newNonce)) {
-            return false;
-        }
-        params.setNonce (newNonce);
-        return true;
-    }
-
-    /**
-     * Set header(s) on the given connection.
-     * @param conn The connection to apply the header(s) to
-     * @param p A source of header values for this connection, if needed.
-     * @param raw Raw header values for this connection, if needed.
-     * @return true if all goes well, false if no headers were set.
-     */
-    @Override
-    public boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
-        params.setNonce (p.findValue("nonce"));
-        params.setOpaque (p.findValue("opaque"));
-        params.setQop (p.findValue("qop"));
-
-        String uri="";
-        String method;
-        if (type == PROXY_AUTHENTICATION &&
-                conn.tunnelState() == HttpURLConnection.TunnelState.SETUP) {
-            uri = HttpURLConnection.connectRequestURI(conn.getURL());
-            method = HTTP_CONNECT;
-        } else {
-            try {
-                uri = conn.getRequestURI();
-            } catch (IOException e) {}
-            method = conn.getMethod();
-        }
-
-        if (params.nonce == null || authMethod == null || pw == null || realm == null) {
-            return false;
-        }
-        if (authMethod.length() >= 1) {
-            // Method seems to get converted to all lower case elsewhere.
-            // It really does need to start with an upper case letter
-            // here.
-            authMethod = Character.toUpperCase(authMethod.charAt(0))
-                        + authMethod.substring(1).toLowerCase();
-        }
-        String algorithm = p.findValue("algorithm");
-        if (algorithm == null || "".equals(algorithm)) {
-            algorithm = "MD5";  // The default, accoriding to rfc2069
-        }
-        params.setAlgorithm (algorithm);
-
-        // If authQop is true, then the server is doing RFC2617 and
-        // has offered qop=auth. We do not support any other modes
-        // and if auth is not offered we fallback to the RFC2069 behavior
-
-        if (params.authQop()) {
-            params.setNewCnonce();
-        }
-
-        String value = getHeaderValueImpl (uri, method);
-        if (value != null) {
-            conn.setAuthenticationProperty(getHeaderName(), value);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    /* Calculate the Authorization header field given the request URI
-     * and based on the authorization information in params
-     */
-    private String getHeaderValueImpl (String uri, String method) {
-        String response;
-        char[] passwd = pw.getPassword();
-        boolean qop = params.authQop();
-        String opaque = params.getOpaque();
-        String cnonce = params.getCnonce ();
-        String nonce = params.getNonce ();
-        String algorithm = params.getAlgorithm ();
-        params.incrementNC ();
-        int  nccount = params.getNCCount ();
-        String ncstring=null;
-
-        if (nccount != -1) {
-            ncstring = Integer.toHexString (nccount).toLowerCase();
-            int len = ncstring.length();
-            if (len < 8)
-                ncstring = zeroPad [len] + ncstring;
-        }
-
-        try {
-            response = computeDigest(true, pw.getUserName(),passwd,realm,
-                                        method, uri, nonce, cnonce, ncstring);
-        } catch (NoSuchAlgorithmException ex) {
-            return null;
-        }
-
-        String ncfield = "\"";
-        if (qop) {
-            ncfield = "\", nc=" + ncstring;
-        }
-
-        String value = authMethod
-                        + " username=\"" + pw.getUserName()
-                        + "\", realm=\"" + realm
-                        + "\", nonce=\"" + nonce
-                        + ncfield
-                        + ", uri=\"" + uri
-                        + "\", response=\"" + response
-                        + "\", algorithm=\"" + algorithm;
-        if (opaque != null) {
-            value = value + "\", opaque=\"" + opaque;
-        }
-        if (cnonce != null) {
-            value = value + "\", cnonce=\"" + cnonce;
-        }
-        if (qop) {
-            value = value + "\", qop=\"auth";
-        }
-        value = value + "\"";
-        return value;
-    }
-
-    public void checkResponse (String header, String method, URL url)
-                                                        throws IOException {
-        checkResponse (header, method, url.getFile());
-    }
-
-    public void checkResponse (String header, String method, String uri)
-                                                        throws IOException {
-        char[] passwd = pw.getPassword();
-        String username = pw.getUserName();
-        boolean qop = params.authQop();
-        String opaque = params.getOpaque();
-        String cnonce = params.cnonce;
-        String nonce = params.getNonce ();
-        String algorithm = params.getAlgorithm ();
-        int  nccount = params.getNCCount ();
-        String ncstring=null;
-
-        if (header == null) {
-            throw new ProtocolException ("No authentication information in response");
-        }
-
-        if (nccount != -1) {
-            ncstring = Integer.toHexString (nccount).toUpperCase();
-            int len = ncstring.length();
-            if (len < 8)
-                ncstring = zeroPad [len] + ncstring;
-        }
-        try {
-            String expected = computeDigest(false, username,passwd,realm,
-                                        method, uri, nonce, cnonce, ncstring);
-            HeaderParser p = new HeaderParser (header);
-            String rspauth = p.findValue ("rspauth");
-            if (rspauth == null) {
-                throw new ProtocolException ("No digest in response");
-            }
-            if (!rspauth.equals (expected)) {
-                throw new ProtocolException ("Response digest invalid");
-            }
-            /* Check if there is a nextnonce field */
-            String nextnonce = p.findValue ("nextnonce");
-            if (nextnonce != null && ! "".equals(nextnonce)) {
-                params.setNonce (nextnonce);
-            }
-
-        } catch (NoSuchAlgorithmException ex) {
-            throw new ProtocolException ("Unsupported algorithm in response");
-        }
-    }
-
-    private String computeDigest(
-                        boolean isRequest, String userName, char[] password,
-                        String realm, String connMethod,
-                        String requestURI, String nonceString,
-                        String cnonce, String ncValue
-                    ) throws NoSuchAlgorithmException
-    {
-
-        String A1, HashA1;
-        String algorithm = params.getAlgorithm ();
-        boolean md5sess = algorithm.equalsIgnoreCase ("MD5-sess");
-
-        MessageDigest md = MessageDigest.getInstance(md5sess?"MD5":algorithm);
-
-        if (md5sess) {
-            if ((HashA1 = params.getCachedHA1 ()) == null) {
-                String s = userName + ":" + realm + ":";
-                String s1 = encode (s, password, md);
-                A1 = s1 + ":" + nonceString + ":" + cnonce;
-                HashA1 = encode(A1, null, md);
-                params.setCachedHA1 (HashA1);
-            }
-        } else {
-            A1 = userName + ":" + realm + ":";
-            HashA1 = encode(A1, password, md);
-        }
-
-        String A2;
-        if (isRequest) {
-            A2 = connMethod + ":" + requestURI;
-        } else {
-            A2 = ":" + requestURI;
-        }
-        String HashA2 = encode(A2, null, md);
-        String combo, finalHash;
-
-        if (params.authQop()) { /* RRC2617 when qop=auth */
-            combo = HashA1+ ":" + nonceString + ":" + ncValue + ":" +
-                        cnonce + ":auth:" +HashA2;
-
-        } else { /* for compatibility with RFC2069 */
-            combo = HashA1 + ":" +
-                       nonceString + ":" +
-                       HashA2;
-        }
-        finalHash = encode(combo, null, md);
-        return finalHash;
-    }
-
-    private final static char charArray[] = {
-        '0', '1', '2', '3', '4', '5', '6', '7',
-        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
-    };
-
-    private final static String zeroPad[] = {
-        // 0         1          2         3        4       5      6     7
-        "00000000", "0000000", "000000", "00000", "0000", "000", "00", "0"
-    };
-
-    private String encode(String src, char[] passwd, MessageDigest md) {
-        try {
-            md.update(src.getBytes("ISO-8859-1"));
-        } catch (java.io.UnsupportedEncodingException uee) {
-            assert false;
-        }
-        if (passwd != null) {
-            byte[] passwdBytes = new byte[passwd.length];
-            for (int i=0; i<passwd.length; i++)
-                passwdBytes[i] = (byte)passwd[i];
-            md.update(passwdBytes);
-            Arrays.fill(passwdBytes, (byte)0x00);
-        }
-        byte[] digest = md.digest();
-
-        StringBuffer res = new StringBuffer(digest.length * 2);
-        for (int i = 0; i < digest.length; i++) {
-            int hashchar = ((digest[i] >>> 4) & 0xf);
-            res.append(charArray[hashchar]);
-            hashchar = (digest[i] & 0xf);
-            res.append(charArray[hashchar]);
-        }
-        return res.toString();
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/Handler.java b/ojluni/src/main/java/sun/net/www/protocol/http/Handler.java
deleted file mode 100644
index 0decc5c..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/Handler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 1994, 2003, 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.
- */
-
-/*-
- *      HTTP stream opener
- */
-
-package sun.net.www.protocol.http;
-
-import java.io.IOException;
-import java.net.URL;
-import java.net.Proxy;
-
-/** open an http input stream given a URL */
-public class Handler extends java.net.URLStreamHandler {
-    protected String proxy;
-    protected int proxyPort;
-
-    protected int getDefaultPort() {
-        return 80;
-    }
-
-    public Handler () {
-        proxy = null;
-        proxyPort = -1;
-    }
-
-    public Handler (String proxy, int port) {
-        this.proxy = proxy;
-        this.proxyPort = port;
-    }
-
-    protected java.net.URLConnection openConnection(URL u)
-    throws IOException {
-        return openConnection(u, (Proxy)null);
-    }
-
-    protected java.net.URLConnection openConnection(URL u, Proxy p)
-        throws IOException {
-        return new HttpURLConnection(u, p, this);
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/HttpAuthenticator.java b/ojluni/src/main/java/sun/net/www/protocol/http/HttpAuthenticator.java
deleted file mode 100644
index 2990202..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/HttpAuthenticator.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (c) 1996, 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 sun.net.www.protocol.http;
-
-import java.net.URL;
-
-/**
- * An interface for all objects that implement HTTP authentication.
- * See the HTTP spec for details on how this works in general.
- * A single class or object can implement an arbitrary number of
- * authentication schemes.
- *
- * @author David Brown
- *
- * @deprecated -- use java.net.Authenticator instead
- * @see java.net.Authenticator
- */
-//
-// REMIND:  Unless compatibility with sun.* API's from 1.2 to 2.0 is
-// a goal, there's no reason to carry this forward into JDK 2.0.
-@Deprecated
-public interface HttpAuthenticator {
-
-
-    /**
-     * Indicate whether the specified authentication scheme is
-     * supported.  In accordance with HTTP specifications, the
-     * scheme name should be checked in a case-insensitive fashion.
-     */
-
-    boolean schemeSupported (String scheme);
-
-    /**
-     * Returns the String that should be included in the HTTP
-     * <B>Authorization</B> field.  Return null if no info was
-     * supplied or could be found.
-     * <P>
-     * Example:
-     * --> GET http://www.authorization-required.com/ HTTP/1.0
-     * <-- HTTP/1.0 403 Unauthorized
-     * <-- WWW-Authenticate: Basic realm="WallyWorld"
-     * call schemeSupported("Basic"); (return true)
-     * call authString(u, "Basic", "WallyWorld", null);
-     *   return "QWadhgWERghghWERfdfQ=="
-     * --> GET http://www.authorization-required.com/ HTTP/1.0
-     * --> Authorization: Basic QWadhgWERghghWERfdfQ==
-     * <-- HTTP/1.0 200 OK
-     * <B> YAY!!!</B>
-     */
-
-    public String authString (URL u, String scheme, String realm);
-
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/HttpCallerInfo.java b/ojluni/src/main/java/sun/net/www/protocol/http/HttpCallerInfo.java
deleted file mode 100644
index fcb3ac8..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/HttpCallerInfo.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.protocol.http;
-
-import java.net.Authenticator.RequestorType;
-import java.net.InetAddress;
-import java.net.URL;
-
-/**
- * Used in HTTP/Negotiate, to feed HTTP request info into JGSS as a HttpCaller,
- * so that special actions can be taken, including special callback handler,
- * special useSubjectCredsOnly value.
- *
- * This is an immutable class. It can be instantiated in two styles;
- *
- * 1. Un-schemed: Create at the beginning before the preferred scheme is
- * determined. This object can be fed into AuthenticationHeader to check
- * for the preference.
- *
- * 2. Schemed: With the scheme field filled, can be used in JGSS-API calls.
- */
-final public class HttpCallerInfo {
-    // All info that an Authenticator needs.
-    final public URL url;
-    final public String host, protocol, prompt, scheme;
-    final public int port;
-    final public InetAddress addr;
-    final public RequestorType authType;
-
-    /**
-     * Create a schemed object based on an un-schemed one.
-     */
-    public HttpCallerInfo(HttpCallerInfo old, String scheme) {
-        this.url = old.url;
-        this.host = old.host;
-        this.protocol = old.protocol;
-        this.prompt = old.prompt;
-        this.port = old.port;
-        this.addr = old.addr;
-        this.authType = old.authType;
-        this.scheme = scheme;
-    }
-
-    /**
-     * Constructor an un-schemed object for site access.
-     */
-    public HttpCallerInfo(URL url) {
-        this.url= url;
-        prompt = "";
-        host = url.getHost();
-
-        int p = url.getPort();
-        if (p == -1) {
-            port = url.getDefaultPort();
-        } else {
-            port = p;
-        }
-
-        InetAddress ia;
-        try {
-            ia = InetAddress.getByName(url.getHost());
-        } catch (Exception e) {
-            ia = null;
-        }
-        addr = ia;
-
-        protocol = url.getProtocol();
-        authType = RequestorType.SERVER;
-        scheme = "";
-    }
-
-    /**
-     * Constructor an un-schemed object for proxy access.
-     */
-    public HttpCallerInfo(URL url, String host, int port) {
-        this.url= url;
-        this.host = host;
-        this.port = port;
-        prompt = "";
-        addr = null;
-        protocol = url.getProtocol();
-        authType = RequestorType.PROXY;
-        scheme = "";
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/HttpURLConnection.java b/ojluni/src/main/java/sun/net/www/protocol/http/HttpURLConnection.java
deleted file mode 100644
index b77976c..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/HttpURLConnection.java
+++ /dev/null
@@ -1,3384 +0,0 @@
-/*
- * 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 sun.net.www.protocol.http;
-
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.ProtocolException;
-import java.net.HttpRetryException;
-import java.net.PasswordAuthentication;
-import java.net.Authenticator;
-import java.net.HttpCookie;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.net.SocketTimeoutException;
-import java.net.Proxy;
-import java.net.ProxySelector;
-import java.net.URI;
-import java.net.InetSocketAddress;
-import java.net.CookieHandler;
-import java.net.ResponseCache;
-import java.net.CacheResponse;
-import java.net.SecureCacheResponse;
-import java.net.CacheRequest;
-import java.net.Authenticator.RequestorType;
-import java.io.*;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Map;
-import java.util.List;
-import java.util.Locale;
-import java.util.StringTokenizer;
-import java.util.Iterator;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Set;
-import sun.net.*;
-import sun.net.www.*;
-import sun.net.www.http.HttpClient;
-import sun.net.www.http.PosterOutputStream;
-import sun.net.www.http.ChunkedInputStream;
-import sun.net.www.http.ChunkedOutputStream;
-import sun.util.logging.PlatformLogger;
-import java.text.SimpleDateFormat;
-import java.util.TimeZone;
-import java.net.MalformedURLException;
-import java.nio.ByteBuffer;
-import static sun.net.www.protocol.http.AuthScheme.BASIC;
-import static sun.net.www.protocol.http.AuthScheme.DIGEST;
-import static sun.net.www.protocol.http.AuthScheme.NTLM;
-import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
-import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
-import static sun.net.www.protocol.http.AuthScheme.UNKNOWN;
-
-/**
- * A class to represent an HTTP connection to a remote object.
- */
-
-
-public class HttpURLConnection extends java.net.HttpURLConnection {
-
-    static String HTTP_CONNECT = "CONNECT";
-
-    static final String version;
-    public static final String userAgent;
-
-    /* max # of allowed re-directs */
-    static final int defaultmaxRedirects = 20;
-    static final int maxRedirects;
-
-    /* Not all servers support the (Proxy)-Authentication-Info headers.
-     * By default, we don't require them to be sent
-     */
-    static final boolean validateProxy;
-    static final boolean validateServer;
-
-    private StreamingOutputStream strOutputStream;
-    private final static String RETRY_MSG1 =
-        "cannot retry due to proxy authentication, in streaming mode";
-    private final static String RETRY_MSG2 =
-        "cannot retry due to server authentication, in streaming mode";
-    private final static String RETRY_MSG3 =
-        "cannot retry due to redirection, in streaming mode";
-
-    /*
-     * System properties related to error stream handling:
-     *
-     * sun.net.http.errorstream.enableBuffering = <boolean>
-     *
-     * With the above system property set to true (default is false),
-     * when the response code is >=400, the HTTP handler will try to
-     * buffer the response body (up to a certain amount and within a
-     * time limit). Thus freeing up the underlying socket connection
-     * for reuse. The rationale behind this is that usually when the
-     * server responds with a >=400 error (client error or server
-     * error, such as 404 file not found), the server will send a
-     * small response body to explain who to contact and what to do to
-     * recover. With this property set to true, even if the
-     * application doesn't call getErrorStream(), read the response
-     * body, and then call close(), the underlying socket connection
-     * can still be kept-alive and reused. The following two system
-     * properties provide further control to the error stream
-     * buffering behaviour.
-     *
-     * sun.net.http.errorstream.timeout = <int>
-     *     the timeout (in millisec) waiting the error stream
-     *     to be buffered; default is 300 ms
-     *
-     * sun.net.http.errorstream.bufferSize = <int>
-     *     the size (in bytes) to use for the buffering the error stream;
-     *     default is 4k
-     */
-
-
-    /* Should we enable buffering of error streams? */
-    private static boolean enableESBuffer = false;
-
-    /* timeout waiting for read for buffered error stream;
-     */
-    private static int timeout4ESBuffer = 0;
-
-    /* buffer size for buffered error stream;
-    */
-    private static int bufSize4ES = 0;
-
-    /*
-     * Restrict setting of request headers through the public api
-     * consistent with JavaScript XMLHttpRequest2 with a few
-     * exceptions. Disallowed headers are silently ignored for
-     * backwards compatibility reasons rather than throwing a
-     * SecurityException. For example, some applets set the
-     * Host header since old JREs did not implement HTTP 1.1.
-     * Additionally, any header starting with Sec- is
-     * disallowed.
-     *
-     * The following headers are allowed for historical reasons:
-     *
-     * Accept-Charset, Accept-Encoding, Cookie, Cookie2, Date,
-     * Referer, TE, User-Agent, headers beginning with Proxy-.
-     *
-     * The following headers are allowed in a limited form:
-     *
-     * Connection: close
-     *
-     * See http://www.w3.org/TR/XMLHttpRequest2.
-     */
-    private static final boolean allowRestrictedHeaders;
-    private static final Set<String> restrictedHeaderSet;
-    private static final String[] restrictedHeaders = {
-        /* Restricted by XMLHttpRequest2 */
-        //"Accept-Charset",
-        //"Accept-Encoding",
-        "Access-Control-Request-Headers",
-        "Access-Control-Request-Method",
-        "Connection", /* close is allowed */
-        "Content-Length",
-        //"Cookie",
-        //"Cookie2",
-        "Content-Transfer-Encoding",
-        //"Date",
-        //"Expect",
-        "Host",
-        "Keep-Alive",
-        "Origin",
-        // "Referer",
-        // "TE",
-        "Trailer",
-        "Transfer-Encoding",
-        "Upgrade",
-        //"User-Agent",
-        "Via"
-    };
-
-    static {
-        maxRedirects = java.security.AccessController.doPrivileged(
-            new sun.security.action.GetIntegerAction(
-                "http.maxRedirects", defaultmaxRedirects)).intValue();
-        version = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("java.version"));
-        String agent = java.security.AccessController.doPrivileged(
-                    new sun.security.action.GetPropertyAction("http.agent"));
-        if (agent == null) {
-            agent = "Java/"+version;
-        } else {
-            agent = agent + " Java/"+version;
-        }
-        userAgent = agent;
-        validateProxy = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "http.auth.digest.validateProxy")).booleanValue();
-        validateServer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "http.auth.digest.validateServer")).booleanValue();
-
-        enableESBuffer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "sun.net.http.errorstream.enableBuffering")).booleanValue();
-        timeout4ESBuffer = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction(
-                    "sun.net.http.errorstream.timeout", 300)).intValue();
-        if (timeout4ESBuffer <= 0) {
-            timeout4ESBuffer = 300; // use the default
-        }
-
-        bufSize4ES = java.security.AccessController.doPrivileged(
-                new sun.security.action.GetIntegerAction(
-                    "sun.net.http.errorstream.bufferSize", 4096)).intValue();
-        if (bufSize4ES <= 0) {
-            bufSize4ES = 4096; // use the default
-        }
-
-        allowRestrictedHeaders = ((Boolean)java.security.AccessController.doPrivileged(
-                new sun.security.action.GetBooleanAction(
-                    "sun.net.http.allowRestrictedHeaders"))).booleanValue();
-        if (!allowRestrictedHeaders) {
-            restrictedHeaderSet = new HashSet<String>(restrictedHeaders.length);
-            for (int i=0; i < restrictedHeaders.length; i++) {
-                restrictedHeaderSet.add(restrictedHeaders[i].toLowerCase());
-            }
-        } else {
-            restrictedHeaderSet = null;
-        }
-    }
-
-    static final String httpVersion = "HTTP/1.1";
-    static final String acceptString =
-        "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2";
-
-    // the following http request headers should NOT have their values
-    // returned for security reasons.
-    private static final String[] EXCLUDE_HEADERS = {
-            "Proxy-Authorization",
-            "Authorization"
-    };
-
-    // also exclude system cookies when any might be set
-    private static final String[] EXCLUDE_HEADERS2= {
-            "Proxy-Authorization",
-            "Authorization",
-            "Cookie",
-            "Cookie2"
-    };
-
-    protected HttpClient http;
-    protected Handler handler;
-    protected Proxy instProxy;
-
-    private CookieHandler cookieHandler;
-    private ResponseCache cacheHandler;
-
-    // the cached response, and cached response headers and body
-    protected CacheResponse cachedResponse;
-    private MessageHeader cachedHeaders;
-    private InputStream cachedInputStream;
-
-    /* output stream to server */
-    protected PrintStream ps = null;
-
-
-    /* buffered error stream */
-    private InputStream errorStream = null;
-
-    /* User set Cookies */
-    private boolean setUserCookies = true;
-    private String userCookies = null;
-    private String userCookies2 = null;
-
-    /* We only have a single static authenticator for now.
-     * REMIND:  backwards compatibility with JDK 1.1.  Should be
-     * eliminated for JDK 2.0.
-     */
-    private static HttpAuthenticator defaultAuth;
-
-    /* all the headers we send
-     * NOTE: do *NOT* dump out the content of 'requests' in the
-     * output or stacktrace since it may contain security-sensitive
-     * headers such as those defined in EXCLUDE_HEADERS.
-     */
-    private MessageHeader requests;
-
-    /* The following two fields are only used with Digest Authentication */
-    String domain;      /* The list of authentication domains */
-    DigestAuthentication.Parameters digestparams;
-
-    /* Current credentials in use */
-    AuthenticationInfo  currentProxyCredentials = null;
-    AuthenticationInfo  currentServerCredentials = null;
-    boolean             needToCheck = true;
-    private boolean doingNTLM2ndStage = false; /* doing the 2nd stage of an NTLM server authentication */
-    private boolean doingNTLMp2ndStage = false; /* doing the 2nd stage of an NTLM proxy authentication */
-
-    /* try auth without calling Authenticator. Used for transparent NTLM authentication */
-    private boolean tryTransparentNTLMServer = true;
-    private boolean tryTransparentNTLMProxy = true;
-
-    /* Used by Windows specific code */
-    private Object authObj;
-
-    /* Set if the user is manually setting the Authorization or Proxy-Authorization headers */
-    boolean isUserServerAuth;
-    boolean isUserProxyAuth;
-
-    String serverAuthKey, proxyAuthKey;
-
-    /* Progress source */
-    protected ProgressSource pi;
-
-    /* all the response headers we get back */
-    private MessageHeader responses;
-    /* the stream _from_ the server */
-    private InputStream inputStream = null;
-    /* post stream _to_ the server, if any */
-    private PosterOutputStream poster = null;
-
-    /* Indicates if the std. request headers have been set in requests. */
-    private boolean setRequests=false;
-
-    /* Indicates whether a request has already failed or not */
-    private boolean failedOnce=false;
-
-    /* Remembered Exception, we will throw it again if somebody
-       calls getInputStream after disconnect */
-    private Exception rememberedException = null;
-
-    /* If we decide we want to reuse a client, we put it here */
-    private HttpClient reuseClient = null;
-
-    /* Tunnel states */
-    public enum TunnelState {
-        /* No tunnel */
-        NONE,
-
-        /* Setting up a tunnel */
-        SETUP,
-
-        /* Tunnel has been successfully setup */
-        TUNNELING
-    }
-
-    private TunnelState tunnelState = TunnelState.NONE;
-
-    /* Redefine timeouts from java.net.URLConnection as we need -1 to mean
-     * not set. This is to ensure backward compatibility.
-     */
-    private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT;
-    private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT;
-
-    /* Logging support */
-    private static final PlatformLogger logger =
-            PlatformLogger.getLogger("sun.net.www.protocol.http.HttpURLConnection");
-
-    /*
-     * privileged request password authentication
-     *
-     */
-    private static PasswordAuthentication
-    privilegedRequestPasswordAuthentication(
-                            final String host,
-                            final InetAddress addr,
-                            final int port,
-                            final String protocol,
-                            final String prompt,
-                            final String scheme,
-                            final URL url,
-                            final RequestorType authType) {
-        return java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<PasswordAuthentication>() {
-                public PasswordAuthentication run() {
-                    if (logger.isLoggable(PlatformLogger.FINEST)) {
-                        logger.finest("Requesting Authentication: host =" + host + " url = " + url);
-                    }
-                    PasswordAuthentication pass = Authenticator.requestPasswordAuthentication(
-                        host, addr, port, protocol,
-                        prompt, scheme, url, authType);
-                    if (logger.isLoggable(PlatformLogger.FINEST)) {
-                        logger.finest("Authentication returned: " + (pass != null ? pass.toString() : "null"));
-                    }
-                    return pass;
-                }
-            });
-    }
-
-    private boolean isRestrictedHeader(String key, String value) {
-        if (allowRestrictedHeaders) {
-            return false;
-        }
-
-        key = key.toLowerCase();
-        if (restrictedHeaderSet.contains(key)) {
-            /*
-             * Exceptions to restricted headers:
-             *
-             * Allow "Connection: close".
-             */
-            if (key.equals("connection") && value.equalsIgnoreCase("close")) {
-                return false;
-            }
-            return true;
-        } else if (key.startsWith("sec-")) {
-            return true;
-        }
-        return false;
-    }
-
-    /*
-     * Checks the validity of http message header and whether the header
-     * is restricted and throws IllegalArgumentException if invalid or
-     * restricted.
-     */
-    private boolean isExternalMessageHeaderAllowed(String key, String value) {
-        checkMessageHeader(key, value);
-        if (!isRestrictedHeader(key, value)) {
-            return true;
-        }
-        return false;
-    }
-
-    /* Logging support */
-    public static PlatformLogger getHttpLogger() {
-        return logger;
-    }
-
-    /* Used for Windows NTLM implementation */
-    public Object authObj() {
-        return authObj;
-    }
-
-    public void authObj(Object authObj) {
-        this.authObj = authObj;
-    }
-
-    /*
-     * checks the validity of http message header and throws
-     * IllegalArgumentException if invalid.
-     */
-    private void checkMessageHeader(String key, String value) {
-        char LF = '\n';
-        int index = key.indexOf(LF);
-        if (index != -1) {
-            throw new IllegalArgumentException(
-                "Illegal character(s) in message header field: " + key);
-        }
-        else {
-            if (value == null) {
-                return;
-            }
-
-            index = value.indexOf(LF);
-            while (index != -1) {
-                index++;
-                if (index < value.length()) {
-                    char c = value.charAt(index);
-                    if ((c==' ') || (c=='\t')) {
-                        // ok, check the next occurrence
-                        index = value.indexOf(LF, index);
-                        continue;
-                    }
-                }
-                throw new IllegalArgumentException(
-                    "Illegal character(s) in message header value: " + value);
-            }
-        }
-    }
-
-    /* adds the standard key/val pairs to reqests if necessary & write to
-     * given PrintStream
-     */
-    private void writeRequests() throws IOException {
-        /* print all message headers in the MessageHeader
-         * onto the wire - all the ones we've set and any
-         * others that have been set
-         */
-        // send any pre-emptive authentication
-        if (http.usingProxy && tunnelState() != TunnelState.TUNNELING) {
-            setPreemptiveProxyAuthentication(requests);
-        }
-        if (!setRequests) {
-
-            /* We're very particular about the order in which we
-             * set the request headers here.  The order should not
-             * matter, but some careless CGI programs have been
-             * written to expect a very particular order of the
-             * standard headers.  To name names, the order in which
-             * Navigator3.0 sends them.  In particular, we make *sure*
-             * to send Content-type: <> and Content-length:<> second
-             * to last and last, respectively, in the case of a POST
-             * request.
-             */
-            if (!failedOnce)
-                requests.prepend(method + " " + getRequestURI()+" "  +
-                                 httpVersion, null);
-            if (!getUseCaches()) {
-                requests.setIfNotSet ("Cache-Control", "no-cache");
-                requests.setIfNotSet ("Pragma", "no-cache");
-            }
-            requests.setIfNotSet("User-Agent", userAgent);
-            int port = url.getPort();
-            String host = url.getHost();
-            if (port != -1 && port != url.getDefaultPort()) {
-                host += ":" + String.valueOf(port);
-            }
-            requests.setIfNotSet("Host", host);
-            requests.setIfNotSet("Accept", acceptString);
-
-            /*
-             * For HTTP/1.1 the default behavior is to keep connections alive.
-             * However, we may be talking to a 1.0 server so we should set
-             * keep-alive just in case, except if we have encountered an error
-             * or if keep alive is disabled via a system property
-             */
-
-            // Try keep-alive only on first attempt
-            if (!failedOnce && http.getHttpKeepAliveSet()) {
-                if (http.usingProxy && tunnelState() != TunnelState.TUNNELING) {
-                    requests.setIfNotSet("Proxy-Connection", "keep-alive");
-                } else {
-                    requests.setIfNotSet("Connection", "keep-alive");
-                }
-            } else {
-                /*
-                 * RFC 2616 HTTP/1.1 section 14.10 says:
-                 * HTTP/1.1 applications that do not support persistent
-                 * connections MUST include the "close" connection option
-                 * in every message
-                 */
-                requests.setIfNotSet("Connection", "close");
-            }
-            // Set modified since if necessary
-            long modTime = getIfModifiedSince();
-            if (modTime != 0 ) {
-                Date date = new Date(modTime);
-                //use the preferred date format according to RFC 2068(HTTP1.1),
-                // RFC 822 and RFC 1123
-                SimpleDateFormat fo =
-                  new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss 'GMT'", Locale.US);
-                fo.setTimeZone(TimeZone.getTimeZone("GMT"));
-                requests.setIfNotSet("If-Modified-Since", fo.format(date));
-            }
-            // check for preemptive authorization
-            AuthenticationInfo sauth = AuthenticationInfo.getServerAuth(url);
-            if (sauth != null && sauth.supportsPreemptiveAuthorization() ) {
-                // Sets "Authorization"
-                requests.setIfNotSet(sauth.getHeaderName(), sauth.getHeaderValue(url,method));
-                currentServerCredentials = sauth;
-            }
-
-            if (!method.equals("PUT") && (poster != null || streaming())) {
-                requests.setIfNotSet ("Content-type",
-                        "application/x-www-form-urlencoded");
-            }
-
-            boolean chunked = false;
-
-            if (streaming()) {
-                if (chunkLength != -1) {
-                    requests.set ("Transfer-Encoding", "chunked");
-                    chunked = true;
-                } else { /* fixed content length */
-                    if (fixedContentLengthLong != -1) {
-                        requests.set ("Content-Length",
-                                      String.valueOf(fixedContentLengthLong));
-                    } else if (fixedContentLength != -1) {
-                        requests.set ("Content-Length",
-                                      String.valueOf(fixedContentLength));
-                    }
-                }
-            } else if (poster != null) {
-                /* add Content-Length & POST/PUT data */
-                synchronized (poster) {
-                    /* close it, so no more data can be added */
-                    poster.close();
-                    requests.set("Content-Length",
-                                 String.valueOf(poster.size()));
-                }
-            }
-
-            if (!chunked) {
-                if (requests.findValue("Transfer-Encoding") != null) {
-                    requests.remove("Transfer-Encoding");
-                    if (logger.isLoggable(PlatformLogger.WARNING)) {
-                        logger.warning(
-                            "use streaming mode for chunked encoding");
-                    }
-                }
-            }
-
-            // get applicable cookies based on the uri and request headers
-            // add them to the existing request headers
-            setCookieHeader();
-
-            setRequests=true;
-        }
-        if (logger.isLoggable(PlatformLogger.FINE)) {
-            logger.fine(requests.toString());
-        }
-        http.writeRequests(requests, poster, streaming());
-        if (ps.checkError()) {
-            String proxyHost = http.getProxyHostUsed();
-            int proxyPort = http.getProxyPortUsed();
-            disconnectInternal();
-            if (failedOnce) {
-                throw new IOException("Error writing to server");
-            } else { // try once more
-                failedOnce=true;
-                if (proxyHost != null) {
-                    setProxiedClient(url, proxyHost, proxyPort);
-                } else {
-                    setNewClient (url);
-                }
-                ps = (PrintStream) http.getOutputStream();
-                connected=true;
-                responses = new MessageHeader();
-                setRequests=false;
-                writeRequests();
-            }
-        }
-    }
-
-
-    /**
-     * Create a new HttpClient object, bypassing the cache of
-     * HTTP client objects/connections.
-     *
-     * @param url       the URL being accessed
-     */
-    protected void setNewClient (URL url)
-    throws IOException {
-        setNewClient(url, false);
-    }
-
-    /**
-     * Obtain a HttpsClient object. Use the cached copy if specified.
-     *
-     * @param url       the URL being accessed
-     * @param useCache  whether the cached connection should be used
-     *        if present
-     */
-    protected void setNewClient (URL url, boolean useCache)
-        throws IOException {
-        http = HttpClient.New(url, null, -1, useCache, connectTimeout, this);
-        http.setReadTimeout(readTimeout);
-    }
-
-
-    /**
-     * Create a new HttpClient object, set up so that it uses
-     * per-instance proxying to the given HTTP proxy.  This
-     * bypasses the cache of HTTP client objects/connections.
-     *
-     * @param url       the URL being accessed
-     * @param proxyHost the proxy host to use
-     * @param proxyPort the proxy port to use
-     */
-    protected void setProxiedClient (URL url, String proxyHost, int proxyPort)
-    throws IOException {
-        setProxiedClient(url, proxyHost, proxyPort, false);
-    }
-
-    /**
-     * Obtain a HttpClient object, set up so that it uses per-instance
-     * proxying to the given HTTP proxy. Use the cached copy of HTTP
-     * client objects/connections if specified.
-     *
-     * @param url       the URL being accessed
-     * @param proxyHost the proxy host to use
-     * @param proxyPort the proxy port to use
-     * @param useCache  whether the cached connection should be used
-     *        if present
-     */
-    protected void setProxiedClient (URL url,
-                                           String proxyHost, int proxyPort,
-                                           boolean useCache)
-        throws IOException {
-        proxiedConnect(url, proxyHost, proxyPort, useCache);
-    }
-
-    protected void proxiedConnect(URL url,
-                                           String proxyHost, int proxyPort,
-                                           boolean useCache)
-        throws IOException {
-        http = HttpClient.New (url, proxyHost, proxyPort, useCache,
-            connectTimeout, this);
-        http.setReadTimeout(readTimeout);
-    }
-
-    protected HttpURLConnection(URL u, Handler handler)
-    throws IOException {
-        // we set proxy == null to distinguish this case with the case
-        // when per connection proxy is set
-        this(u, null, handler);
-    }
-
-    public HttpURLConnection(URL u, String host, int port) {
-        this(u, new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(host, port)));
-    }
-
-    /** this constructor is used by other protocol handlers such as ftp
-        that want to use http to fetch urls on their behalf.*/
-    public HttpURLConnection(URL u, Proxy p) {
-        this(u, p, new Handler());
-    }
-
-    protected HttpURLConnection(URL u, Proxy p, Handler handler) {
-        super(u);
-        requests = new MessageHeader();
-        responses = new MessageHeader();
-        this.handler = handler;
-        instProxy = p;
-        if (instProxy instanceof sun.net.ApplicationProxy) {
-            /* Application set Proxies should not have access to cookies
-             * in a secure environment unless explicitly allowed. */
-            try {
-                cookieHandler = CookieHandler.getDefault();
-            } catch (SecurityException se) { /* swallow exception */ }
-        } else {
-            cookieHandler = java.security.AccessController.doPrivileged(
-                new java.security.PrivilegedAction<CookieHandler>() {
-                public CookieHandler run() {
-                    return CookieHandler.getDefault();
-                }
-            });
-        }
-        cacheHandler = java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<ResponseCache>() {
-                public ResponseCache run() {
-                return ResponseCache.getDefault();
-            }
-        });
-    }
-
-    /**
-     * @deprecated.  Use java.net.Authenticator.setDefault() instead.
-     */
-    public static void setDefaultAuthenticator(HttpAuthenticator a) {
-        defaultAuth = a;
-    }
-
-    /**
-     * opens a stream allowing redirects only to the same host.
-     */
-    public static InputStream openConnectionCheckRedirects(URLConnection c)
-        throws IOException
-    {
-        boolean redir;
-        int redirects = 0;
-        InputStream in;
-
-        do {
-            if (c instanceof HttpURLConnection) {
-                ((HttpURLConnection) c).setInstanceFollowRedirects(false);
-            }
-
-            // We want to open the input stream before
-            // getting headers, because getHeaderField()
-            // et al swallow IOExceptions.
-            in = c.getInputStream();
-            redir = false;
-
-            if (c instanceof HttpURLConnection) {
-                HttpURLConnection http = (HttpURLConnection) c;
-                int stat = http.getResponseCode();
-                if (stat >= 300 && stat <= 307 && stat != 306 &&
-                        stat != HttpURLConnection.HTTP_NOT_MODIFIED) {
-                    URL base = http.getURL();
-                    String loc = http.getHeaderField("Location");
-                    URL target = null;
-                    if (loc != null) {
-                        target = new URL(base, loc);
-                    }
-                    http.disconnect();
-                    if (target == null
-                        || !base.getProtocol().equals(target.getProtocol())
-                        || base.getPort() != target.getPort()
-                        || !hostsEqual(base, target)
-                        || redirects >= 5)
-                    {
-                        throw new SecurityException("illegal URL redirect");
-                    }
-                    redir = true;
-                    c = target.openConnection();
-                    redirects++;
-                }
-            }
-        } while (redir);
-        return in;
-    }
-
-
-    //
-    // Same as java.net.URL.hostsEqual
-    //
-    private static boolean hostsEqual(URL u1, URL u2) {
-        final String h1 = u1.getHost();
-        final String h2 = u2.getHost();
-
-        if (h1 == null) {
-            return h2 == null;
-        } else if (h2 == null) {
-            return false;
-        } else if (h1.equalsIgnoreCase(h2)) {
-            return true;
-        }
-        // Have to resolve addresses before comparing, otherwise
-        // names like tachyon and tachyon.eng would compare different
-        final boolean result[] = {false};
-
-        java.security.AccessController.doPrivileged(
-            new java.security.PrivilegedAction<Void>() {
-                public Void run() {
-                try {
-                    InetAddress a1 = InetAddress.getByName(h1);
-                    InetAddress a2 = InetAddress.getByName(h2);
-                    result[0] = a1.equals(a2);
-                } catch(UnknownHostException e) {
-                } catch(SecurityException e) {
-                }
-                return null;
-            }
-        });
-
-        return result[0];
-    }
-
-    // overridden in HTTPS subclass
-
-    public void connect() throws IOException {
-        plainConnect();
-    }
-
-    private boolean checkReuseConnection () {
-        if (connected) {
-            return true;
-        }
-        if (reuseClient != null) {
-            http = reuseClient;
-            http.setReadTimeout(getReadTimeout());
-            http.reuse = false;
-            reuseClient = null;
-            connected = true;
-            return true;
-        }
-        return false;
-    }
-
-    protected void plainConnect()  throws IOException {
-        if (connected) {
-            return;
-        }
-        // try to see if request can be served from local cache
-        if (cacheHandler != null && getUseCaches()) {
-            try {
-                URI uri = ParseUtil.toURI(url);
-                if (uri != null) {
-                    cachedResponse = cacheHandler.get(uri, getRequestMethod(), requests.getHeaders(EXCLUDE_HEADERS));
-                    if ("https".equalsIgnoreCase(uri.getScheme())
-                        && !(cachedResponse instanceof SecureCacheResponse)) {
-                        cachedResponse = null;
-                    }
-                    if (logger.isLoggable(PlatformLogger.FINEST)) {
-                        logger.finest("Cache Request for " + uri + " / " + getRequestMethod());
-                        logger.finest("From cache: " + (cachedResponse != null ? cachedResponse.toString() : "null"));
-                    }
-                    if (cachedResponse != null) {
-                        cachedHeaders = mapToMessageHeader(cachedResponse.getHeaders());
-                        cachedInputStream = cachedResponse.getBody();
-                    }
-                }
-            } catch (IOException ioex) {
-                // ignore and commence normal connection
-            }
-            if (cachedHeaders != null && cachedInputStream != null) {
-                connected = true;
-                return;
-            } else {
-                cachedResponse = null;
-            }
-        }
-        try {
-            /* Try to open connections using the following scheme,
-             * return on the first one that's successful:
-             * 1) if (instProxy != null)
-             *        connect to instProxy; raise exception if failed
-             * 2) else use system default ProxySelector
-             * 3) is 2) fails, make direct connection
-             */
-
-            if (instProxy == null) { // no instance Proxy is set
-                /**
-                 * Do we have to use a proxy?
-                 */
-                ProxySelector sel =
-                    java.security.AccessController.doPrivileged(
-                        new java.security.PrivilegedAction<ProxySelector>() {
-                            public ProxySelector run() {
-                                     return ProxySelector.getDefault();
-                                 }
-                             });
-                if (sel != null) {
-                    URI uri = sun.net.www.ParseUtil.toURI(url);
-                    if (logger.isLoggable(PlatformLogger.FINEST)) {
-                        logger.finest("ProxySelector Request for " + uri);
-                    }
-                    Iterator<Proxy> it = sel.select(uri).iterator();
-                    Proxy p;
-                    while (it.hasNext()) {
-                        p = it.next();
-                        try {
-                            if (!failedOnce) {
-                                http = getNewHttpClient(url, p, connectTimeout);
-                                http.setReadTimeout(readTimeout);
-                            } else {
-                                // make sure to construct new connection if first
-                                // attempt failed
-                                http = getNewHttpClient(url, p, connectTimeout, false);
-                                http.setReadTimeout(readTimeout);
-                            }
-                            if (logger.isLoggable(PlatformLogger.FINEST)) {
-                                if (p != null) {
-                                    logger.finest("Proxy used: " + p.toString());
-                                }
-                            }
-                            break;
-                        } catch (IOException ioex) {
-                            if (p != Proxy.NO_PROXY) {
-                                sel.connectFailed(uri, p.address(), ioex);
-                                if (!it.hasNext()) {
-                                    // fallback to direct connection
-                                    http = getNewHttpClient(url, null, connectTimeout, false);
-                                    http.setReadTimeout(readTimeout);
-                                    break;
-                                }
-                            } else {
-                                throw ioex;
-                            }
-                            continue;
-                        }
-                    }
-                } else {
-                    // No proxy selector, create http client with no proxy
-                    if (!failedOnce) {
-                        http = getNewHttpClient(url, null, connectTimeout);
-                        http.setReadTimeout(readTimeout);
-                    } else {
-                        // make sure to construct new connection if first
-                        // attempt failed
-                        http = getNewHttpClient(url, null, connectTimeout, false);
-                        http.setReadTimeout(readTimeout);
-                    }
-                }
-            } else {
-                if (!failedOnce) {
-                    http = getNewHttpClient(url, instProxy, connectTimeout);
-                    http.setReadTimeout(readTimeout);
-                } else {
-                    // make sure to construct new connection if first
-                    // attempt failed
-                    http = getNewHttpClient(url, instProxy, connectTimeout, false);
-                    http.setReadTimeout(readTimeout);
-                }
-            }
-
-            ps = (PrintStream)http.getOutputStream();
-        } catch (IOException e) {
-            throw e;
-        }
-        // constructor to HTTP client calls openserver
-        connected = true;
-    }
-
-    // subclass HttpsClient will overwrite & return an instance of HttpsClient
-    protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout)
-        throws IOException {
-        return HttpClient.New(url, p, connectTimeout, this);
-    }
-
-    // subclass HttpsClient will overwrite & return an instance of HttpsClient
-    protected HttpClient getNewHttpClient(URL url, Proxy p,
-                                          int connectTimeout, boolean useCache)
-        throws IOException {
-        return HttpClient.New(url, p, connectTimeout, useCache, this);
-    }
-
-    private void expect100Continue() throws IOException {
-            // Expect: 100-Continue was set, so check the return code for
-            // Acceptance
-            int oldTimeout = http.getReadTimeout();
-            boolean enforceTimeOut = false;
-            boolean timedOut = false;
-            if (oldTimeout <= 0) {
-                // 5s read timeout in case the server doesn't understand
-                // Expect: 100-Continue
-                http.setReadTimeout(5000);
-                enforceTimeOut = true;
-            }
-
-            try {
-                http.parseHTTP(responses, pi, this);
-            } catch (SocketTimeoutException se) {
-                if (!enforceTimeOut) {
-                    throw se;
-                }
-                timedOut = true;
-                http.setIgnoreContinue(true);
-            }
-            if (!timedOut) {
-                // Can't use getResponseCode() yet
-                String resp = responses.getValue(0);
-                // Parse the response which is of the form:
-                // HTTP/1.1 417 Expectation Failed
-                // HTTP/1.1 100 Continue
-                if (resp != null && resp.startsWith("HTTP/")) {
-                    String[] sa = resp.split("\\s+");
-                    responseCode = -1;
-                    try {
-                        // Response code is 2nd token on the line
-                        if (sa.length > 1)
-                            responseCode = Integer.parseInt(sa[1]);
-                    } catch (NumberFormatException numberFormatException) {
-                    }
-                }
-                if (responseCode != 100) {
-                    throw new ProtocolException("Server rejected operation");
-                }
-            }
-
-            http.setReadTimeout(oldTimeout);
-
-            responseCode = -1;
-            responses.reset();
-            // Proceed
-    }
-
-    /*
-     * Allowable input/output sequences:
-     * [interpreted as POST/PUT]
-     * - get output, [write output,] get input, [read input]
-     * - get output, [write output]
-     * [interpreted as GET]
-     * - get input, [read input]
-     * Disallowed:
-     * - get input, [read input,] get output, [write output]
-     */
-
-    @Override
-    public synchronized OutputStream getOutputStream() throws IOException {
-
-        try {
-            if (!doOutput) {
-                throw new ProtocolException("cannot write to a URLConnection"
-                               + " if doOutput=false - call setDoOutput(true)");
-            }
-
-            if (method.equals("GET")) {
-                method = "POST"; // Backward compatibility
-            }
-            if (!"POST".equals(method) && !"PUT".equals(method) &&
-                "http".equals(url.getProtocol())) {
-                throw new ProtocolException("HTTP method " + method +
-                                            " doesn't support output");
-            }
-
-            // if there's already an input stream open, throw an exception
-            if (inputStream != null) {
-                throw new ProtocolException("Cannot write output after reading input.");
-            }
-
-            if (!checkReuseConnection())
-                connect();
-
-            boolean expectContinue = false;
-            String expects = requests.findValue("Expect");
-            if ("100-Continue".equalsIgnoreCase(expects)) {
-                http.setIgnoreContinue(false);
-                expectContinue = true;
-            }
-
-            if (streaming() && strOutputStream == null) {
-                writeRequests();
-            }
-
-            if (expectContinue) {
-                expect100Continue();
-            }
-            ps = (PrintStream)http.getOutputStream();
-            if (streaming()) {
-                if (strOutputStream == null) {
-                    if (chunkLength != -1) { /* chunked */
-                         strOutputStream = new StreamingOutputStream(
-                               new ChunkedOutputStream(ps, chunkLength), -1L);
-                    } else { /* must be fixed content length */
-                        long length = 0L;
-                        if (fixedContentLengthLong != -1) {
-                            length = fixedContentLengthLong;
-                        } else if (fixedContentLength != -1) {
-                            length = fixedContentLength;
-                        }
-                        strOutputStream = new StreamingOutputStream(ps, length);
-                    }
-                }
-                return strOutputStream;
-            } else {
-                if (poster == null) {
-                    poster = new PosterOutputStream();
-                }
-                return poster;
-            }
-        } catch (RuntimeException e) {
-            disconnectInternal();
-            throw e;
-        } catch (ProtocolException e) {
-            // Save the response code which may have been set while enforcing
-            // the 100-continue. disconnectInternal() forces it to -1
-            int i = responseCode;
-            disconnectInternal();
-            responseCode = i;
-            throw e;
-        } catch (IOException e) {
-            disconnectInternal();
-            throw e;
-        }
-    }
-
-    public boolean streaming () {
-        return (fixedContentLength != -1) || (fixedContentLengthLong != -1) ||
-               (chunkLength != -1);
-    }
-
-    /*
-     * get applicable cookies based on the uri and request headers
-     * add them to the existing request headers
-     */
-    private void setCookieHeader() throws IOException {
-        if (cookieHandler != null) {
-            // we only want to capture the user defined Cookies once, as
-            // they cannot be changed by user code after we are connected,
-            // only internally.
-            synchronized (this) {
-                if (setUserCookies) {
-                    int k = requests.getKey("Cookie");
-                    if (k != -1)
-                        userCookies = requests.getValue(k);
-                    k = requests.getKey("Cookie2");
-                    if (k != -1)
-                        userCookies2 = requests.getValue(k);
-                    setUserCookies = false;
-                }
-            }
-
-            // remove old Cookie header before setting new one.
-            requests.remove("Cookie");
-            requests.remove("Cookie2");
-
-            URI uri = ParseUtil.toURI(url);
-            if (uri != null) {
-                if (logger.isLoggable(PlatformLogger.FINEST)) {
-                    logger.finest("CookieHandler request for " + uri);
-                }
-                Map<String, List<String>> cookies
-                    = cookieHandler.get(
-                        uri, requests.getHeaders(EXCLUDE_HEADERS));
-                if (!cookies.isEmpty()) {
-                    if (logger.isLoggable(PlatformLogger.FINEST)) {
-                        logger.finest("Cookies retrieved: " + cookies.toString());
-                    }
-                    for (Map.Entry<String, List<String>> entry :
-                             cookies.entrySet()) {
-                        String key = entry.getKey();
-                        // ignore all entries that don't have "Cookie"
-                        // or "Cookie2" as keys
-                        if (!"Cookie".equalsIgnoreCase(key) &&
-                            !"Cookie2".equalsIgnoreCase(key)) {
-                            continue;
-                        }
-                        List<String> l = entry.getValue();
-                        if (l != null && !l.isEmpty()) {
-                            StringBuilder cookieValue = new StringBuilder();
-                            for (String value : l) {
-                                cookieValue.append(value).append("; ");
-                            }
-                            // strip off the trailing '; '
-                            try {
-                                requests.add(key, cookieValue.substring(0, cookieValue.length() - 2));
-                            } catch (StringIndexOutOfBoundsException ignored) {
-                                // no-op
-                            }
-                        }
-                    }
-                }
-            }
-            if (userCookies != null) {
-                int k;
-                if ((k = requests.getKey("Cookie")) != -1)
-                    requests.set("Cookie", requests.getValue(k) + ";" + userCookies);
-                else
-                    requests.set("Cookie", userCookies);
-            }
-            if (userCookies2 != null) {
-                int k;
-                if ((k = requests.getKey("Cookie2")) != -1)
-                    requests.set("Cookie2", requests.getValue(k) + ";" + userCookies2);
-                else
-                    requests.set("Cookie2", userCookies2);
-            }
-
-        } // end of getting cookies
-    }
-
-    @Override
-    @SuppressWarnings("empty-statement")
-    public synchronized InputStream getInputStream() throws IOException {
-
-        if (!doInput) {
-            throw new ProtocolException("Cannot read from URLConnection"
-                   + " if doInput=false (call setDoInput(true))");
-        }
-
-        if (rememberedException != null) {
-            if (rememberedException instanceof RuntimeException)
-                throw new RuntimeException(rememberedException);
-            else {
-                throw getChainedException((IOException)rememberedException);
-            }
-        }
-
-        if (inputStream != null) {
-            return inputStream;
-        }
-
-        if (streaming() ) {
-            if (strOutputStream == null) {
-                getOutputStream();
-            }
-            /* make sure stream is closed */
-            strOutputStream.close ();
-            if (!strOutputStream.writtenOK()) {
-                throw new IOException ("Incomplete output stream");
-            }
-        }
-
-        int redirects = 0;
-        int respCode = 0;
-        long cl = -1;
-        AuthenticationInfo serverAuthentication = null;
-        AuthenticationInfo proxyAuthentication = null;
-        AuthenticationHeader srvHdr = null;
-
-        /**
-         * Failed Negotiate
-         *
-         * In some cases, the Negotiate auth is supported for the
-         * remote host but the negotiate process still fails (For
-         * example, if the web page is located on a backend server
-         * and delegation is needed but fails). The authentication
-         * process will start again, and we need to detect this
-         * kind of failure and do proper fallback (say, to NTLM).
-         *
-         * In order to achieve this, the inNegotiate flag is set
-         * when the first negotiate challenge is met (and reset
-         * if authentication is finished). If a fresh new negotiate
-         * challenge (no parameter) is found while inNegotiate is
-         * set, we know there's a failed auth attempt recently.
-         * Here we'll ignore the header line so that fallback
-         * can be practiced.
-         *
-         * inNegotiateProxy is for proxy authentication.
-         */
-        boolean inNegotiate = false;
-        boolean inNegotiateProxy = false;
-
-        // If the user has set either of these headers then do not remove them
-        isUserServerAuth = requests.getKey("Authorization") != -1;
-        isUserProxyAuth = requests.getKey("Proxy-Authorization") != -1;
-
-        try {
-            do {
-                if (!checkReuseConnection())
-                    connect();
-
-                if (cachedInputStream != null) {
-                    return cachedInputStream;
-                }
-
-                // Check if URL should be metered
-                boolean meteredInput = ProgressMonitor.getDefault().shouldMeterInput(url, method);
-
-                if (meteredInput)   {
-                    pi = new ProgressSource(url, method);
-                    pi.beginTracking();
-                }
-
-                /* REMIND: This exists to fix the HttpsURLConnection subclass.
-                 * Hotjava needs to run on JDK1.1FCS.  Do proper fix once a
-                 * proper solution for SSL can be found.
-                 */
-                ps = (PrintStream)http.getOutputStream();
-
-                if (!streaming()) {
-                    writeRequests();
-                }
-                http.parseHTTP(responses, pi, this);
-                if (logger.isLoggable(PlatformLogger.FINE)) {
-                    logger.fine(responses.toString());
-                }
-
-                boolean b1 = responses.filterNTLMResponses("WWW-Authenticate");
-                boolean b2 = responses.filterNTLMResponses("Proxy-Authenticate");
-                if (b1 || b2) {
-                    if (logger.isLoggable(PlatformLogger.FINE)) {
-                        logger.fine(">>>> Headers are filtered");
-                        logger.fine(responses.toString());
-                    }
-                }
-
-                inputStream = http.getInputStream();
-
-                respCode = getResponseCode();
-                if (respCode == -1) {
-                    disconnectInternal();
-                    throw new IOException ("Invalid Http response");
-                }
-                if (respCode == HTTP_PROXY_AUTH) {
-                    if (streaming()) {
-                        disconnectInternal();
-                        throw new HttpRetryException (
-                            RETRY_MSG1, HTTP_PROXY_AUTH);
-                    }
-
-                    // Read comments labeled "Failed Negotiate" for details.
-                    boolean dontUseNegotiate = false;
-                    Iterator iter = responses.multiValueIterator("Proxy-Authenticate");
-                    while (iter.hasNext()) {
-                        String value = ((String)iter.next()).trim();
-                        if (value.equalsIgnoreCase("Negotiate") ||
-                                value.equalsIgnoreCase("Kerberos")) {
-                            if (!inNegotiateProxy) {
-                                inNegotiateProxy = true;
-                            } else {
-                                dontUseNegotiate = true;
-                                doingNTLMp2ndStage = false;
-                                proxyAuthentication = null;
-                            }
-                            break;
-                        }
-                    }
-
-                    // changes: add a 3rd parameter to the constructor of
-                    // AuthenticationHeader, so that NegotiateAuthentication.
-                    // isSupported can be tested.
-                    // The other 2 appearances of "new AuthenticationHeader" is
-                    // altered in similar ways.
-
-                    AuthenticationHeader authhdr = new AuthenticationHeader (
-                            "Proxy-Authenticate", responses,
-                            new HttpCallerInfo(url, http.getProxyHostUsed(),
-                                http.getProxyPortUsed()),
-                            dontUseNegotiate
-                    );
-
-                    if (!doingNTLMp2ndStage) {
-                        proxyAuthentication =
-                            resetProxyAuthentication(proxyAuthentication, authhdr);
-                        if (proxyAuthentication != null) {
-                            redirects++;
-                            disconnectInternal();
-                            continue;
-                        }
-                    } else {
-                        /* in this case, only one header field will be present */
-                        String raw = responses.findValue ("Proxy-Authenticate");
-                        reset ();
-                        if (!proxyAuthentication.setHeaders(this,
-                                                        authhdr.headerParser(), raw)) {
-                            disconnectInternal();
-                            throw new IOException ("Authentication failure");
-                        }
-                        if (serverAuthentication != null && srvHdr != null &&
-                                !serverAuthentication.setHeaders(this,
-                                                        srvHdr.headerParser(), raw)) {
-                            disconnectInternal ();
-                            throw new IOException ("Authentication failure");
-                        }
-                        authObj = null;
-                        doingNTLMp2ndStage = false;
-                        continue;
-                    }
-                } else {
-                    inNegotiateProxy = false;
-                    doingNTLMp2ndStage = false;
-                    if (!isUserProxyAuth)
-                        requests.remove("Proxy-Authorization");
-                }
-
-                // cache proxy authentication info
-                if (proxyAuthentication != null) {
-                    // cache auth info on success, domain header not relevant.
-                    proxyAuthentication.addToCache();
-                }
-
-                if (respCode == HTTP_UNAUTHORIZED) {
-                    if (streaming()) {
-                        disconnectInternal();
-                        throw new HttpRetryException (
-                            RETRY_MSG2, HTTP_UNAUTHORIZED);
-                    }
-
-                    // Read comments labeled "Failed Negotiate" for details.
-                    boolean dontUseNegotiate = false;
-                    Iterator iter = responses.multiValueIterator("WWW-Authenticate");
-                    while (iter.hasNext()) {
-                        String value = ((String)iter.next()).trim();
-                        if (value.equalsIgnoreCase("Negotiate") ||
-                                value.equalsIgnoreCase("Kerberos")) {
-                            if (!inNegotiate) {
-                                inNegotiate = true;
-                            } else {
-                                dontUseNegotiate = true;
-                                doingNTLM2ndStage = false;
-                                serverAuthentication = null;
-                            }
-                            break;
-                        }
-                    }
-
-                    srvHdr = new AuthenticationHeader (
-                            "WWW-Authenticate", responses,
-                            new HttpCallerInfo(url),
-                            dontUseNegotiate
-                    );
-
-                    String raw = srvHdr.raw();
-                    if (!doingNTLM2ndStage) {
-                        if ((serverAuthentication != null)&&
-                            serverAuthentication.getAuthScheme() != NTLM) {
-                            if (serverAuthentication.isAuthorizationStale (raw)) {
-                                /* we can retry with the current credentials */
-                                disconnectWeb();
-                                redirects++;
-                                requests.set(serverAuthentication.getHeaderName(),
-                                            serverAuthentication.getHeaderValue(url, method));
-                                currentServerCredentials = serverAuthentication;
-                                setCookieHeader();
-                                continue;
-                            } else {
-                                serverAuthentication.removeFromCache();
-                            }
-                        }
-                        serverAuthentication = getServerAuthentication(srvHdr);
-                        currentServerCredentials = serverAuthentication;
-
-                        if (serverAuthentication != null) {
-                            disconnectWeb();
-                            redirects++; // don't let things loop ad nauseum
-                            setCookieHeader();
-                            continue;
-                        }
-                    } else {
-                        reset ();
-                        /* header not used for ntlm */
-                        if (!serverAuthentication.setHeaders(this, null, raw)) {
-                            disconnectWeb();
-                            throw new IOException ("Authentication failure");
-                        }
-                        doingNTLM2ndStage = false;
-                        authObj = null;
-                        setCookieHeader();
-                        continue;
-                    }
-                }
-                // cache server authentication info
-                if (serverAuthentication != null) {
-                    // cache auth info on success
-                    if (!(serverAuthentication instanceof DigestAuthentication) ||
-                        (domain == null)) {
-                        if (serverAuthentication instanceof BasicAuthentication) {
-                            // check if the path is shorter than the existing entry
-                            String npath = AuthenticationInfo.reducePath (url.getPath());
-                            String opath = serverAuthentication.path;
-                            if (!opath.startsWith (npath) || npath.length() >= opath.length()) {
-                                /* npath is longer, there must be a common root */
-                                npath = BasicAuthentication.getRootPath (opath, npath);
-                            }
-                            // remove the entry and create a new one
-                            BasicAuthentication a =
-                                (BasicAuthentication) serverAuthentication.clone();
-                            serverAuthentication.removeFromCache();
-                            a.path = npath;
-                            serverAuthentication = a;
-                        }
-                        serverAuthentication.addToCache();
-                    } else {
-                        // what we cache is based on the domain list in the request
-                        DigestAuthentication srv = (DigestAuthentication)
-                            serverAuthentication;
-                        StringTokenizer tok = new StringTokenizer (domain," ");
-                        String realm = srv.realm;
-                        PasswordAuthentication pw = srv.pw;
-                        digestparams = srv.params;
-                        while (tok.hasMoreTokens()) {
-                            String path = tok.nextToken();
-                            try {
-                                /* path could be an abs_path or a complete URI */
-                                URL u = new URL (url, path);
-                                DigestAuthentication d = new DigestAuthentication (
-                                                   false, u, realm, "Digest", pw, digestparams);
-                                d.addToCache ();
-                            } catch (Exception e) {}
-                        }
-                    }
-                }
-
-                // some flags should be reset to its initialized form so that
-                // even after a redirect the necessary checks can still be
-                // preformed.
-                inNegotiate = false;
-                inNegotiateProxy = false;
-
-                //serverAuthentication = null;
-                doingNTLMp2ndStage = false;
-                doingNTLM2ndStage = false;
-                if (!isUserServerAuth)
-                    requests.remove("Authorization");
-                if (!isUserProxyAuth)
-                    requests.remove("Proxy-Authorization");
-
-                if (respCode == HTTP_OK) {
-                    checkResponseCredentials (false);
-                } else {
-                    needToCheck = false;
-                }
-
-                // a flag need to clean
-                needToCheck = true;
-
-                if (followRedirect()) {
-                    /* if we should follow a redirect, then the followRedirects()
-                     * method will disconnect() and re-connect us to the new
-                     * location
-                     */
-                    redirects++;
-
-                    // redirecting HTTP response may have set cookie, so
-                    // need to re-generate request header
-                    setCookieHeader();
-
-                    continue;
-                }
-
-                try {
-                    cl = Long.parseLong(responses.findValue("content-length"));
-                } catch (Exception exc) { };
-
-                if (method.equals("HEAD") || cl == 0 ||
-                    respCode == HTTP_NOT_MODIFIED ||
-                    respCode == HTTP_NO_CONTENT) {
-
-                    if (pi != null) {
-                        pi.finishTracking();
-                        pi = null;
-                    }
-                    http.finished();
-                    http = null;
-                    inputStream = new EmptyInputStream();
-                    connected = false;
-                }
-
-                if (respCode == 200 || respCode == 203 || respCode == 206 ||
-                    respCode == 300 || respCode == 301 || respCode == 410) {
-                    if (cacheHandler != null) {
-                        // give cache a chance to save response in cache
-                        URI uri = ParseUtil.toURI(url);
-                        if (uri != null) {
-                            URLConnection uconn = this;
-                            if ("https".equalsIgnoreCase(uri.getScheme())) {
-                                try {
-                                // use reflection to get to the public
-                                // HttpsURLConnection instance saved in
-                                // DelegateHttpsURLConnection
-                                uconn = (URLConnection)this.getClass().getField("httpsURLConnection").get(this);
-                                } catch (IllegalAccessException iae) {
-                                    // ignored; use 'this'
-                                } catch (NoSuchFieldException nsfe) {
-                                    // ignored; use 'this'
-                                }
-                            }
-                            CacheRequest cacheRequest =
-                                cacheHandler.put(uri, uconn);
-                            if (cacheRequest != null && http != null) {
-                                http.setCacheRequest(cacheRequest);
-                                inputStream = new HttpInputStream(inputStream, cacheRequest);
-                            }
-                        }
-                    }
-                }
-
-                if (!(inputStream instanceof HttpInputStream)) {
-                    inputStream = new HttpInputStream(inputStream);
-                }
-
-                if (respCode >= 400) {
-                    if (respCode == 404 || respCode == 410) {
-                        throw new FileNotFoundException(url.toString());
-                    } else {
-                        throw new java.io.IOException("Server returned HTTP" +
-                              " response code: " + respCode + " for URL: " +
-                              url.toString());
-                    }
-                }
-                poster = null;
-                strOutputStream = null;
-                return inputStream;
-            } while (redirects < maxRedirects);
-
-            throw new ProtocolException("Server redirected too many " +
-                                        " times ("+ redirects + ")");
-        } catch (RuntimeException e) {
-            disconnectInternal();
-            rememberedException = e;
-            throw e;
-        } catch (IOException e) {
-            rememberedException = e;
-
-            // buffer the error stream if bytes < 4k
-            // and it can be buffered within 1 second
-            String te = responses.findValue("Transfer-Encoding");
-            if (http != null && http.isKeepingAlive() && enableESBuffer &&
-                (cl > 0 || (te != null && te.equalsIgnoreCase("chunked")))) {
-                errorStream = ErrorStream.getErrorStream(inputStream, cl, http);
-            }
-            throw e;
-        } finally {
-            if (proxyAuthKey != null) {
-                AuthenticationInfo.endAuthRequest(proxyAuthKey);
-            }
-            if (serverAuthKey != null) {
-                AuthenticationInfo.endAuthRequest(serverAuthKey);
-            }
-        }
-    }
-
-    /*
-     * Creates a chained exception that has the same type as
-     * original exception and with the same message. Right now,
-     * there is no convenient APIs for doing so.
-     */
-    private IOException getChainedException(final IOException rememberedException) {
-        try {
-            final Object[] args = { rememberedException.getMessage() };
-            IOException chainedException =
-                java.security.AccessController.doPrivileged(
-                    new java.security.PrivilegedExceptionAction<IOException>() {
-                        public IOException run() throws Exception {
-                            return (IOException)
-                                rememberedException.getClass()
-                                .getConstructor(new Class[] { String.class })
-                                .newInstance(args);
-                        }
-                    });
-            chainedException.initCause(rememberedException);
-            return chainedException;
-        } catch (Exception ignored) {
-            return rememberedException;
-        }
-    }
-
-    @Override
-    public InputStream getErrorStream() {
-        if (connected && responseCode >= 400) {
-            // Client Error 4xx and Server Error 5xx
-            if (errorStream != null) {
-                return errorStream;
-            } else if (inputStream != null) {
-                return inputStream;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * set or reset proxy authentication info in request headers
-     * after receiving a 407 error. In the case of NTLM however,
-     * receiving a 407 is normal and we just skip the stale check
-     * because ntlm does not support this feature.
-     */
-    private AuthenticationInfo
-        resetProxyAuthentication(AuthenticationInfo proxyAuthentication, AuthenticationHeader auth) throws IOException {
-        if ((proxyAuthentication != null )&&
-             proxyAuthentication.getAuthScheme() != NTLM) {
-            String raw = auth.raw();
-            if (proxyAuthentication.isAuthorizationStale (raw)) {
-                /* we can retry with the current credentials */
-                String value;
-                if (proxyAuthentication instanceof DigestAuthentication) {
-                    DigestAuthentication digestProxy = (DigestAuthentication)
-                        proxyAuthentication;
-                    if (tunnelState() == TunnelState.SETUP) {
-                        value = digestProxy.getHeaderValue(connectRequestURI(url), HTTP_CONNECT);
-                    } else {
-                        value = digestProxy.getHeaderValue(getRequestURI(), method);
-                    }
-                } else {
-                    value = proxyAuthentication.getHeaderValue(url, method);
-                }
-                requests.set(proxyAuthentication.getHeaderName(), value);
-                currentProxyCredentials = proxyAuthentication;
-                return proxyAuthentication;
-            } else {
-                proxyAuthentication.removeFromCache();
-            }
-        }
-        proxyAuthentication = getHttpProxyAuthentication(auth);
-        currentProxyCredentials = proxyAuthentication;
-        return  proxyAuthentication;
-    }
-
-    /**
-     * Returns the tunnel state.
-     *
-     * @return  the state
-     */
-    TunnelState tunnelState() {
-        return tunnelState;
-    }
-
-    /**
-     * Set the tunneling status.
-     *
-     * @param  the state
-     */
-    public void setTunnelState(TunnelState tunnelState) {
-        this.tunnelState = tunnelState;
-    }
-
-    /**
-     * establish a tunnel through proxy server
-     */
-    public synchronized void doTunneling() throws IOException {
-        int retryTunnel = 0;
-        String statusLine = "";
-        int respCode = 0;
-        AuthenticationInfo proxyAuthentication = null;
-        String proxyHost = null;
-        int proxyPort = -1;
-
-        // save current requests so that they can be restored after tunnel is setup.
-        MessageHeader savedRequests = requests;
-        requests = new MessageHeader();
-
-        // Read comments labeled "Failed Negotiate" for details.
-        boolean inNegotiateProxy = false;
-
-        try {
-            /* Actively setting up a tunnel */
-            setTunnelState(TunnelState.SETUP);
-
-            do {
-                if (!checkReuseConnection()) {
-                    proxiedConnect(url, proxyHost, proxyPort, false);
-                }
-                // send the "CONNECT" request to establish a tunnel
-                // through proxy server
-                sendCONNECTRequest();
-                responses.reset();
-
-                // There is no need to track progress in HTTP Tunneling,
-                // so ProgressSource is null.
-                http.parseHTTP(responses, null, this);
-
-                /* Log the response to the CONNECT */
-                if (logger.isLoggable(PlatformLogger.FINE)) {
-                    logger.fine(responses.toString());
-                }
-
-                if (responses.filterNTLMResponses("Proxy-Authenticate")) {
-                    if (logger.isLoggable(PlatformLogger.FINE)) {
-                        logger.fine(">>>> Headers are filtered");
-                        logger.fine(responses.toString());
-                    }
-                }
-
-                statusLine = responses.getValue(0);
-                StringTokenizer st = new StringTokenizer(statusLine);
-                st.nextToken();
-                respCode = Integer.parseInt(st.nextToken().trim());
-                if (respCode == HTTP_PROXY_AUTH) {
-                    // Read comments labeled "Failed Negotiate" for details.
-                    boolean dontUseNegotiate = false;
-                    Iterator iter = responses.multiValueIterator("Proxy-Authenticate");
-                    while (iter.hasNext()) {
-                        String value = ((String)iter.next()).trim();
-                        if (value.equalsIgnoreCase("Negotiate") ||
-                                value.equalsIgnoreCase("Kerberos")) {
-                            if (!inNegotiateProxy) {
-                                inNegotiateProxy = true;
-                            } else {
-                                dontUseNegotiate = true;
-                                doingNTLMp2ndStage = false;
-                                proxyAuthentication = null;
-                            }
-                            break;
-                        }
-                    }
-
-                    AuthenticationHeader authhdr = new AuthenticationHeader (
-                            "Proxy-Authenticate", responses,
-                            new HttpCallerInfo(url, http.getProxyHostUsed(),
-                                http.getProxyPortUsed()),
-                            dontUseNegotiate
-                    );
-                    if (!doingNTLMp2ndStage) {
-                        proxyAuthentication =
-                            resetProxyAuthentication(proxyAuthentication, authhdr);
-                        if (proxyAuthentication != null) {
-                            proxyHost = http.getProxyHostUsed();
-                            proxyPort = http.getProxyPortUsed();
-                            disconnectInternal();
-                            retryTunnel++;
-                            continue;
-                        }
-                    } else {
-                        String raw = responses.findValue ("Proxy-Authenticate");
-                        reset ();
-                        if (!proxyAuthentication.setHeaders(this,
-                                                authhdr.headerParser(), raw)) {
-                            disconnectInternal();
-                            throw new IOException ("Authentication failure");
-                        }
-                        authObj = null;
-                        doingNTLMp2ndStage = false;
-                        continue;
-                    }
-                }
-                // cache proxy authentication info
-                if (proxyAuthentication != null) {
-                    // cache auth info on success, domain header not relevant.
-                    proxyAuthentication.addToCache();
-                }
-
-                if (respCode == HTTP_OK) {
-                    setTunnelState(TunnelState.TUNNELING);
-                    break;
-                }
-                // we don't know how to deal with other response code
-                // so disconnect and report error
-                disconnectInternal();
-                setTunnelState(TunnelState.NONE);
-                break;
-            } while (retryTunnel < maxRedirects);
-
-            if (retryTunnel >= maxRedirects || (respCode != HTTP_OK)) {
-                throw new IOException("Unable to tunnel through proxy."+
-                                      " Proxy returns \"" +
-                                      statusLine + "\"");
-            }
-        } finally  {
-            if (proxyAuthKey != null) {
-                AuthenticationInfo.endAuthRequest(proxyAuthKey);
-            }
-        }
-
-        // restore original request headers
-        requests = savedRequests;
-
-        // reset responses
-        responses.reset();
-    }
-
-    static String connectRequestURI(URL url) {
-        String host = url.getHost();
-        int port = url.getPort();
-        port = port != -1 ? port : url.getDefaultPort();
-
-        return host + ":" + port;
-    }
-
-    /**
-     * send a CONNECT request for establishing a tunnel to proxy server
-     */
-    private void sendCONNECTRequest() throws IOException {
-        int port = url.getPort();
-
-        requests.set(0, HTTP_CONNECT + " " + connectRequestURI(url)
-                         + " " + httpVersion, null);
-        requests.setIfNotSet("User-Agent", userAgent);
-
-        String host = url.getHost();
-        if (port != -1 && port != url.getDefaultPort()) {
-            host += ":" + String.valueOf(port);
-        }
-        requests.setIfNotSet("Host", host);
-
-        // Not really necessary for a tunnel, but can't hurt
-        requests.setIfNotSet("Accept", acceptString);
-
-        if (http.getHttpKeepAliveSet()) {
-            requests.setIfNotSet("Proxy-Connection", "keep-alive");
-        }
-
-        setPreemptiveProxyAuthentication(requests);
-
-         /* Log the CONNECT request */
-        if (logger.isLoggable(PlatformLogger.FINE)) {
-            logger.fine(requests.toString());
-        }
-
-        http.writeRequests(requests, null);
-    }
-
-    /**
-     * Sets pre-emptive proxy authentication in header
-     */
-    private void setPreemptiveProxyAuthentication(MessageHeader requests) throws IOException {
-        AuthenticationInfo pauth
-            = AuthenticationInfo.getProxyAuth(http.getProxyHostUsed(),
-                                              http.getProxyPortUsed());
-        if (pauth != null && pauth.supportsPreemptiveAuthorization()) {
-            String value;
-            if (pauth instanceof DigestAuthentication) {
-                DigestAuthentication digestProxy = (DigestAuthentication) pauth;
-                if (tunnelState() == TunnelState.SETUP) {
-                    value = digestProxy
-                        .getHeaderValue(connectRequestURI(url), HTTP_CONNECT);
-                } else {
-                    value = digestProxy.getHeaderValue(getRequestURI(), method);
-                }
-            } else {
-                value = pauth.getHeaderValue(url, method);
-            }
-
-            // Sets "Proxy-authorization"
-            requests.set(pauth.getHeaderName(), value);
-            currentProxyCredentials = pauth;
-        }
-    }
-
-    /**
-     * Gets the authentication for an HTTP proxy, and applies it to
-     * the connection.
-     */
-    private AuthenticationInfo getHttpProxyAuthentication (AuthenticationHeader authhdr) {
-        /* get authorization from authenticator */
-        AuthenticationInfo ret = null;
-        String raw = authhdr.raw();
-        String host = http.getProxyHostUsed();
-        int port = http.getProxyPortUsed();
-        if (host != null && authhdr.isPresent()) {
-            HeaderParser p = authhdr.headerParser();
-            String realm = p.findValue("realm");
-            String scheme = authhdr.scheme();
-            AuthScheme authScheme = UNKNOWN;
-            if ("basic".equalsIgnoreCase(scheme)) {
-                authScheme = BASIC;
-            } else if ("digest".equalsIgnoreCase(scheme)) {
-                authScheme = DIGEST;
-            } else if ("ntlm".equalsIgnoreCase(scheme)) {
-                authScheme = NTLM;
-                doingNTLMp2ndStage = true;
-            } else if ("Kerberos".equalsIgnoreCase(scheme)) {
-                authScheme = KERBEROS;
-                doingNTLMp2ndStage = true;
-            } else if ("Negotiate".equalsIgnoreCase(scheme)) {
-                authScheme = NEGOTIATE;
-                doingNTLMp2ndStage = true;
-            }
-
-            if (realm == null)
-                realm = "";
-            proxyAuthKey = AuthenticationInfo.getProxyAuthKey(host, port, realm, authScheme);
-            ret = AuthenticationInfo.getProxyAuth(proxyAuthKey);
-            if (ret == null) {
-                switch (authScheme) {
-                case BASIC:
-                    InetAddress addr = null;
-                    try {
-                        final String finalHost = host;
-                        addr = java.security.AccessController.doPrivileged(
-                            new java.security.PrivilegedExceptionAction<InetAddress>() {
-                                public InetAddress run()
-                                    throws java.net.UnknownHostException {
-                                    return InetAddress.getByName(finalHost);
-                                }
-                            });
-                    } catch (java.security.PrivilegedActionException ignored) {
-                        // User will have an unknown host.
-                    }
-                    PasswordAuthentication a =
-                        privilegedRequestPasswordAuthentication(
-                                    host, addr, port, "http",
-                                    realm, scheme, url, RequestorType.PROXY);
-                    if (a != null) {
-                        ret = new BasicAuthentication(true, host, port, realm, a);
-                    }
-                    break;
-                case DIGEST:
-                    a = privilegedRequestPasswordAuthentication(
-                                    host, null, port, url.getProtocol(),
-                                    realm, scheme, url, RequestorType.PROXY);
-                    if (a != null) {
-                        DigestAuthentication.Parameters params =
-                            new DigestAuthentication.Parameters();
-                        ret = new DigestAuthentication(true, host, port, realm,
-                                                            scheme, a, params);
-                    }
-                    break;
-                case NTLM:
-                    if (NTLMAuthenticationProxy.proxy.supported) {
-                        /* tryTransparentNTLMProxy will always be true the first
-                         * time around, but verify that the platform supports it
-                         * otherwise don't try. */
-                        if (tryTransparentNTLMProxy) {
-                            tryTransparentNTLMProxy =
-                                    NTLMAuthenticationProxy.proxy.supportsTransparentAuth;
-                        }
-                        a = null;
-                        if (tryTransparentNTLMProxy) {
-                            logger.finest("Trying Transparent NTLM authentication");
-                        } else {
-                            a = privilegedRequestPasswordAuthentication(
-                                                host, null, port, url.getProtocol(),
-                                                "", scheme, url, RequestorType.PROXY);
-                        }
-                        /* If we are not trying transparent authentication then
-                         * we need to have a PasswordAuthentication instance. For
-                         * transparent authentication (Windows only) the username
-                         * and password will be picked up from the current logged
-                         * on users credentials.
-                        */
-                        if (tryTransparentNTLMProxy ||
-                              (!tryTransparentNTLMProxy && a != null)) {
-                            ret = NTLMAuthenticationProxy.proxy.create(true, host, port, a);
-                        }
-
-                        /* set to false so that we do not try again */
-                        tryTransparentNTLMProxy = false;
-                    }
-                    break;
-                case NEGOTIATE:
-                    ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
-                    break;
-                case KERBEROS:
-                    ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
-                    break;
-                case UNKNOWN:
-                    logger.finest("Unknown/Unsupported authentication scheme: " + scheme);
-                default:
-                    throw new AssertionError("should not reach here");
-                }
-            }
-            // For backwards compatibility, we also try defaultAuth
-            // REMIND:  Get rid of this for JDK2.0.
-
-            if (ret == null && defaultAuth != null
-                && defaultAuth.schemeSupported(scheme)) {
-                try {
-                    URL u = new URL("http", host, port, "/");
-                    String a = defaultAuth.authString(u, scheme, realm);
-                    if (a != null) {
-                        ret = new BasicAuthentication (true, host, port, realm, a);
-                        // not in cache by default - cache on success
-                    }
-                } catch (java.net.MalformedURLException ignored) {
-                }
-            }
-            if (ret != null) {
-                if (!ret.setHeaders(this, p, raw)) {
-                    ret = null;
-                }
-            }
-        }
-        if (logger.isLoggable(PlatformLogger.FINER)) {
-            logger.finer("Proxy Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
-        }
-        return ret;
-    }
-
-    /**
-     * Gets the authentication for an HTTP server, and applies it to
-     * the connection.
-     * @param authHdr the AuthenticationHeader which tells what auth scheme is
-     * prefered.
-     */
-    private AuthenticationInfo getServerAuthentication (AuthenticationHeader authhdr) {
-        /* get authorization from authenticator */
-        AuthenticationInfo ret = null;
-        String raw = authhdr.raw();
-        /* When we get an NTLM auth from cache, don't set any special headers */
-        if (authhdr.isPresent()) {
-            HeaderParser p = authhdr.headerParser();
-            String realm = p.findValue("realm");
-            String scheme = authhdr.scheme();
-            AuthScheme authScheme = UNKNOWN;
-            if ("basic".equalsIgnoreCase(scheme)) {
-                authScheme = BASIC;
-            } else if ("digest".equalsIgnoreCase(scheme)) {
-                authScheme = DIGEST;
-            } else if ("ntlm".equalsIgnoreCase(scheme)) {
-                authScheme = NTLM;
-                doingNTLM2ndStage = true;
-            } else if ("Kerberos".equalsIgnoreCase(scheme)) {
-                authScheme = KERBEROS;
-                doingNTLM2ndStage = true;
-            } else if ("Negotiate".equalsIgnoreCase(scheme)) {
-                authScheme = NEGOTIATE;
-                doingNTLM2ndStage = true;
-            }
-
-            domain = p.findValue ("domain");
-            if (realm == null)
-                realm = "";
-            serverAuthKey = AuthenticationInfo.getServerAuthKey(url, realm, authScheme);
-            ret = AuthenticationInfo.getServerAuth(serverAuthKey);
-            InetAddress addr = null;
-            if (ret == null) {
-                try {
-                    addr = InetAddress.getByName(url.getHost());
-                } catch (java.net.UnknownHostException ignored) {
-                    // User will have addr = null
-                }
-            }
-            // replacing -1 with default port for a protocol
-            int port = url.getPort();
-            if (port == -1) {
-                port = url.getDefaultPort();
-            }
-            if (ret == null) {
-                switch(authScheme) {
-                case KERBEROS:
-                    ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos"));
-                    break;
-                case NEGOTIATE:
-                    ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate"));
-                    break;
-                case BASIC:
-                    PasswordAuthentication a =
-                        privilegedRequestPasswordAuthentication(
-                            url.getHost(), addr, port, url.getProtocol(),
-                            realm, scheme, url, RequestorType.SERVER);
-                    if (a != null) {
-                        ret = new BasicAuthentication(false, url, realm, a);
-                    }
-                    break;
-                case DIGEST:
-                    a = privilegedRequestPasswordAuthentication(
-                            url.getHost(), addr, port, url.getProtocol(),
-                            realm, scheme, url, RequestorType.SERVER);
-                    if (a != null) {
-                        digestparams = new DigestAuthentication.Parameters();
-                        ret = new DigestAuthentication(false, url, realm, scheme, a, digestparams);
-                    }
-                    break;
-                case NTLM:
-                    if (NTLMAuthenticationProxy.proxy.supported) {
-                        URL url1;
-                        try {
-                            url1 = new URL (url, "/"); /* truncate the path */
-                        } catch (Exception e) {
-                            url1 = url;
-                        }
-
-                        /* tryTransparentNTLMServer will always be true the first
-                         * time around, but verify that the platform supports it
-                         * otherwise don't try. */
-                        if (tryTransparentNTLMServer) {
-                            tryTransparentNTLMServer =
-                                    NTLMAuthenticationProxy.proxy.supportsTransparentAuth;
-                            /* If the platform supports transparent authentication
-                             * then check if we are in a secure environment
-                             * whether, or not, we should try transparent authentication.*/
-                            if (tryTransparentNTLMServer) {
-                                tryTransparentNTLMServer =
-                                        NTLMAuthenticationProxy.proxy.isTrustedSite(url);
-                            }
-                        }
-                        a = null;
-                        if (tryTransparentNTLMServer) {
-                            logger.finest("Trying Transparent NTLM authentication");
-                        } else {
-                            a = privilegedRequestPasswordAuthentication(
-                                url.getHost(), addr, port, url.getProtocol(),
-                                "", scheme, url, RequestorType.SERVER);
-                        }
-
-                        /* If we are not trying transparent authentication then
-                         * we need to have a PasswordAuthentication instance. For
-                         * transparent authentication (Windows only) the username
-                         * and password will be picked up from the current logged
-                         * on users credentials.
-                         */
-                        if (tryTransparentNTLMServer ||
-                              (!tryTransparentNTLMServer && a != null)) {
-                            ret = NTLMAuthenticationProxy.proxy.create(false, url1, a);
-                        }
-
-                        /* set to false so that we do not try again */
-                        tryTransparentNTLMServer = false;
-                    }
-                    break;
-                case UNKNOWN:
-                    logger.finest("Unknown/Unsupported authentication scheme: " + scheme);
-                default:
-                    throw new AssertionError("should not reach here");
-                }
-            }
-
-            // For backwards compatibility, we also try defaultAuth
-            // REMIND:  Get rid of this for JDK2.0.
-
-            if (ret == null && defaultAuth != null
-                && defaultAuth.schemeSupported(scheme)) {
-                String a = defaultAuth.authString(url, scheme, realm);
-                if (a != null) {
-                    ret = new BasicAuthentication (false, url, realm, a);
-                    // not in cache by default - cache on success
-                }
-            }
-
-            if (ret != null ) {
-                if (!ret.setHeaders(this, p, raw)) {
-                    ret = null;
-                }
-            }
-        }
-        if (logger.isLoggable(PlatformLogger.FINER)) {
-            logger.finer("Server Authentication for " + authhdr.toString() +" returned " + (ret != null ? ret.toString() : "null"));
-        }
-        return ret;
-    }
-
-    /* inclose will be true if called from close(), in which case we
-     * force the call to check because this is the last chance to do so.
-     * If not in close(), then the authentication info could arrive in a trailer
-     * field, which we have not read yet.
-     */
-    private void checkResponseCredentials (boolean inClose) throws IOException {
-        try {
-            if (!needToCheck)
-                return;
-            if ((validateProxy && currentProxyCredentials != null) &&
-                (currentProxyCredentials instanceof DigestAuthentication)) {
-                String raw = responses.findValue ("Proxy-Authentication-Info");
-                if (inClose || (raw != null)) {
-                    DigestAuthentication da = (DigestAuthentication)
-                        currentProxyCredentials;
-                    da.checkResponse (raw, method, getRequestURI());
-                    currentProxyCredentials = null;
-                }
-            }
-            if ((validateServer && currentServerCredentials != null) &&
-                (currentServerCredentials instanceof DigestAuthentication)) {
-                String raw = responses.findValue ("Authentication-Info");
-                if (inClose || (raw != null)) {
-                    DigestAuthentication da = (DigestAuthentication)
-                        currentServerCredentials;
-                    da.checkResponse (raw, method, url);
-                    currentServerCredentials = null;
-                }
-            }
-            if ((currentServerCredentials==null) && (currentProxyCredentials == null)) {
-                needToCheck = false;
-            }
-        } catch (IOException e) {
-            disconnectInternal();
-            connected = false;
-            throw e;
-        }
-    }
-
-   /* The request URI used in the request line for this request.
-    * Also, needed for digest authentication
-    */
-
-    String requestURI = null;
-
-    String getRequestURI() throws IOException {
-        if (requestURI == null) {
-            requestURI = http.getURLFile();
-        }
-        return requestURI;
-    }
-
-    /* Tells us whether to follow a redirect.  If so, it
-     * closes the connection (break any keep-alive) and
-     * resets the url, re-connects, and resets the request
-     * property.
-     */
-    private boolean followRedirect() throws IOException {
-        if (!getInstanceFollowRedirects()) {
-            return false;
-        }
-
-        int stat = getResponseCode();
-        if (stat < 300 || stat > 307 || stat == 306
-                                || stat == HTTP_NOT_MODIFIED) {
-            return false;
-        }
-        String loc = getHeaderField("Location");
-        if (loc == null) {
-            /* this should be present - if not, we have no choice
-             * but to go forward w/ the response we got
-             */
-            return false;
-        }
-        URL locUrl;
-        try {
-            locUrl = new URL(loc);
-            if (!url.getProtocol().equalsIgnoreCase(locUrl.getProtocol())) {
-                return false;
-            }
-
-        } catch (MalformedURLException mue) {
-          // treat loc as a relative URI to conform to popular browsers
-          locUrl = new URL(url, loc);
-        }
-        disconnectInternal();
-        if (streaming()) {
-            throw new HttpRetryException (RETRY_MSG3, stat, loc);
-        }
-        if (logger.isLoggable(PlatformLogger.FINE)) {
-            logger.fine("Redirected from " + url + " to " + locUrl);
-        }
-
-        // clear out old response headers!!!!
-        responses = new MessageHeader();
-        if (stat == HTTP_USE_PROXY) {
-            /* This means we must re-request the resource through the
-             * proxy denoted in the "Location:" field of the response.
-             * Judging by the spec, the string in the Location header
-             * _should_ denote a URL - let's hope for "http://my.proxy.org"
-             * Make a new HttpClient to the proxy, using HttpClient's
-             * Instance-specific proxy fields, but note we're still fetching
-             * the same URL.
-             */
-            String proxyHost = locUrl.getHost();
-            int proxyPort = locUrl.getPort();
-
-            SecurityManager security = System.getSecurityManager();
-            if (security != null) {
-                security.checkConnect(proxyHost, proxyPort);
-            }
-
-            setProxiedClient (url, proxyHost, proxyPort);
-            requests.set(0, method + " " + getRequestURI()+" "  +
-                             httpVersion, null);
-            connected = true;
-        } else {
-            // maintain previous headers, just change the name
-            // of the file we're getting
-            url = locUrl;
-            requestURI = null; // force it to be recalculated
-            if (method.equals("POST") && !Boolean.getBoolean("http.strictPostRedirect") && (stat!=307)) {
-                /* The HTTP/1.1 spec says that a redirect from a POST
-                 * *should not* be immediately turned into a GET, and
-                 * that some HTTP/1.0 clients incorrectly did this.
-                 * Correct behavior redirects a POST to another POST.
-                 * Unfortunately, since most browsers have this incorrect
-                 * behavior, the web works this way now.  Typical usage
-                 * seems to be:
-                 *   POST a login code or passwd to a web page.
-                 *   after validation, the server redirects to another
-                 *     (welcome) page
-                 *   The second request is (erroneously) expected to be GET
-                 *
-                 * We will do the incorrect thing (POST-->GET) by default.
-                 * We will provide the capability to do the "right" thing
-                 * (POST-->POST) by a system property, "http.strictPostRedirect=true"
-                 */
-
-                requests = new MessageHeader();
-                setRequests = false;
-                setRequestMethod("GET");
-                poster = null;
-                if (!checkReuseConnection())
-                    connect();
-            } else {
-                if (!checkReuseConnection())
-                    connect();
-                /* Even after a connect() call, http variable still can be
-                 * null, if a ResponseCache has been installed and it returns
-                 * a non-null CacheResponse instance. So check nullity before using it.
-                 *
-                 * And further, if http is null, there's no need to do anything
-                 * about request headers because successive http session will use
-                 * cachedInputStream/cachedHeaders anyway, which is returned by
-                 * CacheResponse.
-                 */
-                if (http != null) {
-                    requests.set(0, method + " " + getRequestURI()+" "  +
-                                 httpVersion, null);
-                    int port = url.getPort();
-                    String host = url.getHost();
-                    if (port != -1 && port != url.getDefaultPort()) {
-                        host += ":" + String.valueOf(port);
-                    }
-                    requests.set("Host", host);
-                }
-            }
-        }
-        return true;
-    }
-
-    /* dummy byte buffer for reading off socket prior to closing */
-    byte[] cdata = new byte [128];
-
-    /**
-     * Reset (without disconnecting the TCP conn) in order to do another transaction with this instance
-     */
-    private void reset() throws IOException {
-        http.reuse = true;
-        /* must save before calling close */
-        reuseClient = http;
-        InputStream is = http.getInputStream();
-        if (!method.equals("HEAD")) {
-            try {
-                /* we want to read the rest of the response without using the
-                 * hurry mechanism, because that would close the connection
-                 * if everything is not available immediately
-                 */
-                if ((is instanceof ChunkedInputStream) ||
-                    (is instanceof MeteredStream)) {
-                    /* reading until eof will not block */
-                    while (is.read (cdata) > 0) {}
-                } else {
-                    /* raw stream, which will block on read, so only read
-                     * the expected number of bytes, probably 0
-                     */
-                    long cl = 0;
-                    int n = 0;
-                    String cls = responses.findValue ("Content-Length");
-                    if (cls != null) {
-                        try {
-                            cl = Long.parseLong (cls);
-                        } catch (NumberFormatException e) {
-                            cl = 0;
-                        }
-                    }
-                    for (long i=0; i<cl; ) {
-                        if ((n = is.read (cdata)) == -1) {
-                            break;
-                        } else {
-                            i+= n;
-                        }
-                    }
-                }
-            } catch (IOException e) {
-                http.reuse = false;
-                reuseClient = null;
-                disconnectInternal();
-                return;
-            }
-            try {
-                if (is instanceof MeteredStream) {
-                    is.close();
-                }
-            } catch (IOException e) { }
-        }
-        responseCode = -1;
-        responses = new MessageHeader();
-        connected = false;
-    }
-
-    /**
-     * Disconnect from the web server at the first 401 error. Do not
-     * disconnect when using a proxy, a good proxy should have already
-     * closed the connection to the web server.
-     */
-    private void disconnectWeb() throws IOException {
-        if (usingProxy() && http.isKeepingAlive()) {
-            responseCode = -1;
-            // clean up, particularly, skip the content part
-            // of a 401 error response
-            reset();
-        } else {
-            disconnectInternal();
-        }
-    }
-
-    /**
-     * Disconnect from the server (for internal use)
-     */
-    private void disconnectInternal() {
-        responseCode = -1;
-        inputStream = null;
-        if (pi != null) {
-            pi.finishTracking();
-            pi = null;
-        }
-        if (http != null) {
-            http.closeServer();
-            http = null;
-            connected = false;
-        }
-    }
-
-    /**
-     * Disconnect from the server (public API)
-     */
-    public void disconnect() {
-
-        responseCode = -1;
-        if (pi != null) {
-            pi.finishTracking();
-            pi = null;
-        }
-
-        if (http != null) {
-            /*
-             * If we have an input stream this means we received a response
-             * from the server. That stream may have been read to EOF and
-             * dependening on the stream type may already be closed or the
-             * the http client may be returned to the keep-alive cache.
-             * If the http client has been returned to the keep-alive cache
-             * it may be closed (idle timeout) or may be allocated to
-             * another request.
-             *
-             * In other to avoid timing issues we close the input stream
-             * which will either close the underlying connection or return
-             * the client to the cache. If there's a possibility that the
-             * client has been returned to the cache (ie: stream is a keep
-             * alive stream or a chunked input stream) then we remove an
-             * idle connection to the server. Note that this approach
-             * can be considered an approximation in that we may close a
-             * different idle connection to that used by the request.
-             * Additionally it's possible that we close two connections
-             * - the first becuase it wasn't an EOF (and couldn't be
-             * hurried) - the second, another idle connection to the
-             * same server. The is okay because "disconnect" is an
-             * indication that the application doesn't intend to access
-             * this http server for a while.
-             */
-
-            if (inputStream != null) {
-                HttpClient hc = http;
-
-                // un-synchronized
-                boolean ka = hc.isKeepingAlive();
-
-                try {
-                    inputStream.close();
-                } catch (IOException ioe) { }
-
-                // if the connection is persistent it may have been closed
-                // or returned to the keep-alive cache. If it's been returned
-                // to the keep-alive cache then we would like to close it
-                // but it may have been allocated
-
-                if (ka) {
-                    hc.closeIdleConnection();
-                }
-
-
-            } else {
-                // We are deliberatly being disconnected so HttpClient
-                // should not try to resend the request no matter what stage
-                // of the connection we are in.
-                http.setDoNotRetry(true);
-
-                http.closeServer();
-            }
-
-            //      poster = null;
-            http = null;
-            connected = false;
-        }
-        cachedInputStream = null;
-        if (cachedHeaders != null) {
-            cachedHeaders.reset();
-        }
-    }
-
-    public boolean usingProxy() {
-        if (http != null) {
-            return (http.getProxyHostUsed() != null);
-        }
-        return false;
-    }
-
-    // constant strings represent set-cookie header names
-    private final static String SET_COOKIE = "set-cookie";
-    private final static String SET_COOKIE2 = "set-cookie2";
-
-    /**
-     * Returns a filtered version of the given headers value.
-     *
-     * Note: The implementation currently only filters out HttpOnly cookies
-     *       from Set-Cookie and Set-Cookie2 headers.
-     */
-    private String filterHeaderField(String name, String value) {
-        if (value == null)
-            return null;
-
-        if (SET_COOKIE.equalsIgnoreCase(name) ||
-            SET_COOKIE2.equalsIgnoreCase(name)) {
-            // Filtering only if there is a cookie handler. [Assumption: the
-            // cookie handler will store/retrieve the HttpOnly cookies]
-            if (cookieHandler == null)
-                return value;
-
-            StringBuilder retValue = new StringBuilder();
-            List<HttpCookie> cookies = HttpCookie.parse(value, true);
-            boolean multipleCookies = false;
-            for (HttpCookie cookie : cookies) {
-                // skip HttpOnly cookies
-                if (cookie.isHttpOnly())
-                    continue;
-                if (multipleCookies)
-                    retValue.append(',');  // RFC 2965, comma separated
-                retValue.append(cookie.header);
-                multipleCookies = true;
-            }
-
-            return retValue.length() == 0 ? "" : retValue.toString();
-        }
-
-        return value;
-    }
-
-    // Cache the filtered response headers so that they don't need
-    // to be generated for every getHeaderFields() call.
-    private Map<String, List<String>> filteredHeaders;  // null
-
-    private Map<String, List<String>> getFilteredHeaderFields() {
-        if (filteredHeaders != null)
-            return filteredHeaders;
-
-        Map<String, List<String>> headers, tmpMap = new HashMap<>();
-
-        if (cachedHeaders != null)
-            headers = cachedHeaders.getHeaders();
-        else
-            headers = responses.getHeaders();
-
-        for (Map.Entry<String, List<String>> e: headers.entrySet()) {
-            String key = e.getKey();
-            List<String> values = e.getValue(), filteredVals = new ArrayList<>();
-            for (String value : values) {
-                String fVal = filterHeaderField(key, value);
-                if (fVal != null)
-                    filteredVals.add(fVal);
-            }
-            if (!filteredVals.isEmpty())
-                tmpMap.put(key, Collections.unmodifiableList(filteredVals));
-        }
-
-        return filteredHeaders = Collections.unmodifiableMap(tmpMap);
-    }
-
-    /**
-     * Gets a header field by name. Returns null if not known.
-     * @param name the name of the header field
-     */
-    @Override
-    public String getHeaderField(String name) {
-        try {
-            getInputStream();
-        } catch (IOException e) {}
-
-        if (cachedHeaders != null) {
-            return filterHeaderField(name, cachedHeaders.findValue(name));
-        }
-
-        return filterHeaderField(name, responses.findValue(name));
-    }
-
-    /**
-     * 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
-     */
-    @Override
-    public Map<String, List<String>> getHeaderFields() {
-        try {
-            getInputStream();
-        } catch (IOException e) {}
-
-        return getFilteredHeaderFields();
-    }
-
-    /**
-     * Gets a header field by index. Returns null if not known.
-     * @param n the index of the header field
-     */
-    @Override
-    public String getHeaderField(int n) {
-        try {
-            getInputStream();
-        } catch (IOException e) {}
-
-        if (cachedHeaders != null) {
-           return filterHeaderField(cachedHeaders.getKey(n),
-                                    cachedHeaders.getValue(n));
-        }
-        return filterHeaderField(responses.getKey(n), responses.getValue(n));
-    }
-
-    /**
-     * Gets a header field by index. Returns null if not known.
-     * @param n the index of the header field
-     */
-    @Override
-    public String getHeaderFieldKey(int n) {
-        try {
-            getInputStream();
-        } catch (IOException e) {}
-
-        if (cachedHeaders != null) {
-            return cachedHeaders.getKey(n);
-        }
-
-        return responses.getKey(n);
-    }
-
-    /**
-     * Sets request property. If a property with the key already
-     * exists, overwrite its value with the new value.
-     * @param value the value to be set
-     */
-    @Override
-    public void setRequestProperty(String key, String value) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
-        if (key == null)
-            throw new NullPointerException ("key is null");
-
-        if (isExternalMessageHeaderAllowed(key, value)) {
-            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</code>").
-     * @param   value  the value associated with it.
-     * @see #getRequestProperties(java.lang.String)
-     * @since 1.4
-     */
-    @Override
-    public void addRequestProperty(String key, String value) {
-        if (connected)
-            throw new IllegalStateException("Already connected");
-        if (key == null)
-            throw new NullPointerException ("key is null");
-
-        if (isExternalMessageHeaderAllowed(key, value)) {
-            requests.add(key, value);
-        }
-    }
-
-    //
-    // Set a property for authentication.  This can safely disregard
-    // the connected test.
-    //
-    public void setAuthenticationProperty(String key, String value) {
-        checkMessageHeader(key, value);
-        requests.set(key, value);
-    }
-
-    @Override
-    public synchronized String getRequestProperty (String key) {
-        if (key == null) {
-            return null;
-        }
-
-        // don't return headers containing security sensitive information
-        for (int i=0; i < EXCLUDE_HEADERS.length; i++) {
-            if (key.equalsIgnoreCase(EXCLUDE_HEADERS[i])) {
-                return null;
-            }
-        }
-        if (!setUserCookies) {
-            if (key.equalsIgnoreCase("Cookie")) {
-                return userCookies;
-            }
-            if (key.equalsIgnoreCase("Cookie2")) {
-                return userCookies2;
-            }
-        }
-        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
-     */
-    @Override
-    public synchronized Map<String, List<String>> getRequestProperties() {
-        if (connected)
-            throw new IllegalStateException("Already connected");
-
-        // exclude headers containing security-sensitive info
-        if (setUserCookies) {
-            return requests.getHeaders(EXCLUDE_HEADERS);
-        }
-        /*
-         * The cookies in the requests message headers may have
-         * been modified. Use the saved user cookies instead.
-         */
-        Map userCookiesMap = null;
-        if (userCookies != null || userCookies2 != null) {
-            userCookiesMap = new HashMap();
-            if (userCookies != null) {
-                userCookiesMap.put("Cookie", userCookies);
-            }
-            if (userCookies2 != null) {
-                userCookiesMap.put("Cookie2", userCookies2);
-            }
-        }
-        return requests.filterAndAddHeaders(EXCLUDE_HEADERS2, userCookiesMap);
-    }
-
-    @Override
-    public void setConnectTimeout(int timeout) {
-        if (timeout < 0)
-            throw new IllegalArgumentException("timeouts can't 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</code> that indicates the connect timeout
-     *         value in milliseconds
-     * @see java.net.URLConnection#setConnectTimeout(int)
-     * @see java.net.URLConnection#connect()
-     * @since 1.5
-     */
-    @Override
-    public int getConnectTimeout() {
-        return (connectTimeout < 0 ? 0 : 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</code> that specifies the timeout
-     * value to be used in milliseconds
-     * @throws IllegalArgumentException if the timeout parameter is negative
-     *
-     * @see java.net.URLConnectiongetReadTimeout()
-     * @see java.io.InputStream#read()
-     * @since 1.5
-     */
-    @Override
-    public void setReadTimeout(int timeout) {
-        if (timeout < 0)
-            throw new IllegalArgumentException("timeouts can't 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</code> that indicates the read timeout
-     *         value in milliseconds
-     *
-     * @see java.net.URLConnection#setReadTimeout(int)
-     * @see java.io.InputStream#read()
-     * @since 1.5
-     */
-    @Override
-    public int getReadTimeout() {
-        return readTimeout < 0 ? 0 : readTimeout;
-    }
-
-    public CookieHandler getCookieHandler() {
-        return cookieHandler;
-    }
-
-    String getMethod() {
-        return method;
-    }
-
-    private MessageHeader mapToMessageHeader(Map<String, List<String>> map) {
-        MessageHeader headers = new MessageHeader();
-        if (map == null || map.isEmpty()) {
-            return headers;
-        }
-        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
-            String key = entry.getKey();
-            List<String> values = entry.getValue();
-            for (String value : values) {
-                if (key == null) {
-                    headers.prepend(key, value);
-                } else {
-                    headers.add(key, value);
-                }
-            }
-        }
-        return headers;
-    }
-
-    /* The purpose of this wrapper is just to capture the close() call
-     * so we can check authentication information that may have
-     * arrived in a Trailer field
-     */
-    class HttpInputStream extends FilterInputStream {
-        private CacheRequest cacheRequest;
-        private OutputStream outputStream;
-        private boolean marked = false;
-        private int inCache = 0;
-        private int markCount = 0;
-
-        public HttpInputStream (InputStream is) {
-            super (is);
-            this.cacheRequest = null;
-            this.outputStream = null;
-        }
-
-        public HttpInputStream (InputStream is, CacheRequest cacheRequest) {
-            super (is);
-            this.cacheRequest = cacheRequest;
-            try {
-                this.outputStream = cacheRequest.getBody();
-            } catch (IOException ioex) {
-                this.cacheRequest.abort();
-                this.cacheRequest = null;
-                this.outputStream = null;
-            }
-        }
-
-        /**
-         * Marks the current position in this input stream. A subsequent
-         * call to the <code>reset</code> method repositions this stream at
-         * the last marked position so that subsequent reads re-read the same
-         * bytes.
-         * <p>
-         * The <code>readlimit</code> argument tells this input stream to
-         * allow that many bytes to be read before the mark position gets
-         * invalidated.
-         * <p>
-         * This method simply performs <code>in.mark(readlimit)</code>.
-         *
-         * @param   readlimit   the maximum limit of bytes that can be read before
-         *                      the mark position becomes invalid.
-         * @see     java.io.FilterInputStream#in
-         * @see     java.io.FilterInputStream#reset()
-         */
-        @Override
-        public synchronized void mark(int readlimit) {
-            super.mark(readlimit);
-            if (cacheRequest != null) {
-                marked = true;
-                markCount = 0;
-            }
-        }
-
-        /**
-         * Repositions this stream to the position at the time the
-         * <code>mark</code> method was last called on this input stream.
-         * <p>
-         * This method
-         * simply performs <code>in.reset()</code>.
-         * <p>
-         * Stream marks are intended to be used in
-         * situations where you need to read ahead a little to see what's in
-         * the stream. Often this is most easily done by invoking some
-         * general parser. If the stream is of the type handled by the
-         * parse, it just chugs along happily. If the stream is not of
-         * that type, the parser should toss an exception when it fails.
-         * If this happens within readlimit bytes, it allows the outer
-         * code to reset the stream and try another parser.
-         *
-         * @exception  IOException  if the stream has not been marked or if the
-         *               mark has been invalidated.
-         * @see        java.io.FilterInputStream#in
-         * @see        java.io.FilterInputStream#mark(int)
-         */
-        @Override
-        public synchronized void reset() throws IOException {
-            super.reset();
-            if (cacheRequest != null) {
-                marked = false;
-                inCache += markCount;
-            }
-        }
-
-        @Override
-        public int read() throws IOException {
-            try {
-                byte[] b = new byte[1];
-                int ret = read(b);
-                return (ret == -1? ret : (b[0] & 0x00FF));
-            } catch (IOException ioex) {
-                if (cacheRequest != null) {
-                    cacheRequest.abort();
-                }
-                throw ioex;
-            }
-        }
-
-        @Override
-        public int read(byte[] b) throws IOException {
-            return read(b, 0, b.length);
-        }
-
-        @Override
-        public int read(byte[] b, int off, int len) throws IOException {
-            try {
-                int newLen = super.read(b, off, len);
-                int nWrite;
-                // write to cache
-                if (inCache > 0) {
-                    if (inCache >= newLen) {
-                        inCache -= newLen;
-                        nWrite = 0;
-                    } else {
-                        nWrite = newLen - inCache;
-                        inCache = 0;
-                    }
-                } else {
-                    nWrite = newLen;
-                }
-                if (nWrite > 0 && outputStream != null)
-                    outputStream.write(b, off + (newLen-nWrite), nWrite);
-                if (marked) {
-                    markCount += newLen;
-                }
-                return newLen;
-            } catch (IOException ioex) {
-                if (cacheRequest != null) {
-                    cacheRequest.abort();
-                }
-                throw ioex;
-            }
-        }
-
-        /* skip() calls read() in order to ensure that entire response gets
-         * cached. same implementation as InputStream.skip */
-
-        private byte[] skipBuffer;
-        private static final int SKIP_BUFFER_SIZE = 8096;
-
-        @Override
-        public long skip (long n) throws IOException {
-
-            long remaining = n;
-            int nr;
-            if (skipBuffer == null)
-                skipBuffer = new byte[SKIP_BUFFER_SIZE];
-
-            byte[] localSkipBuffer = skipBuffer;
-
-            if (n <= 0) {
-                return 0;
-            }
-
-            while (remaining > 0) {
-                nr = read(localSkipBuffer, 0,
-                          (int) Math.min(SKIP_BUFFER_SIZE, remaining));
-                if (nr < 0) {
-                    break;
-                }
-                remaining -= nr;
-            }
-
-            return n - remaining;
-        }
-
-        @Override
-        public void close () throws IOException {
-            try {
-                if (outputStream != null) {
-                    if (read() != -1) {
-                        cacheRequest.abort();
-                    } else {
-                        outputStream.close();
-                    }
-                }
-                super.close ();
-            } catch (IOException ioex) {
-                if (cacheRequest != null) {
-                    cacheRequest.abort();
-                }
-                throw ioex;
-            } finally {
-                HttpURLConnection.this.http = null;
-                checkResponseCredentials (true);
-            }
-        }
-    }
-
-    class StreamingOutputStream extends FilterOutputStream {
-
-        long expected;
-        long written;
-        boolean closed;
-        boolean error;
-        IOException errorExcp;
-
-        /**
-         * expectedLength == -1 if the stream is chunked
-         * expectedLength > 0 if the stream is fixed content-length
-         *    In the 2nd case, we make sure the expected number of
-         *    of bytes are actually written
-         */
-        StreamingOutputStream (OutputStream os, long expectedLength) {
-            super (os);
-            expected = expectedLength;
-            written = 0L;
-            closed = false;
-            error = false;
-        }
-
-        @Override
-        public void write (int b) throws IOException {
-            checkError();
-            written ++;
-            if (expected != -1L && written > expected) {
-                throw new IOException ("too many bytes written");
-            }
-            out.write (b);
-        }
-
-        @Override
-        public void write (byte[] b) throws IOException {
-            write (b, 0, b.length);
-        }
-
-        @Override
-        public void write (byte[] b, int off, int len) throws IOException {
-            checkError();
-            written += len;
-            if (expected != -1L && written > expected) {
-                out.close ();
-                throw new IOException ("too many bytes written");
-            }
-            out.write (b, off, len);
-        }
-
-        void checkError () throws IOException {
-            if (closed) {
-                throw new IOException ("Stream is closed");
-            }
-            if (error) {
-                throw errorExcp;
-            }
-            if (((PrintStream)out).checkError()) {
-                throw new IOException("Error writing request body to server");
-            }
-        }
-
-        /* this is called to check that all the bytes
-         * that were supposed to be written were written
-         * and that the stream is now closed().
-         */
-        boolean writtenOK () {
-            return closed && ! error;
-        }
-
-        @Override
-        public void close () throws IOException {
-            if (closed) {
-                return;
-            }
-            closed = true;
-            if (expected != -1L) {
-                /* not chunked */
-                if (written != expected) {
-                    error = true;
-                    errorExcp = new IOException ("insufficient data written");
-                    out.close ();
-                    throw errorExcp;
-                }
-                super.flush(); /* can't close the socket */
-            } else {
-                /* chunked */
-                super.close (); /* force final chunk to be written */
-                /* trailing \r\n */
-                OutputStream o = http.getOutputStream();
-                o.write ('\r');
-                o.write ('\n');
-                o.flush();
-            }
-        }
-    }
-
-
-    static class ErrorStream extends InputStream {
-        ByteBuffer buffer;
-        InputStream is;
-
-        private ErrorStream(ByteBuffer buf) {
-            buffer = buf;
-            is = null;
-        }
-
-        private ErrorStream(ByteBuffer buf, InputStream is) {
-            buffer = buf;
-            this.is = is;
-        }
-
-        // when this method is called, it's either the case that cl > 0, or
-        // if chunk-encoded, cl = -1; in other words, cl can't be 0
-        public static InputStream getErrorStream(InputStream is, long cl, HttpClient http) {
-
-            // cl can't be 0; this following is here for extra precaution
-            if (cl == 0) {
-                return null;
-            }
-
-            try {
-                // set SO_TIMEOUT to 1/5th of the total timeout
-                // remember the old timeout value so that we can restore it
-                int oldTimeout = http.getReadTimeout();
-                http.setReadTimeout(timeout4ESBuffer/5);
-
-                long expected = 0;
-                boolean isChunked = false;
-                // the chunked case
-                if (cl < 0) {
-                    expected = bufSize4ES;
-                    isChunked = true;
-                } else {
-                    expected = cl;
-                }
-                if (expected <= bufSize4ES) {
-                    int exp = (int) expected;
-                    byte[] buffer = new byte[exp];
-                    int count = 0, time = 0, len = 0;
-                    do {
-                        try {
-                            len = is.read(buffer, count,
-                                             buffer.length - count);
-                            if (len < 0) {
-                                if (isChunked) {
-                                    // chunked ended
-                                    // if chunked ended prematurely,
-                                    // an IOException would be thrown
-                                    break;
-                                }
-                                // the server sends less than cl bytes of data
-                                throw new IOException("the server closes"+
-                                                      " before sending "+cl+
-                                                      " bytes of data");
-                            }
-                            count += len;
-                        } catch (SocketTimeoutException ex) {
-                            time += timeout4ESBuffer/5;
-                        }
-                    } while (count < exp && time < timeout4ESBuffer);
-
-                    // reset SO_TIMEOUT to old value
-                    http.setReadTimeout(oldTimeout);
-
-                    // if count < cl at this point, we will not try to reuse
-                    // the connection
-                    if (count == 0) {
-                        // since we haven't read anything,
-                        // we will return the underlying
-                        // inputstream back to the application
-                        return null;
-                    }  else if ((count == expected && !(isChunked)) || (isChunked && len <0)) {
-                        // put the connection into keep-alive cache
-                        // the inputstream will try to do the right thing
-                        is.close();
-                        return new ErrorStream(ByteBuffer.wrap(buffer, 0, count));
-                    } else {
-                        // we read part of the response body
-                        return new ErrorStream(
-                                      ByteBuffer.wrap(buffer, 0, count), is);
-                    }
-                }
-                return null;
-            } catch (IOException ioex) {
-                // ioex.printStackTrace();
-                return null;
-            }
-        }
-
-        @Override
-        public int available() throws IOException {
-            if (is == null) {
-                return buffer.remaining();
-            } else {
-                return buffer.remaining()+is.available();
-            }
-        }
-
-        public int read() throws IOException {
-            byte[] b = new byte[1];
-            int ret = read(b);
-            return (ret == -1? ret : (b[0] & 0x00FF));
-        }
-
-        @Override
-        public int read(byte[] b) throws IOException {
-            return read(b, 0, b.length);
-        }
-
-        @Override
-        public int read(byte[] b, int off, int len) throws IOException {
-            int rem = buffer.remaining();
-            if (rem > 0) {
-                int ret = rem < len? rem : len;
-                buffer.get(b, off, ret);
-                return ret;
-            } else {
-                if (is == null) {
-                    return -1;
-                } else {
-                    return is.read(b, off, len);
-                }
-            }
-        }
-
-        @Override
-        public void close() throws IOException {
-            buffer = null;
-            if (is != null) {
-                is.close();
-            }
-        }
-    }
-}
-
-/** An input stream that just returns EOF.  This is for
- * HTTP URLConnections that are KeepAlive && use the
- * HEAD method - i.e., stream not dead, but nothing to be read.
- */
-
-class EmptyInputStream extends InputStream {
-
-    @Override
-    public int available() {
-        return 0;
-    }
-
-    public int read() {
-        return -1;
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/NTLMAuthenticationProxy.java b/ojluni/src/main/java/sun/net/www/protocol/http/NTLMAuthenticationProxy.java
deleted file mode 100644
index 5d656a0..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/NTLMAuthenticationProxy.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2009, 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 sun.net.www.protocol.http;
-
-import java.net.URL;
-import java.net.PasswordAuthentication;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Method;
-import sun.util.logging.PlatformLogger;
-
-/**
- * Proxy class for loading NTLMAuthentication, so as to remove static
- * dependancy.
- */
-class NTLMAuthenticationProxy {
-    private static Method supportsTA;
-    private static Method isTrustedSite;
-    private static final String clazzStr = "sun.net.www.protocol.http.ntlm.NTLMAuthentication";
-    private static final String supportsTAStr = "supportsTransparentAuth";
-    private static final String isTrustedSiteStr = "isTrustedSite";
-
-    static final NTLMAuthenticationProxy proxy = tryLoadNTLMAuthentication();
-    static final boolean supported = proxy != null ? true : false;
-    static final boolean supportsTransparentAuth = supported ? supportsTransparentAuth() : false;
-
-    private final Constructor<? extends AuthenticationInfo> threeArgCtr;
-    private final Constructor<? extends AuthenticationInfo> fiveArgCtr;
-
-    private NTLMAuthenticationProxy(Constructor<? extends AuthenticationInfo> threeArgCtr,
-                                    Constructor<? extends AuthenticationInfo> fiveArgCtr) {
-        this.threeArgCtr = threeArgCtr;
-        this.fiveArgCtr = fiveArgCtr;
-    }
-
-
-    AuthenticationInfo create(boolean isProxy,
-                              URL url,
-                              PasswordAuthentication pw) {
-        try {
-            return threeArgCtr.newInstance(isProxy, url, pw);
-        } catch (ReflectiveOperationException roe) {
-            finest(roe);
-        }
-
-        return null;
-    }
-
-    AuthenticationInfo create(boolean isProxy,
-                              String host,
-                              int port,
-                              PasswordAuthentication pw) {
-        try {
-            return fiveArgCtr.newInstance(isProxy, host, port, pw);
-        } catch (ReflectiveOperationException roe) {
-            finest(roe);
-        }
-
-        return null;
-    }
-
-    /* Returns true if the NTLM implementation supports transparent
-     * authentication (try with the current users credentials before
-     * prompting for username and password, etc).
-     */
-    private static boolean supportsTransparentAuth() {
-        try {
-            return (Boolean)supportsTA.invoke(null);
-        } catch (ReflectiveOperationException roe) {
-            finest(roe);
-        }
-
-        return false;
-    }
-
-    /* Transparent authentication should only be tried with a trusted
-     * site ( when running in a secure environment ).
-     */
-    public static boolean isTrustedSite(URL url) {
-        try {
-            return (Boolean)isTrustedSite.invoke(null, url);
-        } catch (ReflectiveOperationException roe) {
-            finest(roe);
-        }
-
-        return false;
-    }
-
-    /**
-     * Loads the NTLM authentiation implementation through reflection. If
-     * the class is present, then it must have the required constructors and
-     * method. Otherwise, it is considered an error.
-     */
-    @SuppressWarnings("unchecked")
-    private static NTLMAuthenticationProxy tryLoadNTLMAuthentication() {
-        Class<? extends AuthenticationInfo> cl;
-        Constructor<? extends AuthenticationInfo> threeArg, fiveArg;
-        try {
-            cl = (Class<? extends AuthenticationInfo>)Class.forName(clazzStr, true, null);
-            if (cl != null) {
-                threeArg = cl.getConstructor(boolean.class,
-                                             URL.class,
-                                             PasswordAuthentication.class);
-                fiveArg = cl.getConstructor(boolean.class,
-                                            String.class,
-                                            int.class,
-                                            PasswordAuthentication.class);
-                supportsTA = cl.getDeclaredMethod(supportsTAStr);
-                isTrustedSite = cl.getDeclaredMethod(isTrustedSiteStr, java.net.URL.class);
-                return new NTLMAuthenticationProxy(threeArg,
-                                                   fiveArg);
-            }
-        } catch (ClassNotFoundException cnfe) {
-            finest(cnfe);
-        } catch (ReflectiveOperationException roe) {
-            throw new AssertionError(roe);
-        }
-
-        return null;
-    }
-
-    static void finest(Exception e) {
-        PlatformLogger logger = HttpURLConnection.getHttpLogger();
-        logger.finest("NTLMAuthenticationProxy: " + e);
-    }
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/NegotiateAuthentication.java b/ojluni/src/main/java/sun/net/www/protocol/http/NegotiateAuthentication.java
deleted file mode 100644
index 23a8a83..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/NegotiateAuthentication.java
+++ /dev/null
@@ -1,217 +0,0 @@
-/*
- * Copyright (c) 2005, 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 sun.net.www.protocol.http;
-
-import java.net.URL;
-import java.io.IOException;
-import java.net.Authenticator.RequestorType;
-import java.util.HashMap;
-import sun.net.www.HeaderParser;
-import sun.misc.BASE64Decoder;
-import sun.misc.BASE64Encoder;
-import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE;
-import static sun.net.www.protocol.http.AuthScheme.KERBEROS;
-
-/**
- * NegotiateAuthentication:
- *
- * @author weijun.wang@sun.com
- * @since 1.6
- */
-
-class NegotiateAuthentication extends AuthenticationInfo {
-
-    private static final long serialVersionUID = 100L;
-
-    final private HttpCallerInfo hci;
-
-    // These maps are used to manage the GSS availability for diffrent
-    // hosts. The key for both maps is the host name.
-    // <code>supported</code> is set when isSupported is checked,
-    // if it's true, a cached Negotiator is put into <code>cache</code>.
-    // the cache can be used only once, so after the first use, it's cleaned.
-    static HashMap <String, Boolean> supported = null;
-    static HashMap <String, Negotiator> cache = null;
-
-    // The HTTP Negotiate Helper
-    private Negotiator negotiator = null;
-
-   /**
-    * Constructor used for both WWW and proxy entries.
-    * @param hci a schemed object.
-    */
-    public NegotiateAuthentication(HttpCallerInfo hci) {
-        super(RequestorType.PROXY==hci.authType ? PROXY_AUTHENTICATION : SERVER_AUTHENTICATION,
-              hci.scheme.equalsIgnoreCase("Negotiate") ? NEGOTIATE : KERBEROS,
-              hci.url,
-              "");
-        this.hci = hci;
-    }
-
-    /**
-     * @return true if this authentication supports preemptive authorization
-     */
-    @Override
-    public boolean supportsPreemptiveAuthorization() {
-        return false;
-    }
-
-    /**
-     * Find out if the HttpCallerInfo supports Negotiate protocol. In order to
-     * find out yes or no, an initialization of a Negotiator object against it
-     * is tried. The generated object will be cached under the name of ths
-     * hostname at a success try.<br>
-     *
-     * If this method is called for the second time on an HttpCallerInfo with
-     * the same hostname, the answer is retrieved from cache.
-     *
-     * @return true if supported
-     */
-    synchronized public static boolean isSupported(HttpCallerInfo hci) {
-        if (supported == null) {
-            supported = new HashMap <String, Boolean>();
-            cache = new HashMap <String, Negotiator>();
-        }
-        String hostname = hci.host;
-        hostname = hostname.toLowerCase();
-        if (supported.containsKey(hostname)) {
-            return supported.get(hostname);
-        }
-
-        Negotiator neg = Negotiator.getNegotiator(hci);
-        if (neg != null) {
-            supported.put(hostname, true);
-            // the only place cache.put is called. here we can make sure
-            // the object is valid and the oneToken inside is not null
-            cache.put(hostname, neg);
-            return true;
-        } else {
-            supported.put(hostname, false);
-            return false;
-        }
-    }
-
-    /**
-     * Not supported. Must use the setHeaders() method
-     */
-    @Override
-    public String getHeaderValue(URL url, String method) {
-        throw new RuntimeException ("getHeaderValue not supported");
-    }
-
-    /**
-     * Check if the header indicates that the current auth. parameters are stale.
-     * If so, then replace the relevant field with the new value
-     * and return true. Otherwise return false.
-     * returning true means the request can be retried with the same userid/password
-     * returning false means we have to go back to the user to ask for a new
-     * username password.
-     */
-    @Override
-    public boolean isAuthorizationStale (String header) {
-        return false; /* should not be called for Negotiate */
-    }
-
-    /**
-     * Set header(s) on the given connection.
-     * @param conn The connection to apply the header(s) to
-     * @param p A source of header values for this connection, not used because
-     *          HeaderParser converts the fields to lower case, use raw instead
-     * @param raw The raw header field.
-     * @return true if all goes well, false if no headers were set.
-     */
-    @Override
-    public synchronized boolean setHeaders(HttpURLConnection conn, HeaderParser p, String raw) {
-
-        try {
-            String response;
-            byte[] incoming = null;
-            String[] parts = raw.split("\\s+");
-            if (parts.length > 1) {
-                incoming = new BASE64Decoder().decodeBuffer(parts[1]);
-            }
-            response = hci.scheme + " " + new B64Encoder().encode(
-                        incoming==null?firstToken():nextToken(incoming));
-
-            conn.setAuthenticationProperty(getHeaderName(), response);
-            return true;
-        } catch (IOException e) {
-            return false;
-        }
-    }
-
-    /**
-     * return the first token.
-     * @returns the token
-     * @throws IOException if <code>Negotiator.getNegotiator()</code> or
-     *                     <code>Negotiator.firstToken()</code> failed.
-     */
-    private byte[] firstToken() throws IOException {
-        negotiator = null;
-        if (cache != null) {
-            synchronized(cache) {
-                negotiator = cache.get(getHost());
-                if (negotiator != null) {
-                    cache.remove(getHost()); // so that it is only used once
-                }
-            }
-        }
-        if (negotiator == null) {
-            negotiator = Negotiator.getNegotiator(hci);
-            if (negotiator == null) {
-                IOException ioe = new IOException("Cannot initialize Negotiator");
-                throw ioe;
-            }
-        }
-
-        return negotiator.firstToken();
-    }
-
-    /**
-     * return more tokens
-     * @param token the token to be fed into <code>negotiator.nextToken()</code>
-     * @returns the token
-     * @throws IOException if <code>negotiator.nextToken()</code> throws Exception.
-     *  May happen if the input token is invalid.
-     */
-    private byte[] nextToken(byte[] token) throws IOException {
-        return negotiator.nextToken(token);
-    }
-
-    class B64Encoder extends BASE64Encoder {
-        protected int bytesPerLine () {
-            return 100000;  // as big as it can be, maybe INT_MAX
-        }
-    }
-
-    // MS will send a final WWW-Authenticate even if the status is already
-    // 200 OK. The token can be fed into initSecContext() again to determine
-    // if the server can be trusted. This is not the same concept as Digest's
-    // Authentication-Info header.
-    //
-    // Currently we ignore this header.
-
-}
diff --git a/ojluni/src/main/java/sun/net/www/protocol/http/Negotiator.java b/ojluni/src/main/java/sun/net/www/protocol/http/Negotiator.java
deleted file mode 100644
index 522d6fb..0000000
--- a/ojluni/src/main/java/sun/net/www/protocol/http/Negotiator.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (c) 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 sun.net.www.protocol.http;
-
-import java.io.IOException;
-import java.lang.reflect.Constructor;
-import sun.util.logging.PlatformLogger;
-
-/**
- * This abstract class is a bridge to connect NegotiteAuthentication and
- * NegotiatorImpl, so that JAAS and JGSS calls can be made
- */
-public abstract class Negotiator {
-    static Negotiator getNegotiator(HttpCallerInfo hci) {
-
-        // These lines are equivalent to
-        // return new NegotiatorImpl(hci);
-        // The current implementation will make sure NegotiatorImpl is not
-        // directly referenced when compiling, thus smooth the way of building
-        // the J2SE platform where HttpURLConnection is a bootstrap class.
-        //
-        // Makes NegotiatorImpl, and the security classes it references, a
-        // runtime dependency rather than a static one.
-
-        Class clazz;
-        Constructor c;
-        try {
-            clazz = Class.forName("sun.net.www.protocol.http.spnego.NegotiatorImpl", true, null);
-            c = clazz.getConstructor(HttpCallerInfo.class);
-        } catch (ClassNotFoundException cnfe) {
-            finest(cnfe);
-            return null;
-        } catch (ReflectiveOperationException roe) {
-            // if the class is there then something seriously wrong if
-            // the constructor is not.
-            throw new AssertionError(roe);
-        }
-
-        try {
-            return (Negotiator) (c.newInstance(hci));
-        } catch (ReflectiveOperationException roe) {
-            finest(roe);
-            Throwable t = roe.getCause();
-            if (t != null && t instanceof Exception)
-                finest((Exception)t);
-            return null;
-        }
-    }
-
-    public abstract byte[] firstToken() throws IOException;
-
-    public abstract byte[] nextToken(byte[] in) throws IOException;
-
-    private static void finest(Exception e) {
-        PlatformLogger logger = HttpURLConnection.getHttpLogger();
-        logger.finest("NegotiateAuthentication: " + e);
-    }
-}
-
diff --git a/ojluni/src/main/native/DatagramPacket.c b/ojluni/src/main/native/DatagramPacket.c
deleted file mode 100644
index fac60ed..0000000
--- a/ojluni/src/main/native/DatagramPacket.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 1997, 2002, 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.
- */
-
-#include "net_util.h"
-#include "JNIHelp.h"
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-
-/************************************************************************
- * DatagramPacket
- */
-
-jfieldID dp_addressID;
-jfieldID dp_portID;
-jfieldID dp_bufID;
-jfieldID dp_offsetID;
-jfieldID dp_lengthID;
-jfieldID dp_bufLengthID;
-
-/*
- * Class:     java_net_DatagramPacket
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-DatagramPacket_init (JNIEnv *env, jclass cls) {
-    dp_addressID = (*env)->GetFieldID(env, cls, "address",
-                                      "Ljava/net/InetAddress;");
-    CHECK_NULL(dp_addressID);
-    dp_portID = (*env)->GetFieldID(env, cls, "port", "I");
-    CHECK_NULL(dp_portID);
-    dp_bufID = (*env)->GetFieldID(env, cls, "buf", "[B");
-    CHECK_NULL(dp_bufID);
-    dp_offsetID = (*env)->GetFieldID(env, cls, "offset", "I");
-    CHECK_NULL(dp_offsetID);
-    dp_lengthID = (*env)->GetFieldID(env, cls, "length", "I");
-    CHECK_NULL(dp_lengthID);
-    dp_bufLengthID = (*env)->GetFieldID(env, cls, "bufLength", "I");
-    CHECK_NULL(dp_bufLengthID);
-}
-
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(DatagramPacket, init, "()V"),
-};
-
-void register_java_net_DatagramPacket(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/net/DatagramPacket", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/PlainDatagramSocketImpl.c b/ojluni/src/main/native/PlainDatagramSocketImpl.c
deleted file mode 100644
index b36e286..0000000
--- a/ojluni/src/main/native/PlainDatagramSocketImpl.c
+++ /dev/null
@@ -1,1965 +0,0 @@
-/*
- * Copyright (c) 1997, 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.
- */
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-
-#ifdef __solaris__
-#include <fcntl.h>
-#endif
-#ifdef __linux__
-#include <unistd.h>
-//#include <sys/sysctl.h>
-#include <sys/utsname.h>
-#include <netinet/ip.h>
-
-#define IPV6_MULTICAST_IF 17
-#ifndef SO_BSDCOMPAT
-#define SO_BSDCOMPAT  14
-#endif
-/**
- * IP_MULTICAST_ALL has been supported since kernel version 2.6.31
- * but we may be building on a machine that is older than that.
- */
-#ifndef IP_MULTICAST_ALL
-#define IP_MULTICAST_ALL      49
-#endif
-#endif  //  __linux__
-
-#ifndef IPTOS_TOS_MASK
-#define IPTOS_TOS_MASK 0x1e
-#endif
-#ifndef IPTOS_PREC_MASK
-#define IPTOS_PREC_MASK 0xe0
-#endif
-
-#include "jvm.h"
-#include "jni_util.h"
-#include "net_util.h"
-
-#include "java_net_SocketOptions.h"
-#include "java_net_PlainDatagramSocketImpl.h"
-#include "JNIHelp.h"
-
-#define NATIVE_METHOD(className, functionName, signature) \
-{ #functionName, signature, (void*)(className ## _ ## functionName) }
-/************************************************************************
- * PlainDatagramSocketImpl
- */
-
-static jfieldID IO_fd_fdID;
-
-static jfieldID pdsi_fdID;
-static jfieldID pdsi_timeoutID;
-static jfieldID pdsi_trafficClassID;
-static jfieldID pdsi_localPortID;
-static jfieldID pdsi_connected;
-static jfieldID pdsi_connectedAddress;
-static jfieldID pdsi_connectedPort;
-
-extern void setDefaultScopeID(JNIEnv *env, struct sockaddr *him);
-extern int getDefaultScopeID(JNIEnv *env);
-
-/*
- * Returns a java.lang.Integer based on 'i'
- */
-static jobject createInteger(JNIEnv *env, int i) {
-    static jclass i_class;
-    static jmethodID i_ctrID;
-
-    if (i_class == NULL) {
-        jclass c = (*env)->FindClass(env, "java/lang/Integer");
-        CHECK_NULL_RETURN(c, NULL);
-        i_ctrID = (*env)->GetMethodID(env, c, "<init>", "(I)V");
-        CHECK_NULL_RETURN(i_ctrID, NULL);
-        i_class = (*env)->NewGlobalRef(env, c);
-        CHECK_NULL_RETURN(i_class, NULL);
-    }
-
-    return ( (*env)->NewObject(env, i_class, i_ctrID, i) );
-}
-
-/*
- * Returns a java.lang.Boolean based on 'b'
- */
-static jobject createBoolean(JNIEnv *env, int b) {
-    static jclass b_class;
-    static jmethodID b_ctrID;
-
-    if (b_class == NULL) {
-        jclass c = (*env)->FindClass(env, "java/lang/Boolean");
-        CHECK_NULL_RETURN(c, NULL);
-        b_ctrID = (*env)->GetMethodID(env, c, "<init>", "(Z)V");
-        CHECK_NULL_RETURN(b_ctrID, NULL);
-        b_class = (*env)->NewGlobalRef(env, c);
-        CHECK_NULL_RETURN(b_class, NULL);
-    }
-
-    return( (*env)->NewObject(env, b_class, b_ctrID, (jboolean)(b!=0)) );
-}
-
-
-/*
- * Returns the fd for a PlainDatagramSocketImpl or -1
- * if closed.
- */
-static int getFD(JNIEnv *env, jobject this) {
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    if (fdObj == NULL) {
-        return -1;
-    }
-    return (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-}
-
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    init
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_init(JNIEnv *env, jclass cls) {
-
-#ifdef __linux__
-    struct utsname sysinfo;
-#endif
-    pdsi_fdID = (*env)->GetFieldID(env, cls, "fd",
-                                   "Ljava/io/FileDescriptor;");
-    CHECK_NULL(pdsi_fdID);
-    pdsi_timeoutID = (*env)->GetFieldID(env, cls, "timeout", "I");
-    CHECK_NULL(pdsi_timeoutID);
-    pdsi_trafficClassID = (*env)->GetFieldID(env, cls, "trafficClass", "I");
-    CHECK_NULL(pdsi_trafficClassID);
-    pdsi_localPortID = (*env)->GetFieldID(env, cls, "localPort", "I");
-    CHECK_NULL(pdsi_localPortID);
-    pdsi_connected = (*env)->GetFieldID(env, cls, "connected", "Z");
-    CHECK_NULL(pdsi_connected);
-    pdsi_connectedAddress = (*env)->GetFieldID(env, cls, "connectedAddress",
-                                               "Ljava/net/InetAddress;");
-    CHECK_NULL(pdsi_connectedAddress);
-    pdsi_connectedPort = (*env)->GetFieldID(env, cls, "connectedPort", "I");
-    CHECK_NULL(pdsi_connectedPort);
-
-    IO_fd_fdID = NET_GetFileDescriptorID(env);
-    CHECK_NULL(IO_fd_fdID);
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    bind
- * Signature: (ILjava/net/InetAddress;)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_bind0(JNIEnv *env, jobject this,
-                                           jint localport, jobject iaObj) {
-    /* fdObj is the FileDescriptor field on this */
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    /* fd is an int field on fdObj */
-    int fd;
-    int len = 0;
-    SOCKADDR him;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-
-    if (IS_NULL(iaObj)) {
-        JNU_ThrowNullPointerException(env, "iaObj is null.");
-        return;
-    }
-
-    /* bind */
-    if (NET_InetAddressToSockaddr(env, iaObj, localport, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
-      return;
-    }
-    setDefaultScopeID(env, (struct sockaddr *)&him);
-
-    if (NET_Bind(fd, (struct sockaddr *)&him, len) < 0)  {
-        if (errno == EADDRINUSE || errno == EADDRNOTAVAIL ||
-            errno == EPERM || errno == EACCES) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "BindException",
-                            "Bind failed");
-        } else {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                            "Bind failed");
-        }
-        return;
-    }
-
-    /* initialize the local port */
-    if (localport == 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.
-         */
-        if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                            "Error getting socket name");
-            return;
-        }
-
-        localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
-
-        (*env)->SetIntField(env, this, pdsi_localPortID, localport);
-    } else {
-        (*env)->SetIntField(env, this, pdsi_localPortID, localport);
-    }
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    connect0
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_connect0(JNIEnv *env, jobject this,
-                                               jobject address, jint port) {
-    /* The object's field */
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    /* The fdObj'fd */
-    jint fd;
-    /* The packetAddress address, family and port */
-    SOCKADDR rmtaddr;
-    int len = 0;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    }
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-
-    if (IS_NULL(address)) {
-        JNU_ThrowNullPointerException(env, "address");
-        return;
-    }
-
-    if (NET_InetAddressToSockaddr(env, address, port, (struct sockaddr *)&rmtaddr, &len, JNI_TRUE) != 0) {
-      return;
-    }
-
-    setDefaultScopeID(env, (struct sockaddr *)&rmtaddr);
-    if (JVM_Connect(fd, (struct sockaddr *)&rmtaddr, len) == -1) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
-                        "Connect failed");
-        return;
-    }
-
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    disconnect0
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_disconnect0(JNIEnv *env, jobject this, jint family) {
-    /* The object's field */
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    /* The fdObj'fd */
-    jint fd;
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-    SOCKADDR addr;
-    int len;
-#endif
-
-    if (IS_NULL(fdObj)) {
-        return;
-    }
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-        memset(&addr, 0, sizeof(addr));
-#ifdef AF_INET6
-        if (ipv6_available()) {
-            struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&addr;
-            him6->sin6_family = AF_UNSPEC;
-            len = sizeof(struct sockaddr_in6);
-        } else
-#endif
-        {
-            struct sockaddr_in *him4 = (struct sockaddr_in*)&addr;
-            him4->sin_family = AF_UNSPEC;
-            len = sizeof(struct sockaddr_in);
-        }
-        JVM_Connect(fd, (struct sockaddr *)&addr, len);
-
-#ifdef __linux__
-        int localPort = 0;
-        if (JVM_GetSockName(fd, (struct sockaddr *)&addr, &len) == -1)
-            return;
-        localPort = NET_GetPortFromSockaddr((struct sockaddr *)&addr);
-        if (localPort == 0) {
-            localPort = (*env)->GetIntField(env, this, pdsi_localPortID);
-#ifdef AF_INET6
-            if (((struct sockaddr*)&addr)->sa_family == AF_INET6) {
-                ((struct sockaddr_in6*)&addr)->sin6_port = htons(localPort);
-            } else
-#endif /* AF_INET6 */
-            {
-                ((struct sockaddr_in*)&addr)->sin_port = htons(localPort);
-            }
-            NET_Bind(fd, (struct sockaddr *)&addr, len);
-        }
-#endif
-#else
-    JVM_Connect(fd, 0, 0);
-#endif
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    send
- * Signature: (Ljava/net/DatagramPacket;)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_send(JNIEnv *env, jobject this,
-                                           jobject packet) {
-
-    char BUF[MAX_BUFFER_LEN];
-    char *fullPacket = NULL;
-    int ret, mallocedPacket = JNI_FALSE;
-    /* The object's field */
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    jint trafficClass = (*env)->GetIntField(env, this, pdsi_trafficClassID);
-
-    jbyteArray packetBuffer;
-    jobject packetAddress;
-    jint packetBufferOffset, packetBufferLen, packetPort;
-    jboolean connected;
-
-    /* The fdObj'fd */
-    jint fd;
-
-    SOCKADDR rmtaddr, *rmtaddrP=&rmtaddr;
-    int len;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    }
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-
-    if (IS_NULL(packet)) {
-        JNU_ThrowNullPointerException(env, "packet");
-        return;
-    }
-
-    connected = (*env)->GetBooleanField(env, this, pdsi_connected);
-
-    packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
-    packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
-    if (IS_NULL(packetBuffer) || IS_NULL(packetAddress)) {
-        JNU_ThrowNullPointerException(env, "null buffer || null address");
-        return;
-    }
-
-    packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
-    packetBufferLen = (*env)->GetIntField(env, packet, dp_lengthID);
-
-    if (connected) {
-        /* arg to NET_Sendto () null in this case */
-        len = 0;
-        rmtaddrP = 0;
-    } else {
-        packetPort = (*env)->GetIntField(env, packet, dp_portID);
-        if (NET_InetAddressToSockaddr(env, packetAddress, packetPort, (struct sockaddr *)&rmtaddr, &len, JNI_TRUE) != 0) {
-          return;
-        }
-    }
-    setDefaultScopeID(env, (struct sockaddr *)&rmtaddr);
-
-    if (packetBufferLen > MAX_BUFFER_LEN) {
-        /* When JNI-ifying the JDK's IO routines, we turned
-         * reads and writes of byte arrays of size greater
-         * than 2048 bytes into several operations of size 2048.
-         * This saves a malloc()/memcpy()/free() for big
-         * buffers.  This is OK for file IO and TCP, but that
-         * strategy violates the semantics of a datagram protocol.
-         * (one big send) != (several smaller sends).  So here
-         * we *must* allocate the buffer.  Note it needn't be bigger
-         * than 65,536 (0xFFFF), the max size of an IP packet.
-         * Anything bigger should be truncated anyway.
-         *
-         * We may want to use a smarter allocation scheme at some
-         * point.
-         */
-        if (packetBufferLen > MAX_PACKET_LEN) {
-            packetBufferLen = MAX_PACKET_LEN;
-        }
-        fullPacket = (char *)malloc(packetBufferLen);
-
-        if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "Send buffer native heap allocation failed");
-            return;
-        } else {
-            mallocedPacket = JNI_TRUE;
-        }
-    } else {
-        fullPacket = &(BUF[0]);
-    }
-
-    (*env)->GetByteArrayRegion(env, packetBuffer, packetBufferOffset, packetBufferLen,
-                               (jbyte *)fullPacket);
-#ifdef AF_INET6
-    if (trafficClass != 0 && ipv6_available()) {
-        NET_SetTrafficClass((struct sockaddr *)&rmtaddr, trafficClass);
-    }
-#endif /* AF_INET6 */
-
-
-    /*
-     * Send the datagram.
-     *
-     * If we are connected it's possible that sendto will return
-     * ECONNREFUSED indicating that an ICMP port unreachable has
-     * received.
-     */
-    ret = NET_SendTo(fd, fullPacket, packetBufferLen, 0,
-                     (struct sockaddr *)rmtaddrP, len);
-
-    if (ret < 0) {
-        switch (ret) {
-            case JVM_IO_ERR :
-                if (errno == ECONNREFUSED) {
-                    JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
-                            "ICMP Port Unreachable");
-                } else {
-                    NET_ThrowByNameWithLastError(env, "java/io/IOException", "sendto failed");
-                }
-                break;
-
-            case JVM_IO_INTR:
-                JNU_ThrowByName(env, "java/io/InterruptedIOException",
-                                "operation interrupted");
-                break;
-        }
-    }
-
-    if (mallocedPacket) {
-        free(fullPacket);
-    }
-    return;
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    peek
- * Signature: (Ljava/net/InetAddress;)I
- */
-JNIEXPORT jint JNICALL
-PlainDatagramSocketImpl_peek(JNIEnv *env, jobject this,
-                                           jobject addressObj) {
-
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
-    jint fd;
-    ssize_t n;
-    SOCKADDR remote_addr;
-    int len;
-    char buf[1];
-    jint family;
-    jobject iaObj;
-    int port;
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-        return -1;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    if (IS_NULL(addressObj)) {
-        JNU_ThrowNullPointerException(env, "Null address in peek()");
-        return -1;
-    }
-    if (timeout) {
-        int ret = NET_Timeout(fd, timeout);
-        if (ret == 0) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                            "Peek timed out");
-            return ret;
-        } else if (ret == JVM_IO_ERR) {
-            if (errno == EBADF) {
-                 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-            } else {
-                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Peek failed");
-            }
-            return ret;
-        } else if (ret == JVM_IO_INTR) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-            return ret; /* WARNING: SHOULD WE REALLY RETURN -2??? */
-        }
-    }
-
-    len = SOCKADDR_LEN;
-    n = NET_RecvFrom(fd, buf, 1, MSG_PEEK,
-                     (struct sockaddr *)&remote_addr, &len);
-
-    if (n == JVM_IO_ERR) {
-
-#ifdef __solaris__
-        if (errno == ECONNREFUSED) {
-            int orig_errno = errno;
-            (void) recv(fd, buf, 1, 0);
-            errno = orig_errno;
-        }
-#endif
-        if (errno == ECONNREFUSED) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
-                            "ICMP Port Unreachable");
-        } else {
-            if (errno == EBADF) {
-                 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-            } else {
-                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Peek failed");
-            }
-        }
-        return 0;
-    } else if (n == JVM_IO_INTR) {
-        JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
-        return 0;
-    }
-
-    iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
-#ifdef AF_INET6
-    family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
-#else
-    family = AF_INET;
-#endif
-    if (family == AF_INET) { /* this API can't handle IPV6 addresses */
-        int address = getInetAddress_addr(env, iaObj);
-        setInetAddress_addr(env, addressObj, address);
-    }
-    return port;
-}
-
-JNIEXPORT jint JNICALL
-PlainDatagramSocketImpl_peekData(JNIEnv *env, jobject this,
-                                           jobject packet) {
-
-    char BUF[MAX_BUFFER_LEN];
-    char *fullPacket = NULL;
-    int mallocedPacket = JNI_FALSE;
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
-
-    jbyteArray packetBuffer;
-    jint packetBufferOffset, packetBufferLen;
-
-    int fd;
-
-    int n;
-    SOCKADDR remote_addr;
-    int len;
-    int port;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return -1;
-    }
-
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-
-    if (IS_NULL(packet)) {
-        JNU_ThrowNullPointerException(env, "packet");
-        return -1;
-    }
-
-    packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
-    if (IS_NULL(packetBuffer)) {
-        JNU_ThrowNullPointerException(env, "packet buffer");
-        return -1;
-    }
-    packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
-    packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID);
-    if (timeout) {
-        int ret = NET_Timeout(fd, timeout);
-        if (ret == 0) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                            "Receive timed out");
-            return -1;
-        } else if (ret == JVM_IO_ERR) {
-#ifdef __linux__
-            if (errno == EBADF) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-            } else {
-                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
-            }
-#else
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-#endif
-            return -1;
-        } else if (ret == JVM_IO_INTR) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-            return -1;
-        }
-    }
-
-    if (packetBufferLen > MAX_BUFFER_LEN) {
-
-        /* When JNI-ifying the JDK's IO routines, we turned
-         * reads and writes of byte arrays of size greater
-         * than 2048 bytes into several operations of size 2048.
-         * This saves a malloc()/memcpy()/free() for big
-         * buffers.  This is OK for file IO and TCP, but that
-         * strategy violates the semantics of a datagram protocol.
-         * (one big send) != (several smaller sends).  So here
-         * we *must* allocate the buffer.  Note it needn't be bigger
-         * than 65,536 (0xFFFF), the max size of an IP packet.
-         * anything bigger is truncated anyway.
-         *
-         * We may want to use a smarter allocation scheme at some
-         * point.
-         */
-        if (packetBufferLen > MAX_PACKET_LEN) {
-            packetBufferLen = MAX_PACKET_LEN;
-        }
-        fullPacket = (char *)malloc(packetBufferLen);
-
-        if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "Peek buffer native heap allocation failed");
-            return -1;
-        } else {
-            mallocedPacket = JNI_TRUE;
-        }
-    } else {
-        fullPacket = &(BUF[0]);
-    }
-
-    len = SOCKADDR_LEN;
-    n = NET_RecvFrom(fd, fullPacket, packetBufferLen, MSG_PEEK,
-                     (struct sockaddr *)&remote_addr, &len);
-    /* truncate the data if the packet's length is too small */
-    if (n > packetBufferLen) {
-        n = packetBufferLen;
-    }
-    if (n == JVM_IO_ERR) {
-
-#ifdef __solaris__
-        if (errno == ECONNREFUSED) {
-            int orig_errno = errno;
-            (void) recv(fd, fullPacket, 1, 0);
-            errno = orig_errno;
-        }
-#endif
-        (*env)->SetIntField(env, packet, dp_offsetID, 0);
-        (*env)->SetIntField(env, packet, dp_lengthID, 0);
-        if (errno == ECONNREFUSED) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
-                            "ICMP Port Unreachable");
-        } else {
-            if (errno == EBADF) {
-                 JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-            } else {
-                 NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
-            }
-        }
-    } else if (n == JVM_IO_INTR) {
-        (*env)->SetIntField(env, packet, dp_offsetID, 0);
-        (*env)->SetIntField(env, packet, dp_lengthID, 0);
-        JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                        "operation interrupted");
-    } else {
-        /*
-         * success - fill in received address...
-         *
-         * REMIND: Fill in an int on the packet, and create inetadd
-         * object in Java, as a performance improvement. Also
-         * construct the inetadd object lazily.
-         */
-
-        jobject packetAddress;
-
-        /*
-         * Check if there is an InetAddress already associated with this
-         * packet. If so we check if it is the same source address. We
-         * can't update any existing InetAddress because it is immutable
-         */
-        packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
-        if (packetAddress != NULL) {
-            if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, packetAddress)) {
-                /* force a new InetAddress to be created */
-                packetAddress = NULL;
-            }
-        }
-        if (packetAddress == NULL) {
-            packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
-            /* stuff the new Inetaddress in the packet */
-            (*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
-        } else {
-            /* only get the new port number */
-            port = NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr);
-        }
-        /* and fill in the data, remote address/port and such */
-        (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
-                                   (jbyte *)fullPacket);
-        (*env)->SetIntField(env, packet, dp_portID, port);
-        (*env)->SetIntField(env, packet, dp_lengthID, n);
-    }
-
-    if (mallocedPacket) {
-        free(fullPacket);
-    }
-    return port;
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    receive
- * Signature: (Ljava/net/DatagramPacket;)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_receive0(JNIEnv *env, jobject this,
-                                              jobject packet) {
-
-    char BUF[MAX_BUFFER_LEN];
-    char *fullPacket = NULL;
-    int mallocedPacket = JNI_FALSE;
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    jint timeout = (*env)->GetIntField(env, this, pdsi_timeoutID);
-
-    jbyteArray packetBuffer;
-    jint packetBufferOffset, packetBufferLen;
-
-    int fd;
-
-    int n;
-    SOCKADDR remote_addr;
-    int len;
-    jboolean retry;
-#ifdef __linux__
-    jboolean connected = JNI_FALSE;
-    jobject connectedAddress = NULL;
-    jint connectedPort = 0;
-    jlong prevTime = 0;
-#endif
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    }
-
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-
-    if (IS_NULL(packet)) {
-        JNU_ThrowNullPointerException(env, "packet");
-        return;
-    }
-
-    packetBuffer = (*env)->GetObjectField(env, packet, dp_bufID);
-    if (IS_NULL(packetBuffer)) {
-        JNU_ThrowNullPointerException(env, "packet buffer");
-        return;
-    }
-    packetBufferOffset = (*env)->GetIntField(env, packet, dp_offsetID);
-    packetBufferLen = (*env)->GetIntField(env, packet, dp_bufLengthID);
-
-    if (packetBufferLen > MAX_BUFFER_LEN) {
-
-        /* When JNI-ifying the JDK's IO routines, we turned
-         * reads and writes of byte arrays of size greater
-         * than 2048 bytes into several operations of size 2048.
-         * This saves a malloc()/memcpy()/free() for big
-         * buffers.  This is OK for file IO and TCP, but that
-         * strategy violates the semantics of a datagram protocol.
-         * (one big send) != (several smaller sends).  So here
-         * we *must* allocate the buffer.  Note it needn't be bigger
-         * than 65,536 (0xFFFF), the max size of an IP packet.
-         * anything bigger is truncated anyway.
-         *
-         * We may want to use a smarter allocation scheme at some
-         * point.
-         */
-        if (packetBufferLen > MAX_PACKET_LEN) {
-            packetBufferLen = MAX_PACKET_LEN;
-        }
-        fullPacket = (char *)malloc(packetBufferLen);
-
-        if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "Receive buffer native heap allocation failed");
-            return;
-        } else {
-            mallocedPacket = JNI_TRUE;
-        }
-    } else {
-        fullPacket = &(BUF[0]);
-    }
-
-
-    do {
-        retry = JNI_FALSE;
-
-        if (timeout) {
-            int ret = NET_Timeout(fd, timeout);
-            if (ret <= 0) {
-                if (ret == 0) {
-                    JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                                    "Receive timed out");
-                } else if (ret == JVM_IO_ERR) {
-#ifdef __linux__
-                    if (errno == EBADF) {
-                         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-                     } else {
-                         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
-                     }
-#else
-                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-#endif
-                } else if (ret == JVM_IO_INTR) {
-                    JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                                    "operation interrupted");
-                }
-
-                if (mallocedPacket) {
-                    free(fullPacket);
-                }
-
-                return;
-            }
-        }
-
-        len = SOCKADDR_LEN;
-        n = NET_RecvFrom(fd, fullPacket, packetBufferLen, 0,
-                         (struct sockaddr *)&remote_addr, &len);
-        /* truncate the data if the packet's length is too small */
-        if (n > packetBufferLen) {
-            n = packetBufferLen;
-        }
-        if (n == JVM_IO_ERR) {
-            (*env)->SetIntField(env, packet, dp_offsetID, 0);
-            (*env)->SetIntField(env, packet, dp_lengthID, 0);
-            if (errno == ECONNREFUSED) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "PortUnreachableException",
-                                "ICMP Port Unreachable");
-            } else {
-                if (errno == EBADF) {
-                     JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-                 } else {
-                     NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Receive failed");
-                 }
-            }
-        } else if (n == JVM_IO_INTR) {
-            (*env)->SetIntField(env, packet, dp_offsetID, 0);
-            (*env)->SetIntField(env, packet, dp_lengthID, 0);
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-        } else {
-            int port;
-            jobject packetAddress;
-
-            /*
-             * success - fill in received address...
-             *
-             * REMIND: Fill in an int on the packet, and create inetadd
-             * object in Java, as a performance improvement. Also
-             * construct the inetadd object lazily.
-             */
-
-            /*
-             * Check if there is an InetAddress already associated with this
-             * packet. If so we check if it is the same source address. We
-             * can't update any existing InetAddress because it is immutable
-             */
-            packetAddress = (*env)->GetObjectField(env, packet, dp_addressID);
-            if (packetAddress != NULL) {
-                if (!NET_SockaddrEqualsInetAddress(env, (struct sockaddr *)&remote_addr, packetAddress)) {
-                    /* force a new InetAddress to be created */
-                    packetAddress = NULL;
-                }
-            }
-            if (packetAddress == NULL) {
-                packetAddress = NET_SockaddrToInetAddress(env, (struct sockaddr *)&remote_addr, &port);
-                /* stuff the new Inetaddress in the packet */
-                (*env)->SetObjectField(env, packet, dp_addressID, packetAddress);
-            } else {
-                /* only get the new port number */
-                port = NET_GetPortFromSockaddr((struct sockaddr *)&remote_addr);
-            }
-            /* and fill in the data, remote address/port and such */
-            (*env)->SetByteArrayRegion(env, packetBuffer, packetBufferOffset, n,
-                                       (jbyte *)fullPacket);
-            (*env)->SetIntField(env, packet, dp_portID, port);
-            (*env)->SetIntField(env, packet, dp_lengthID, n);
-        }
-
-    } while (retry);
-
-    if (mallocedPacket) {
-        free(fullPacket);
-    }
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    datagramSocketCreate
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_datagramSocketCreate(JNIEnv *env,
-                                                           jobject this) {
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    int arg, fd, t = 1;
-#ifdef AF_INET6
-    int domain = ipv6_available() ? AF_INET6 : AF_INET;
-#else
-    int domain = AF_INET;
-#endif
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    }
-
-    if ((fd = JVM_Socket(domain, SOCK_DGRAM, 0)) == JVM_IO_ERR) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                       "Error creating socket");
-        return;
-    }
-    tagSocket(env, fd);
-
-#ifdef AF_INET6
-    /* Disable IPV6_V6ONLY to ensure dual-socket support */
-    if (domain == AF_INET6) {
-        arg = 0;
-        if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&arg,
-                       sizeof(int)) < 0) {
-            NET_ThrowNew(env, errno, "cannot set IPPROTO_IPV6");
-            untagSocket(env, fd);
-            close(fd);
-            return;
-        }
-    }
-#endif /* AF_INET6 */
-
-#ifdef __APPLE__
-    arg = 65507;
-    if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_SNDBUF,
-                       (char *)&arg, sizeof(arg)) < 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        strerror(errno));
-        return;
-    }
-    if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_RCVBUF,
-                       (char *)&arg, sizeof(arg)) < 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        strerror(errno));
-        return;
-    }
-#endif /* __APPLE__ */
-
-     setsockopt(fd, SOL_SOCKET, SO_BROADCAST, (char*) &t, sizeof(int));
-
-#if defined(__linux__)
-     arg = 0;
-     int level = (domain == AF_INET6) ? IPPROTO_IPV6 : IPPROTO_IP;
-     if ((setsockopt(fd, level, IP_MULTICAST_ALL, (char*)&arg, sizeof(arg)) < 0) &&
-         (errno != ENOPROTOOPT)) {
-         JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                         strerror(errno));
-         close(fd);
-         return;
-     }
-#endif
-
-#if defined (__linux__) && defined (AF_INET6)
-    /*
-     * On Linux for IPv6 sockets we must set the hop limit
-     * to 1 to be compatible with default TTL of 1 for IPv4 sockets.
-     */
-    if (domain == AF_INET6) {
-        int ttl = 1;
-        setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (char *)&ttl,
-                   sizeof(ttl));
-    }
-#endif /* __linux__ */
-
-    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    datagramSocketClose
- * Signature: ()V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_datagramSocketClose(JNIEnv *env,
-                                                          jobject this) {
-    /*
-     * REMIND: PUT A LOCK AROUND THIS CODE
-     */
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    int fd;
-
-    if (IS_NULL(fdObj)) {
-        return;
-    }
-    fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    if (fd == -1) {
-        return;
-    }
-    (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
-    untagSocket(env, fd);
-    NET_SocketClose(fd);
-}
-
-
-/*
- * Set outgoing multicast interface designated by a NetworkInterface index.
- * Throw exception if failed.
- *
- * Android changed: return 0 on success, negative on failure.
- * Android changed: Interface index (not NetworkInterface) as the parameter
- */
-static int mcast_set_if_by_if_v4(JNIEnv *env, jobject this, int fd, jint ifindex) {
-    struct ip_mreqn req;
-    memset(&req, 0, sizeof(req));
-    req.imr_ifindex = ifindex;
-
-    if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
-                       (const char*)&req, sizeof(req)) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                       "Error setting socket option");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Set outgoing multicast interface designated by a NetworkInterface.
- * Throw exception if failed.
- * Android changed: Interface index (not NetworkInterface) as the parameter
- */
-static void mcast_set_if_by_if_v6(JNIEnv *env, jobject this, int fd, jint ifindex) {
-    if (JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-                       (const char*)&ifindex, sizeof(ifindex)) < 0) {
-        if (errno == EINVAL && ifindex > 0) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                "IPV6_MULTICAST_IF failed (interface has IPv4 "
-                "address only?)");
-        } else {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                           "Error setting socket option");
-        }
-        return;
-    }
-}
-
-/*
- * Set outgoing multicast interface designated by an InetAddress.
- * Throw exception if failed.
- *
- * Android-changed : Return type, return 0 on success, negative on failure.
- */
-static int mcast_set_if_by_addr_v4(JNIEnv *env, jobject this, int fd, jobject value) {
-    struct in_addr in;
-
-    in.s_addr = htonl( getInetAddress_addr(env, value) );
-
-    if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_IF,
-                       (const char*)&in, sizeof(in)) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                         "Error setting socket option");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*
- * Set outgoing multicast interface designated by an InetAddress.
- * Throw exception if failed.
- */
-static void mcast_set_if_by_addr_v6(JNIEnv *env, jobject this, int fd, jobject value) {
-    static jclass ni_class;
-    static jmethodID ni_getByInetAddress;
-    static jmethodID ni_getIndex;
-    if (ni_class == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-        CHECK_NULL(c);
-        ni_class = (*env)->NewGlobalRef(env, c);
-        CHECK_NULL(ni_class);
-        ni_getByInetAddress = (*env)->GetStaticMethodID(
-            env, ni_class, "getByInetAddress", "(Ljava/net/InetAddress;)Ljava/net/NetworkInterface;");
-        CHECK_NULL(ni_getByInetAddress);
-        ni_getIndex = (*env)->GetMethodID(
-            env, ni_class, "getIndex", "()I");
-        CHECK_NULL(ni_getIndex);
-    }
-
-    /*
-     * Get the NetworkInterface by inetAddress
-     */
-    jobject ni_value = (*env)->CallStaticObjectMethod(
-        env, ni_class, ni_getByInetAddress, value);
-    if (ni_value == NULL) {
-        if (!(*env)->ExceptionOccurred(env)) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                 "bad argument for IP_MULTICAST_IF"
-                 ": address not bound to any interface");
-        }
-        return;
-    }
-
-    /*
-     * Get the NetworkInterface index
-     */
-    jint ifindex = (*env)->CallIntMethod(env, ni_value, ni_getIndex);
-    if ((*env)->ExceptionOccurred(env)) {
-        return;
-    }
-
-    mcast_set_if_by_if_v6(env, this, fd, ifindex);
-}
-
-/*
- * Sets the multicast interface.
- *
- * SocketOptions.IP_MULTICAST_IF :-
- *      value is a InetAddress
- *      IPv4:   set outgoing multicast interface using
- *              IPPROTO_IP/IP_MULTICAST_IF
- *      IPv6:   Get the index of the interface to which the
- *              InetAddress is bound
- *              Set outgoing multicast interface using
- *              IPPROTO_IPV6/IPV6_MULTICAST_IF
- *
- * SockOptions.IF_MULTICAST_IF2 :-
- *      value is a NetworkInterface
- *      IPv4:   Obtain IP address bound to network interface
- *              (NetworkInterface.addres[0])
- *              set outgoing multicast interface using
- *              IPPROTO_IP/IP_MULTICAST_IF
- *      IPv6:   Obtain NetworkInterface.index
- *              Set outgoing multicast interface using
- *              IPPROTO_IPV6/IPV6_MULTICAST_IF
- *
- */
-static void setMulticastInterface(JNIEnv *env, jobject this, int fd,
-                                  jint opt, jobject value)
-{
-    if (opt == java_net_SocketOptions_IP_MULTICAST_IF) {
-        /*
-         * value is an InetAddress.
-         */
-        // Android-changed: Return early if mcast_set_if_by_addr_v4 threw.
-        // We don't want to call into the IPV6 code with a pending exception.
-        if (mcast_set_if_by_addr_v4(env, this, fd, value)) {
-            return;
-        }
-        if (ipv6_available()) {
-            mcast_set_if_by_addr_v6(env, this, fd, value);
-        }
-    }
-
-    if (opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
-      /*
-         * value is a Integer (Android-changed, openJdk uses NetworkInterface)
-         */
-        static jfieldID integer_valueID;
-        if (integer_valueID == NULL) {
-            jclass c = (*env)->FindClass(env, "java/lang/Integer");
-            CHECK_NULL(c);
-            integer_valueID = (*env)->GetFieldID(env, c, "value", "I");
-            CHECK_NULL(integer_valueID);
-        }
-        int index = (*env)->GetIntField(env, value, integer_valueID);
-
-        // Android-changed: Return early if mcast_set_if_by_addr_v4 threw.
-        // We don't want to call into the IPV6 code with a pending exception.
-        if (mcast_set_if_by_if_v4(env, this, fd, index)) {
-            return;
-        }
-        if (ipv6_available()) {
-            mcast_set_if_by_if_v6(env, this, fd, index);
-        }
-    }
-}
-
-/*
- * Enable/disable local loopback of multicast datagrams.
- */
-static void mcast_set_loop_v4(JNIEnv *env, jobject this, int fd, jobject value) {
-    jclass cls;
-    jfieldID fid;
-    jboolean on;
-    char loopback;
-
-    cls = (*env)->FindClass(env, "java/lang/Boolean");
-    CHECK_NULL(cls);
-    fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-    CHECK_NULL(fid);
-
-    on = (*env)->GetBooleanField(env, value, fid);
-    loopback = (!on ? 1 : 0);
-
-    if (NET_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, (const void *)&loopback, sizeof(char)) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
-        return;
-    }
-}
-
-/*
- * Enable/disable local loopback of multicast datagrams.
- */
-#ifdef AF_INET6
-static void mcast_set_loop_v6(JNIEnv *env, jobject this, int fd, jobject value) {
-    jclass cls;
-    jfieldID fid;
-    jboolean on;
-    int loopback;
-
-    cls = (*env)->FindClass(env, "java/lang/Boolean");
-    CHECK_NULL(cls);
-    fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-    CHECK_NULL(fid);
-
-    on = (*env)->GetBooleanField(env, value, fid);
-    loopback = (!on ? 1 : 0);
-
-    if (NET_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, (const void *)&loopback, sizeof(int)) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
-        return;
-    }
-
-}
-#endif  /* AF_INET6 */
-
-/*
- * Sets the multicast loopback mode.
- */
-static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
-                                  jint opt, jobject value) {
-#ifdef AF_INET6
-#ifdef __linux__
-    mcast_set_loop_v4(env, this, fd, value);
-    if (ipv6_available()) {
-        mcast_set_loop_v6(env, this, fd, value);
-    }
-#else  /* __linux__ not defined */
-    if (ipv6_available()) {
-        mcast_set_loop_v6(env, this, fd, value);
-    } else {
-        mcast_set_loop_v4(env, this, fd, value);
-    }
-#endif  /* __linux__ */
-#else
-    mcast_set_loop_v4(env, this, fd, value);
-#endif  /* AF_INET6 */
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    socketSetOption0
- * Signature: (ILjava/lang/Object;)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_socketSetOption0(JNIEnv *env,
-                                                      jobject this,
-                                                      jint opt,
-                                                      jobject value) {
-    int fd;
-    int level, optname, optlen;
-    union {
-        int i;
-        char c;
-    } optval;
-
-    /*
-     * Check that socket hasn't been closed
-     */
-    fd = getFD(env, this);
-    if (fd < 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    }
-
-    /*
-     * Check argument has been provided
-     */
-    if (IS_NULL(value)) {
-        JNU_ThrowNullPointerException(env, "value argument");
-        return;
-    }
-
-    /*
-     * Setting the multicast interface handled seperately
-     */
-    if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
-        opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
-
-        setMulticastInterface(env, this, fd, opt, value);
-        return;
-    }
-
-    /*
-     * Setting the multicast loopback mode handled separately
-     */
-    if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP) {
-        setMulticastLoopbackMode(env, this, fd, opt, value);
-        return;
-    }
-
-    /*
-     * Map the Java level socket option to the platform specific
-     * level and option name.
-     */
-    if (NET_MapSocketOption(opt, &level, &optname)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
-        return;
-    }
-
-    switch (opt) {
-        case java_net_SocketOptions_SO_SNDBUF :
-        case java_net_SocketOptions_SO_RCVBUF :
-        case java_net_SocketOptions_IP_TOS :
-            {
-                jclass cls;
-                jfieldID fid;
-
-                cls = (*env)->FindClass(env, "java/lang/Integer");
-                CHECK_NULL(cls);
-                fid =  (*env)->GetFieldID(env, cls, "value", "I");
-                CHECK_NULL(fid);
-
-                optval.i = (*env)->GetIntField(env, value, fid);
-                optlen = sizeof(optval.i);
-                break;
-            }
-
-        case java_net_SocketOptions_SO_REUSEADDR:
-        case java_net_SocketOptions_SO_BROADCAST:
-            {
-                jclass cls;
-                jfieldID fid;
-                jboolean on;
-
-                cls = (*env)->FindClass(env, "java/lang/Boolean");
-                CHECK_NULL(cls);
-                fid =  (*env)->GetFieldID(env, cls, "value", "Z");
-                CHECK_NULL(fid);
-
-                on = (*env)->GetBooleanField(env, value, fid);
-
-                /* SO_REUSEADDR or SO_BROADCAST */
-                optval.i = (on ? 1 : 0);
-                optlen = sizeof(optval.i);
-
-                break;
-            }
-
-        default :
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                "Socket option not supported by PlainDatagramSocketImp");
-            return;
-
-    }
-
-    if (NET_SetSockOpt(fd, level, optname, (const void *)&optval, optlen) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Error setting socket option");
-        return;
-    }
-}
-
-
-/*
- * Return the multicast interface:
- *
- * SocketOptions.IP_MULTICAST_IF
- *      IPv4:   Query IPPROTO_IP/IP_MULTICAST_IF
- *              Create InetAddress
- *              IP_MULTICAST_IF returns struct ip_mreqn on 2.2
- *              kernel but struct in_addr on 2.4 kernel
- *      IPv6:   Query IPPROTO_IPV6 / IPV6_MULTICAST_IF
- *              If index == 0 return InetAddress representing
- *              anyLocalAddress.
- *              If index > 0 query NetworkInterface by index
- *              and returns addrs[0]
- *
- * SocketOptions.IP_MULTICAST_IF2
- *      IPv4:   Query IPPROTO_IP/IP_MULTICAST_IF
- *              Query NetworkInterface by IP address and
- *              return the NetworkInterface that the address
- *              is bound too.
- *      IPv6:   Query IPPROTO_IPV6 / IPV6_MULTICAST_IF
- *              (except Linux .2 kernel)
- *              Query NetworkInterface by index and
- *              return NetworkInterface.
- */
-jobject getMulticastInterface(JNIEnv *env, jobject this, int fd, jint opt) {
-    if ((opt == java_net_SocketOptions_IP_MULTICAST_IF2) ||
-        (opt == java_net_SocketOptions_IP_MULTICAST_IF)) {
-        int index;
-        int len = sizeof(index);
-
-        if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-                           (char*)&index, &len) < 0) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                           "Error getting socket option");
-            return NULL;
-        }
-
-        jobject ifindex = createInteger(env, index);
-        CHECK_NULL_RETURN(ifindex, NULL);
-        return ifindex;
-    }
-    return NULL;
-}
-
-
-
-/*
- * Returns relevant info as a jint.
- *
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    socketGetOption
- * Signature: (I)Ljava/lang/Object;
- */
-JNIEXPORT jobject JNICALL
-PlainDatagramSocketImpl_socketGetOption(JNIEnv *env, jobject this,
-                                                      jint opt) {
-    int fd;
-    int level, optname, optlen;
-    union {
-        int i;
-        char c;
-    } optval;
-
-    fd = getFD(env, this);
-    if (fd < 0) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket closed");
-        return NULL;
-    }
-
-    /*
-     * Handle IP_MULTICAST_IF separately
-     */
-    if (opt == java_net_SocketOptions_IP_MULTICAST_IF ||
-        opt == java_net_SocketOptions_IP_MULTICAST_IF2) {
-        return getMulticastInterface(env, this, fd, opt);
-
-    }
-
-    /*
-     * SO_BINDADDR implemented using getsockname
-     */
-    if (opt == java_net_SocketOptions_SO_BINDADDR) {
-        /* find out local IP address */
-        SOCKADDR him;
-        socklen_t len = 0;
-        int port;
-        jobject iaObj;
-
-        len = SOCKADDR_LEN;
-
-        if (getsockname(fd, (struct sockaddr *)&him, &len) == -1) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                           "Error getting socket name");
-            return NULL;
-        }
-        iaObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
-
-        return iaObj;
-    }
-
-    /*
-     * Map the Java level socket option to the platform specific
-     * level and option name.
-     */
-    if (NET_MapSocketOption(opt, &level, &optname)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Invalid option");
-        return NULL;
-    }
-
-    if (opt == java_net_SocketOptions_IP_MULTICAST_LOOP &&
-        level == IPPROTO_IP) {
-        optlen = sizeof(optval.c);
-    } else {
-        optlen = sizeof(optval.i);
-    }
-
-    if (NET_GetSockOpt(fd, level, optname, (void *)&optval, &optlen) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                         "Error getting socket option");
-        return NULL;
-    }
-
-    switch (opt) {
-        case java_net_SocketOptions_IP_MULTICAST_LOOP:
-            /* getLoopbackMode() returns true if IP_MULTICAST_LOOP disabled */
-            if (level == IPPROTO_IP) {
-                return createBoolean(env, (int)!optval.c);
-            } else {
-                return createBoolean(env, !optval.i);
-            }
-
-        case java_net_SocketOptions_SO_BROADCAST:
-        case java_net_SocketOptions_SO_REUSEADDR:
-            return createBoolean(env, optval.i);
-
-        case java_net_SocketOptions_SO_SNDBUF:
-        case java_net_SocketOptions_SO_RCVBUF:
-        case java_net_SocketOptions_IP_TOS:
-            return createInteger(env, optval.i);
-
-    }
-
-    /* should never reach here */
-    return NULL;
-}
-
-/*
- * Multicast-related calls
- */
-
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_setTTL(JNIEnv *env, jobject this,
-                                             jbyte ttl) {
-    jint ittl = ttl;
-    if (ittl < 0) {
-        ittl += 0x100;
-    }
-    PlainDatagramSocketImpl_setTimeToLive(env, this, ittl);
-}
-
-/*
- * Set TTL for a socket. Throw exception if failed.
- */
-static void setTTL(JNIEnv *env, int fd, jint ttl) {
-    char ittl = (char)ttl;
-    if (JVM_SetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL, (char*)&ittl,
-                       sizeof(ittl)) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                       "Error setting socket option");
-    }
-}
-
-/*
- * Set hops limit for a socket. Throw exception if failed.
- */
-#ifdef AF_INET6
-static void setHopLimit(JNIEnv *env, int fd, jint ttl) {
-    int ittl = (int)ttl;
-    if (JVM_SetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
-                       (char*)&ittl, sizeof(ittl)) < 0) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                       "Error setting socket option");
-    }
-}
-#endif
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    setTTL
- * Signature: (B)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_setTimeToLive(JNIEnv *env, jobject this,
-                                                    jint ttl) {
-
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    int fd;
-    /* it is important to cast this to a char, otherwise setsockopt gets confused */
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    /* setsockopt to be correct TTL */
-#ifdef AF_INET6
-#ifdef __linux__
-    setTTL(env, fd, ttl);
-    if ((*env)->ExceptionCheck(env)) {
-        return;
-    }
-    if (ipv6_available()) {
-        setHopLimit(env, fd, ttl);
-    }
-#else  /*  __linux__ not defined */
-    if (ipv6_available()) {
-        setHopLimit(env, fd, ttl);
-    } else {
-        setTTL(env, fd, ttl);
-    }
-#endif  /* __linux__ */
-#else
-    setTTL(env, fd, ttl);
-#endif  /* AF_INET6 */
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    getTTL
- * Signature: ()B
- */
-JNIEXPORT jbyte JNICALL
-PlainDatagramSocketImpl_getTTL(JNIEnv *env, jobject this) {
-    return (jbyte)PlainDatagramSocketImpl_getTimeToLive(env, this);
-}
-
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    getTTL
- * Signature: ()B
- */
-JNIEXPORT jint JNICALL
-PlainDatagramSocketImpl_getTimeToLive(JNIEnv *env, jobject this) {
-
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    jint fd = -1;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return -1;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    /* getsockopt of TTL */
-#ifdef AF_INET6
-    if (ipv6_available()) {
-        int ttl = 0;
-        int len = sizeof(ttl);
-
-        if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
-                               (char*)&ttl, &len) < 0) {
-                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                               "Error getting socket option");
-                return -1;
-            }
-        return (jint)ttl;
-    } else
-#endif /* AF_INET6 */
-        {
-            u_char ttl = 0;
-            int len = sizeof(ttl);
-            if (JVM_GetSockOpt(fd, IPPROTO_IP, IP_MULTICAST_TTL,
-                               (char*)&ttl, &len) < 0) {
-                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                               "Error getting socket option");
-                return -1;
-            }
-            return (jint)ttl;
-        }
-}
-
-
-/*
- * mcast_join_leave: Join or leave a multicast group.
- *
- * For IPv4 sockets use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP socket option
- * to join/leave multicast group.
- *
- * For IPv6 sockets use IPV6_ADD_MEMBERSHIP/IPV6_DROP_MEMBERSHIP socket option
- * to join/leave multicast group. If multicast group is an IPv4 address then
- * an IPv4-mapped address is used.
- *
- * On Linux with IPv6 if we wish to join/leave an IPv4 multicast group then
- * we must use the IPv4 socket options. This is because the IPv6 socket options
- * don't support IPv4-mapped addresses. This is true as per 2.2.19 and 2.4.7
- * kernel releases. In the future it's possible that IP_ADD_MEMBERSHIP
- * will be updated to return ENOPROTOOPT if uses with an IPv6 socket (Solaris
- * already does this). Thus to cater for this we first try with the IPv4
- * socket options and if they fail we use the IPv6 socket options. This
- * seems a reasonable failsafe solution.
- */
-static void mcast_join_leave(JNIEnv *env, jobject this,
-                             jobject iaObj, jobject niObj,
-                             jboolean join) {
-
-    jobject fdObj = (*env)->GetObjectField(env, this, pdsi_fdID);
-    jint fd;
-    jint ipv6_join_leave;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    if (IS_NULL(iaObj)) {
-        JNU_ThrowNullPointerException(env, "iaObj");
-        return;
-    }
-
-    /*
-     * Get java/net/NetworkInterface#index field.
-     */
-    static jfieldID ni_indexID;
-
-    if (ni_indexID == NULL) {
-      jclass c = (*env)->FindClass(env, "java/net/NetworkInterface");
-      CHECK_NULL(c);
-      ni_indexID = (*env)->GetFieldID(env, c, "index", "I");
-      CHECK_NULL(ni_indexID);
-    }
-
-    /*
-     * Determine if this is an IPv4 or IPv6 join/leave.
-     */
-    ipv6_join_leave = ipv6_available();
-
-    if (getInetAddress_family(env, iaObj) == IPv4) {
-        ipv6_join_leave = JNI_FALSE;
-    }
-
-    /*
-     * For IPv4 join use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP socket option
-     *
-     * On Linux if IPv4 or IPv6 use IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP
-     */
-    if (!ipv6_join_leave) {
-        struct ip_mreqn mname;
-        int mname_len;
-
-        /*
-         * joinGroup(InetAddress, NetworkInterface) implementation :-
-         *
-         * Linux/IPv6:  use ip_mreqn structure populated with multicast
-         *              address and interface index.
-         *
-         */
-        if (niObj != NULL) {
-            mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
-            mname.imr_address.s_addr = 0;
-            mname.imr_ifindex =  (*env)->GetIntField(env, niObj, ni_indexID);
-            mname_len = sizeof(struct ip_mreqn);
-        }
-
-
-        /*
-         * joinGroup(InetAddress) implementation :-
-         *
-         * Linux/IPv6:  use ip_mreqn structure populated with multicast
-         *              address and interface index. index obtained
-         *              from cached value or IPV6_MULTICAST_IF.
-         *
-         * IPv4:        use ip_mreq structure populated with multicast
-         *              address and local address obtained from
-         *              IP_MULTICAST_IF. On Linux IP_MULTICAST_IF
-         *              returns different structure depending on
-         *              kernel.
-         */
-
-        if (niObj == NULL) {
-            int index;
-            int len = sizeof(index);
-
-            if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-                               (char*)&index, &len) < 0) {
-                NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed");
-                return;
-            }
-
-            mname.imr_multiaddr.s_addr = htonl(getInetAddress_addr(env, iaObj));
-            mname.imr_address.s_addr = 0 ;
-            mname.imr_ifindex = index;
-            mname_len = sizeof(struct ip_mreqn);
-        }
-
-
-        /*
-         * Join the multicast group.
-         */
-        if (JVM_SetSockOpt(fd, IPPROTO_IP, (join ? IP_ADD_MEMBERSHIP:IP_DROP_MEMBERSHIP),
-                           (char *) &mname, mname_len) < 0) {
-
-            /*
-             * If IP_ADD_MEMBERSHIP returns ENOPROTOOPT on Linux and we've got
-             * IPv6 enabled then it's possible that the kernel has been fixed
-             * so we switch to IPV6_ADD_MEMBERSHIP socket option.
-             * As of 2.4.7 kernel IPV6_ADD_MEMBERSHIP can't handle IPv4-mapped
-             * addresses so we have to use IP_ADD_MEMBERSHIP for IPv4 multicast
-             * groups. However if the socket is an IPv6 socket then then setsockopt
-             * should return ENOPROTOOPT. We assume this will be fixed in Linux
-             * at some stage.
-             */
-            if (errno == ENOPROTOOPT) {
-                if (ipv6_available()) {
-                    ipv6_join_leave = JNI_TRUE;
-                    errno = 0;
-                } else  {
-                    errno = ENOPROTOOPT;    /* errno can be changed by ipv6_available */
-                }
-            }
-            if (errno) {
-                if (join) {
-                    NET_ThrowCurrent(env, "setsockopt IP_ADD_MEMBERSHIP failed");
-                } else {
-                    if (errno == ENOENT)
-                        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "Not a member of the multicast group");
-                    else
-                        NET_ThrowCurrent(env, "setsockopt IP_DROP_MEMBERSHIP failed");
-                }
-                return;
-            }
-        }
-
-        /*
-         * If we haven't switched to IPv6 socket option then we're done.
-         */
-        if (!ipv6_join_leave) {
-            return;
-        }
-    }
-
-
-    /*
-     * IPv6 join. If it's an IPv4 multicast group then we use an IPv4-mapped
-     * address.
-     */
-    {
-        struct ipv6_mreq mname6;
-
-        jbyteArray ipaddress;
-        jbyte caddr[16];
-        jint family;
-        jint address;
-        family = getInetAddress_family(env, iaObj) == IPv4? AF_INET : AF_INET6;
-        if (family == AF_INET) { /* will convert to IPv4-mapped address */
-            memset((char *) caddr, 0, 16);
-            address = getInetAddress_addr(env, iaObj);
-
-            caddr[10] = 0xff;
-            caddr[11] = 0xff;
-
-            caddr[12] = ((address >> 24) & 0xff);
-            caddr[13] = ((address >> 16) & 0xff);
-            caddr[14] = ((address >> 8) & 0xff);
-            caddr[15] = (address & 0xff);
-        } else {
-            // Android-changed: explicit cast to suppress compiler warning.
-            getInet6Address_ipaddress(env, iaObj, (char*)caddr);
-        }
-
-        memcpy((void *)&(mname6.ipv6mr_multiaddr), caddr, sizeof(struct in6_addr));
-        if (IS_NULL(niObj)) {
-            int index;
-            int len = sizeof(index);
-
-            if (JVM_GetSockOpt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF,
-                             (char*)&index, &len) < 0) {
-                NET_ThrowCurrent(env, "getsockopt IPV6_MULTICAST_IF failed");
-                return;
-            }
-
-            mname6.ipv6mr_interface = index;
-        } else {
-            jint idx = (*env)->GetIntField(env, niObj, ni_indexID);
-            mname6.ipv6mr_interface = idx;
-        }
-
-#define ADD_MEMBERSHIP          IPV6_ADD_MEMBERSHIP
-#define DRP_MEMBERSHIP          IPV6_DROP_MEMBERSHIP
-#define S_ADD_MEMBERSHIP        "IPV6_ADD_MEMBERSHIP"
-#define S_DRP_MEMBERSHIP        "IPV6_DROP_MEMBERSHIP"
-
-        /* Join the multicast group */
-        if (JVM_SetSockOpt(fd, IPPROTO_IPV6, (join ? ADD_MEMBERSHIP : DRP_MEMBERSHIP),
-                           (char *) &mname6, sizeof (mname6)) < 0) {
-
-            if (join) {
-                NET_ThrowCurrent(env, "setsockopt " S_ADD_MEMBERSHIP " failed");
-            } else {
-                if (errno == ENOENT) {
-                   JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Not a member of the multicast group");
-                } else {
-                    NET_ThrowCurrent(env, "setsockopt " S_DRP_MEMBERSHIP " failed");
-                }
-            }
-        }
-    }
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    join
- * Signature: (Ljava/net/InetAddress;)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_join(JNIEnv *env, jobject this,
-                                           jobject iaObj, jobject niObj)
-{
-    mcast_join_leave(env, this, iaObj, niObj, JNI_TRUE);
-}
-
-/*
- * Class:     java_net_PlainDatagramSocketImpl
- * Method:    leave
- * Signature: (Ljava/net/InetAddress;)V
- */
-JNIEXPORT void JNICALL
-PlainDatagramSocketImpl_leave(JNIEnv *env, jobject this,
-                                            jobject iaObj, jobject niObj)
-{
-    mcast_join_leave(env, this, iaObj, niObj, JNI_FALSE);
-}
-
-static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(PlainDatagramSocketImpl, leave, "(Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, join, "(Ljava/net/InetAddress;Ljava/net/NetworkInterface;)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, getTimeToLive, "()I"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, getTTL, "()B"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, setTimeToLive, "(I)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, setTTL, "(B)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, socketGetOption, "(I)Ljava/lang/Object;"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, socketSetOption0, "(ILjava/lang/Object;)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, datagramSocketClose, "()V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, datagramSocketCreate, "()V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, receive0, "(Ljava/net/DatagramPacket;)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, peekData, "(Ljava/net/DatagramPacket;)I"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, peek, "(Ljava/net/InetAddress;)I"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, send, "(Ljava/net/DatagramPacket;)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, disconnect0, "(I)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, connect0, "(Ljava/net/InetAddress;I)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, bind0, "(ILjava/net/InetAddress;)V"),
-  NATIVE_METHOD(PlainDatagramSocketImpl, init, "()V"),
-};
-
-void register_java_net_PlainDatagramSocketImpl(JNIEnv* env) {
-  jniRegisterNativeMethods(env, "java/net/PlainDatagramSocketImpl", gMethods, NELEM(gMethods));
-}
diff --git a/ojluni/src/main/native/Register.cpp b/ojluni/src/main/native/Register.cpp
index 8e767f7..42b1a62 100644
--- a/ojluni/src/main/native/Register.cpp
+++ b/ojluni/src/main/native/Register.cpp
@@ -127,8 +127,6 @@
     register_java_net_Inet4Address(env);
     register_java_net_Inet6Address(env);
     register_java_net_PlainSocketImpl(env);
-    register_java_net_PlainDatagramSocketImpl(env);
-    register_java_net_DatagramPacket(env);
     register_java_net_SocketInputStream(env);
     register_java_net_SocketOutputStream(env);
     register_java_nio_Bits(env);
diff --git a/ojluni/src/main/native/net_util.h b/ojluni/src/main/native/net_util.h
index 4b7310b..839e947 100644
--- a/ojluni/src/main/native/net_util.h
+++ b/ojluni/src/main/native/net_util.h
@@ -93,6 +93,8 @@
 extern jfieldID psi_portID;
 extern jfieldID psi_localportID;
 
+/* Android-removed: DatagramSocket moved away from JNI */
+#if 0
 /* DatagramPacket fields */
 extern jfieldID dp_addressID;
 extern jfieldID dp_portID;
@@ -100,6 +102,7 @@
 extern jfieldID dp_offsetID;
 extern jfieldID dp_lengthID;
 extern jfieldID dp_bufLengthID;
+#endif
 
 /* Inet6Address fields */
 extern jclass ia6_class;
diff --git a/ojluni/src/main/native/openjdksub.mk b/ojluni/src/main/native/openjdksub.mk
index da03db2..a083a6b 100644
--- a/ojluni/src/main/native/openjdksub.mk
+++ b/ojluni/src/main/native/openjdksub.mk
@@ -52,8 +52,6 @@
     Inet4Address.c \
     linux_close.cpp \
     PlainSocketImpl.c \
-    PlainDatagramSocketImpl.c \
-    DatagramPacket.c \
     ServerSocketChannelImpl.c \
     SocketInputStream.c \
     SocketOutputStream.c \
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index aed6c1a..a38fa4d 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1436,36 +1436,10 @@
     ojluni/src/main/java/sun/net/www/MeteredStream.java \
     ojluni/src/main/java/sun/net/www/ParseUtil.java \
     ojluni/src/main/java/sun/net/www/URLConnection.java \
-    ojluni/src/main/java/sun/net/www/http/ChunkedInputStream.java \
-    ojluni/src/main/java/sun/net/www/http/ChunkedOutputStream.java \
-    ojluni/src/main/java/sun/net/www/http/HttpCapture.java \
-    ojluni/src/main/java/sun/net/www/http/HttpCaptureInputStream.java \
-    ojluni/src/main/java/sun/net/www/http/HttpCaptureOutputStream.java \
-    ojluni/src/main/java/sun/net/www/http/HttpClient.java \
-    ojluni/src/main/java/sun/net/www/http/Hurryable.java \
-    ojluni/src/main/java/sun/net/www/http/KeepAliveCache.java \
-    ojluni/src/main/java/sun/net/www/http/KeepAliveStream.java \
-    ojluni/src/main/java/sun/net/www/http/KeepAliveStreamCleaner.java \
-    ojluni/src/main/java/sun/net/www/http/PosterOutputStream.java \
     ojluni/src/main/java/sun/net/www/protocol/file/FileURLConnection.java \
     ojluni/src/main/java/sun/net/www/protocol/file/Handler.java \
     ojluni/src/main/java/sun/net/www/protocol/ftp/FtpURLConnection.java \
     ojluni/src/main/java/sun/net/www/protocol/ftp/Handler.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/AuthCache.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheImpl.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/AuthCacheValue.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/AuthScheme.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationHeader.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/AuthenticationInfo.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/BasicAuthentication.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/DigestAuthentication.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/Handler.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/HttpAuthenticator.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/HttpCallerInfo.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/HttpURLConnection.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/NTLMAuthenticationProxy.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/NegotiateAuthentication.java \
-    ojluni/src/main/java/sun/net/www/protocol/http/Negotiator.java \
     ojluni/src/main/java/sun/net/www/protocol/jar/Handler.java \
     ojluni/src/main/java/sun/net/www/protocol/jar/JarFileFactory.java \
     ojluni/src/main/java/sun/net/www/protocol/jar/JarURLConnection.java \