Merge "Fix DirectByteBufferAlignment"
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
index 87e177f..964fd32 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/FormatterTest.java
@@ -876,24 +876,27 @@
         try {
             f = new Formatter(Locale.US);
             f.format("%.s", "hello", "2");
-            fail("should throw UnknownFormatConversionException");
-        } catch (UnknownFormatConversionException e) {
+            fail("should throw Exception");
+        } catch (UnknownFormatConversionException
+                 | IllegalFormatPrecisionException expected) {
             // expected
         }
 
         try {
             f = new Formatter(Locale.US);
             f.format("%.-5s", "123456");
-            fail("should throw UnknownFormatConversionException");
-        } catch (UnknownFormatConversionException e) {
+            fail("should throw Exception");
+        } catch (UnknownFormatConversionException
+                 | IllegalFormatPrecisionException expected) {
             // expected
         }
 
         try {
             f = new Formatter(Locale.US);
             f.format("%1.s", "hello", "2");
-            fail("should throw UnknownFormatConversionException");
-        } catch (UnknownFormatConversionException e) {
+            fail("should throw Exception");
+        } catch (UnknownFormatConversionException
+                 | IllegalFormatPrecisionException expected) {
             // expected
         }
 
@@ -1113,6 +1116,11 @@
                 fail("should throw UnknownFormatConversionException");
             } catch (UnknownFormatConversionException e) {
                 // expected
+            } catch (IllegalFormatPrecisionException e) {
+                // If i is '.', s can also be interpreted as an illegal precision.
+                if (i != '.') {
+                    throw e;
+                }
             }
         }
     }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
index 2f96394..d67b1c9 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/ScannerTest.java
@@ -4801,16 +4801,9 @@
         } catch (NullPointerException expected) {
         }
         String result = s.findInLine(Pattern.compile("^"));
-        assertEquals("", result);
-        MatchResult matchResult = s.match();
-        assertEquals(0, matchResult.start());
-        assertEquals(0, matchResult.end());
-
+        assertEquals(null, result);
         result = s.findInLine(Pattern.compile("$"));
-        assertEquals("", result);
-        matchResult = s.match();
-        assertEquals(0, matchResult.start());
-        assertEquals(0, matchResult.end());
+        assertEquals(null, result);
 
         /*
          * When we use the operation of findInLine(Pattern), the match region
@@ -4827,7 +4820,7 @@
         s = new Scanner("abcd1234test\n");
         result = s.findInLine(Pattern.compile("\\p{Lower}+"));
         assertEquals("abcd", result);
-        matchResult = s.match();
+        MatchResult matchResult = s.match();
         assertEquals(0, matchResult.start());
         assertEquals(4, matchResult.end());
 
@@ -4895,21 +4888,33 @@
         s = new Scanner("test\u0085\ntest");
         result = s.findInLine("est");
         assertEquals("est", result);
-        result = s.findInLine("est");
-        assertEquals("est", result);
+        // First consume input upto U+0085(a line separator)
+        assertTrue(s.hasNextLine());
+        assertEquals("", s.nextLine());
+        // Then consume input upto the "\n"
+        assertTrue(s.hasNextLine());
+        assertEquals("", s.nextLine());
+        // The next line will be "test", which should match.
+        assertEquals("est", s.findInLine("est"));
 
         s = new Scanner("test\ntest");
         result = s.findInLine("est");
         assertEquals("est", result);
         result = s.findInLine("est");
-        assertEquals("est", result);
+        assertNull(result);
 
         s = new Scanner("test\n123\ntest");
         result = s.findInLine("est");
         assertEquals("est", result);
         result = s.findInLine("est");
-        // RI fails. It is a RI's bug.
         assertNull(result);
+        s.nextLine();
+        result = s.findInLine("est");
+        assertNull(result);
+        s.nextLine();
+        result = s.findInLine("est");
+        assertEquals("est", result);
+
 
         s = new Scanner( "   *\n");
         result = s.findInLine(Pattern.compile( "^\\s*(?:\\*(?=[^/]))"));
@@ -4939,16 +4944,10 @@
     public void test_findInLine_LString() {
       Scanner s = new Scanner("");
       String result = s.findInLine("^");
-      assertEquals("", result);
-      MatchResult matchResult = s.match();
-      assertEquals(0, matchResult.start());
-      assertEquals(0, matchResult.end());
+      assertNull(result);
 
       result = s.findInLine("$");
-      assertEquals("", result);
-      matchResult = s.match();
-      assertEquals(0, matchResult.start());
-      assertEquals(0, matchResult.end());
+      assertNull(result);
 
       // When we use the operation of findInLine(Pattern), the match region
       // should not span the line separator.
@@ -4963,7 +4962,7 @@
       s = new Scanner("abcd1234test\n");
       result = s.findInLine("\\p{Lower}+");
       assertEquals("abcd", result);
-      matchResult = s.match();
+      MatchResult matchResult = s.match();
       assertEquals(0, matchResult.start());
       assertEquals(4, matchResult.end());
 
@@ -5024,18 +5023,19 @@
       result = s.findInLine("est");
       assertEquals("est", result);
       result = s.findInLine("est");
-      assertEquals("est", result);
+      assertNull(result);
 
       s = new Scanner("test\ntest");
       result = s.findInLine("est");
       assertEquals("est", result);
       result = s.findInLine("est");
-      assertEquals("est", result);
+      assertNull(result);
 
       s = new Scanner("test\n123\ntest");
       result = s.findInLine("est");
       assertEquals("est", result);
       result = s.findInLine("est");
+      assertNull(result);
     }
 
     /**
diff --git a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
index 0b0fac7..aa26b4f 100644
--- a/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
+++ b/luni/src/main/java/libcore/net/NetworkSecurityPolicy.java
@@ -26,9 +26,20 @@
  * <p>The policy currently consists of a single flag: whether cleartext network traffic is
  * permitted. See {@link #isCleartextTrafficPermitted()}.
  */
-public class NetworkSecurityPolicy {
+public abstract class NetworkSecurityPolicy {
 
-    private static volatile boolean cleartextTrafficPermitted = true;
+    private static volatile NetworkSecurityPolicy instance = new DefaultNetworkSecurityPolicy();
+
+    public static NetworkSecurityPolicy getInstance() {
+        return instance;
+    }
+
+    public static void setInstance(NetworkSecurityPolicy policy) {
+        if (policy == null) {
+            throw new NullPointerException("policy == null");
+        }
+        instance = policy;
+    }
 
     /**
      * Returns whether cleartext network traffic (e.g. HTTP, FTP, XMPP, IMAP, SMTP -- without TLS or
@@ -46,17 +57,12 @@
      * this flag from day one, and well-established third-party network stacks will eventually
      * honor it.
      */
-    public static boolean isCleartextTrafficPermitted() {
-        return cleartextTrafficPermitted;
-    }
+    public abstract boolean isCleartextTrafficPermitted();
 
-    /**
-     * Sets whether cleartext network traffic (e.g. HTTP, FTP, XMPP, IMAP, SMTP -- without TLS or
-     * STARTTLS) is permitted for this process.
-     *
-     * @see #isCleartextTrafficPermitted()
-     */
-    public static void setCleartextTrafficPermitted(boolean permitted) {
-        cleartextTrafficPermitted = permitted;
+    public static final class DefaultNetworkSecurityPolicy extends NetworkSecurityPolicy {
+        @Override
+        public boolean isCleartextTrafficPermitted() {
+            return true;
+        }
     }
 }
diff --git a/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java b/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java
index 96b9e3b..b9b3ff3 100644
--- a/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java
+++ b/luni/src/test/java/libcore/icu/RelativeDateTimeFormatterTest.java
@@ -684,4 +684,19 @@
       }
     }
   }
+
+  // Check for ICU data lookup fallback failure. http://b/25883157
+  public void test_bug25883157() {
+    final Locale locale = new Locale("en", "GB");
+    final TimeZone tz = TimeZone.getTimeZone("GMT");
+
+    final Calendar cal = Calendar.getInstance(tz, locale);
+    cal.set(2015, Calendar.JUNE, 19, 12, 0, 0);
+
+    final long base = cal.getTimeInMillis();
+    final long time = base + 2 * WEEK_IN_MILLIS;
+
+    assertEquals("In 2 wk", getRelativeTimeSpanString(
+        locale, tz, time, base, WEEK_IN_MILLIS, FORMAT_ABBREV_RELATIVE));
+  }
 }
diff --git a/luni/src/test/java/libcore/java/io/FileTest.java b/luni/src/test/java/libcore/java/io/FileTest.java
index 482d9dd..13a6f0b 100644
--- a/luni/src/test/java/libcore/java/io/FileTest.java
+++ b/luni/src/test/java/libcore/java/io/FileTest.java
@@ -302,5 +302,25 @@
         nativeTestFilesWithSurrogatePairs(base.getAbsolutePath());
     }
 
+    // http://b/25878034
+    //
+    // SELinux prevents stat(2) from working on some parts of the system partition, and there
+    // isn't currently a CTS test that enforces this for the system partition as a whole (and it
+    // isn't clear that there can be one). This particular file has a special label
+    // (see file_contexts) that makes sure it isn't unstattable but then again this file might
+    // disappear soon or be absent on some devices.
+    //
+    // TODO: This isn't a very good test. uncrypt is scheduled to disappear somewhere
+    // in the near future. Is there a better candidate file ?
+    public void testExistsOnSystem() {
+        File sh = new File("/system/bin/uncrypt");
+        assertTrue(sh.exists());
+        try {
+            android.system.Os.stat(sh.getAbsolutePath());
+            fail();
+        } catch (android.system.ErrnoException expected) {
+        }
+    }
+
     private static native void nativeTestFilesWithSurrogatePairs(String base);
 }
diff --git a/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java b/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
index d04e2ba..fbcc3ae 100644
--- a/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
+++ b/luni/src/test/java/libcore/net/NetworkSecurityPolicyTest.java
@@ -37,42 +37,40 @@
 
 public class NetworkSecurityPolicyTest extends TestCase {
 
-    private boolean mCleartextTrafficPermittedOriginalState;
+    private NetworkSecurityPolicy mOriginalPolicy;
 
     @Override
     protected void setUp() throws Exception {
         super.setUp();
-        mCleartextTrafficPermittedOriginalState =
-                NetworkSecurityPolicy.isCleartextTrafficPermitted();
+        mOriginalPolicy = NetworkSecurityPolicy.getInstance();
     }
 
     @Override
     protected void tearDown() throws Exception {
         try {
-            NetworkSecurityPolicy.setCleartextTrafficPermitted(
-                    mCleartextTrafficPermittedOriginalState);
+            NetworkSecurityPolicy.setInstance(mOriginalPolicy);
         } finally {
             super.tearDown();
         }
     }
 
     public void testCleartextTrafficPolicySetterAndGetter() {
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
-        assertEquals(false, NetworkSecurityPolicy.isCleartextTrafficPermitted());
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
+        assertEquals(false, NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
 
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
-        assertEquals(true, NetworkSecurityPolicy.isCleartextTrafficPermitted());
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
+        assertEquals(true, NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
 
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
-        assertEquals(false, NetworkSecurityPolicy.isCleartextTrafficPermitted());
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
+        assertEquals(false, NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
 
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
-        assertEquals(true, NetworkSecurityPolicy.isCleartextTrafficPermitted());
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
+        assertEquals(true, NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted());
     }
 
     public void testCleartextTrafficPolicyWithHttpURLConnection() throws Exception {
         // Assert that client transmits some data when cleartext traffic is permitted.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
         try (CapturingServerSocket server = new CapturingServerSocket()) {
             URL url = new URL("http://localhost:" + server.getPort() + "/test.txt");
             try {
@@ -85,7 +83,7 @@
 
         // Assert that client does not transmit any data when cleartext traffic is not permitted and
         // that URLConnection.openConnection or getContent fail with an IOException.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
         try (CapturingServerSocket server = new CapturingServerSocket()) {
             URL url = new URL("http://localhost:" + server.getPort() + "/test.txt");
             try {
@@ -99,7 +97,7 @@
 
     public void testCleartextTrafficPolicyWithFtpURLConnection() throws Exception {
         // Assert that client transmits some data when cleartext traffic is permitted.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
         byte[] serverReplyOnConnect = "220\r\n".getBytes("US-ASCII");
         try (CapturingServerSocket server = new CapturingServerSocket(serverReplyOnConnect)) {
             URL url = new URL("ftp://localhost:" + server.getPort() + "/test.txt");
@@ -113,7 +111,7 @@
 
         // Assert that client does not transmit any data when cleartext traffic is not permitted and
         // that URLConnection.openConnection or getContent fail with an IOException.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
         try (CapturingServerSocket server = new CapturingServerSocket(serverReplyOnConnect)) {
             URL url = new URL("ftp://localhost:" + server.getPort() + "/test.txt");
             try {
@@ -127,7 +125,7 @@
 
     public void testCleartextTrafficPolicyWithJarHttpURLConnection() throws Exception {
         // Assert that client transmits some data when cleartext traffic is permitted.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
         try (CapturingServerSocket server = new CapturingServerSocket()) {
             URL url = new URL("jar:http://localhost:" + server.getPort() + "/test.jar!/");
             try {
@@ -140,7 +138,7 @@
 
         // Assert that client does not transmit any data when cleartext traffic is not permitted and
         // that JarURLConnection.openConnection or getManifest fail with an IOException.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
         try (CapturingServerSocket server = new CapturingServerSocket()) {
             URL url = new URL("jar:http://localhost:" + server.getPort() + "/test.jar!/");
             try {
@@ -154,7 +152,7 @@
 
     public void testCleartextTrafficPolicyWithJarFtpURLConnection() throws Exception {
         // Assert that client transmits some data when cleartext traffic is permitted.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
         byte[] serverReplyOnConnect = "220\r\n".getBytes("US-ASCII");
         try (CapturingServerSocket server = new CapturingServerSocket(serverReplyOnConnect)) {
             URL url = new URL("jar:ftp://localhost:" + server.getPort() + "/test.jar!/");
@@ -168,7 +166,7 @@
 
         // Assert that client does not transmit any data when cleartext traffic is not permitted and
         // that JarURLConnection.openConnection or getManifest fail with an IOException.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
         try (CapturingServerSocket server = new CapturingServerSocket(serverReplyOnConnect)) {
             URL url = new URL("jar:ftp://localhost:" + server.getPort() + "/test.jar!/");
             try {
@@ -182,7 +180,7 @@
 
     public void testCleartextTrafficPolicyWithLoggingSocketHandler() throws Exception {
         // Assert that client transmits some data when cleartext traffic is permitted.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(true);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(true));
         try (CapturingServerSocket server = new CapturingServerSocket()) {
             SocketHandler logger = new SocketHandler("localhost", server.getPort());
             MockErrorManager mockErrorManager = new MockErrorManager();
@@ -196,7 +194,7 @@
         }
 
         // Assert that client does not transmit any data when cleartext traffic is not permitted.
-        NetworkSecurityPolicy.setCleartextTrafficPermitted(false);
+        NetworkSecurityPolicy.setInstance(new TestNetworkSecurityPolicy(false));
         try (CapturingServerSocket server = new CapturingServerSocket()) {
             try {
                 new SocketHandler("localhost", server.getPort());
@@ -312,4 +310,17 @@
             }
         }
     }
+
+    private static class TestNetworkSecurityPolicy extends NetworkSecurityPolicy {
+        private final boolean mCleartextTrafficPermitted;
+
+        public TestNetworkSecurityPolicy(boolean cleartextTrafficPermitted) {
+            mCleartextTrafficPermitted = cleartextTrafficPermitted;
+        }
+
+        @Override
+        public boolean isCleartextTrafficPermitted() {
+            return mCleartextTrafficPermitted;
+        }
+    }
 }
diff --git a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
index 5307cf4..a768863 100644
--- a/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
+++ b/luni/src/test/java/org/apache/harmony/luni/tests/java/net/URLConnectionTest.java
@@ -864,7 +864,7 @@
         URL url = new URL("http", "test", 80, "index.html", new NewHandler());
         URLConnection urlCon = url.openConnection();
         urlCon.setRequestProperty("test", "testProperty");
-        assertNull(urlCon.getRequestProperty("test"));
+        assertEquals("testProperty", urlCon.getRequestProperty("test"));
 
         urlCon.connect();
         try {
diff --git a/ojluni/src/main/java/java/lang/ref/Reference.java b/ojluni/src/main/java/java/lang/ref/Reference.java
index 52d40b0..636f976 100755
--- a/ojluni/src/main/java/java/lang/ref/Reference.java
+++ b/ojluni/src/main/java/java/lang/ref/Reference.java
@@ -107,6 +107,17 @@
         return queueNext != null;
     }
 
+    /** @hide */
+    public final synchronized boolean enqueueInternal() {
+        if (queue != null && queueNext == null) {
+            queue.enqueue(this);
+            queue = null;
+            return true;
+        }
+        return false;
+    }
+
+
     /**
      * Adds this reference object to the queue with which it is registered,
      * if any.
@@ -118,15 +129,6 @@
      *           enqueued; <code>false</code> if it was already enqueued or if
      *           it was not registered with a queue when it was created
      */
-    public final synchronized boolean enqueueInternal() {
-        if (queue != null && queueNext == null) {
-            queue.enqueue(this);
-            queue = null;
-            return true;
-        }
-        return false;
-    }
-
     public boolean enqueue() {
        return enqueueInternal();
     }
diff --git a/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java b/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
index b654c24..b8646d2 100755
--- a/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
+++ b/ojluni/src/main/java/java/lang/ref/ReferenceQueue.java
@@ -32,55 +32,22 @@
  * @author   Mark Reinhold
  * @since    1.2
  */
-
 public class ReferenceQueue<T> {
 
+    // NOTE: This implementation of ReferenceQueue is FIFO (queue-like) whereas
+    // the OpenJdk implementation is LIFO (stack-like).
+    private Reference<? extends T> head = null;
+    private Reference<? extends T> tail = null;
+
+    private final Object lock = new Object();
+
     /**
      * Constructs a new reference-object queue.
      */
     public ReferenceQueue() { }
 
-    /* ----- BEGIN android -----
-    private static class Null extends ReferenceQueue {
-        boolean enqueue(Reference r) {
-            return false;
-        }
-    }
-
-    static ReferenceQueue NULL = new Null();
-    static ReferenceQueue ENQUEUED = new Null();
-
-    static private class Lock { };
-    private Lock lock = new Lock();
-    ----- END android ----- */
-
-    private volatile Reference<? extends T> head = null;
-
-    // ----- BEGIN android -----
-    // Needed to make it a queue (OpenJdk impl behaves like a stack).
-    private Reference<? extends T> tail;
-    // ----- END android -----
-
-    private long queueLength = 0;
-
     boolean enqueue(Reference<? extends T> r) { /* Called only by Reference class */
-        /* ----- BEGIN android -----
-        synchronized (r) {
-            if (r.queue == ENQUEUED) return false;
-            synchronized (lock) {
-                r.queue = ENQUEUED;
-                r.next = (head == null) ? r : head;
-                head = r;
-                queueLength++;
-                if (r instanceof FinalReference) {
-                    sun.misc.VM.addFinalRefCount(1);
-                }
-                lock.notifyAll();
-                return true;
-            }
-        }*/
-        /* Caller must hold r lock */
-        synchronized (this) {
+        synchronized (lock) {
             if (tail == null) {
                 head = r;
             } else {
@@ -88,27 +55,13 @@
             }
             tail = r;
             tail.queueNext = r;
-            queueLength++;
-            this.notifyAll();
+            lock.notifyAll();
             return true;
         }
-        // ----- END android -----
     }
 
-    private Reference<? extends T> reallyPoll() {       /* Must hold lock */
-        /* ----- BEGIN android -----
-        if (head != null) {
-            Reference<? extends T> r = head;
-            head = (r.next == r) ? null : r.next;
-            r.queue = NULL;
-            r.next = r;
-            queueLength--;
-            if (r instanceof FinalReference) {
-                sun.misc.VM.addFinalRefCount(-1);
-            }
-            return r;
-        }
-        */
+    // @GuardedBy("lock")
+    private Reference<? extends T> reallyPollLocked() {
         if (head != null) {
             Reference<? extends T> r = head;
             if (head == tail) {
@@ -118,10 +71,9 @@
                 head = head.queueNext;
             }
             r.queueNext = null;
-            queueLength--;
             return r;
         }
-        // ----- END android -----
+
         return null;
     }
 
@@ -134,14 +86,11 @@
      *          otherwise <code>null</code>
      */
     public Reference<? extends T> poll() {
-        if (head == null)
-            return null;
+        synchronized (lock) {
+            if (head == null)
+                return null;
 
-        /* ----- BEGIN android -----
-        synchronized (lock) { */
-        synchronized (this) {
-        // ----- END android -----
-            return reallyPoll();
+            return reallyPollLocked();
         }
     }
 
@@ -171,20 +120,20 @@
         if (timeout < 0) {
             throw new IllegalArgumentException("Negative timeout value");
         }
-        /* ----- BEGIN android -----
-        synchronized (lock) { */
-        synchronized (this) {
-        // ----- END android -----
-            Reference<? extends T> r = reallyPoll();
+        synchronized (lock) {
+            Reference<? extends T> r = reallyPollLocked();
             if (r != null) return r;
+            long start = (timeout == 0) ? 0 : System.nanoTime();
             for (;;) {
-                /* ----- BEGIN android -----
-                lock.wait(timeout);*/
-                this.wait(timeout);
-                // ----- END android -----
-                r = reallyPoll();
+                lock.wait(timeout);
+                r = reallyPollLocked();
                 if (r != null) return r;
-                if (timeout != 0) return null;
+                if (timeout != 0) {
+                    long end = System.nanoTime();
+                    timeout -= (end - start) / 1000_000;
+                    if (timeout <= 0) return null;
+                    start = end;
+                }
             }
         }
     }
@@ -200,7 +149,6 @@
         return remove(0);
     }
 
-    // ----- BEGIN android -----
     /** @hide */
     public static Reference<?> unenqueued = null;
 
@@ -225,5 +173,4 @@
             ReferenceQueue.class.notifyAll();
         }
     }
-    // ----- END android -----
-}
\ No newline at end of file
+}
diff --git a/ojluni/src/main/java/java/net/URLConnection.java b/ojluni/src/main/java/java/net/URLConnection.java
index 48cf9bc..1cd64b0 100755
--- a/ojluni/src/main/java/java/net/URLConnection.java
+++ b/ojluni/src/main/java/java/net/URLConnection.java
@@ -297,11 +297,6 @@
     private static FileNameMap fileNameMap;
 
     /**
-     * @since 1.2.2
-     */
-    private static boolean fileNameMapLoaded = false;
-
-    /**
      * Loads filename map (a mimetable) from a data file. It will
      * first try to load the user-specific table, defined
      * by &quot;content.types.user.table&quot; property. If that fails,
@@ -313,23 +308,8 @@
      * @see #setFileNameMap(java.net.FileNameMap)
      */
     public static synchronized FileNameMap getFileNameMap() {
-        /* ----- BEGIN android -----
-        if ((fileNameMap == null) && !fileNameMapLoaded) {
-            fileNameMap = sun.net.www.MimeTable.loadTable();
-            fileNameMapLoaded = true;
-        }
-
-        return new FileNameMap() {
-            private FileNameMap map = fileNameMap;
-            public String getContentTypeFor(String fileName) {
-                return map.getContentTypeFor(fileName);
-            }
-        };
-        ----- END android -----*/
-
-        if ((fileNameMap == null) && !fileNameMapLoaded) {
+        if (fileNameMap == null) {
             fileNameMap = new DefaultFileNameMap();
-            fileNameMapLoaded = true;
         }
         return fileNameMap;
     }
diff --git a/ojluni/src/main/java/java/util/ComparableTimSort.java b/ojluni/src/main/java/java/util/ComparableTimSort.java
index 22427a2..4e5e7ac 100755
--- a/ojluni/src/main/java/java/util/ComparableTimSort.java
+++ b/ojluni/src/main/java/java/util/ComparableTimSort.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Google Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -131,7 +132,7 @@
          */
         int stackLen = (len <    120  ?  5 :
                         len <   1542  ? 10 :
-                        len < 119151  ? 19 : 40);
+                        len < 119151  ? 24 : 40);
         runBase = new int[stackLen];
         runLen = new int[stackLen];
     }
diff --git a/ojluni/src/main/java/java/util/Formatter.java b/ojluni/src/main/java/java/util/Formatter.java
index bcd36ea..579b127 100755
--- a/ojluni/src/main/java/java/util/Formatter.java
+++ b/ojluni/src/main/java/java/util/Formatter.java
@@ -47,8 +47,6 @@
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.text.NumberFormat;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import sun.misc.FpUtils;
 import sun.misc.DoubleConsts;
@@ -2501,51 +2499,133 @@
         return this;
     }
 
-    // %[argument_index$][flags][width][.precision][t]conversion
-    private static final String formatSpecifier
-        = "%(\\d+\\$)?([-#+ 0,(\\<]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])";
-
-    private static Pattern fsPattern = Pattern.compile(formatSpecifier);
-
     /**
      * Finds format specifiers in the format string.
      */
     private FormatString[] parse(String s) {
         ArrayList<FormatString> al = new ArrayList<>();
-        Matcher m = fsPattern.matcher(s);
         for (int i = 0, len = s.length(); i < len; ) {
-            if (m.find(i)) {
-                // Anything between the start of the string and the beginning
-                // of the format specifier is either fixed text or contains
-                // an invalid format string.
-                if (m.start() != i) {
-                    // Make sure we didn't miss any invalid format specifiers
-                    checkText(s, i, m.start());
-                    // Assume previous characters were fixed text
-                    al.add(new FixedString(s.substring(i, m.start())));
-                }
-
-                al.add(new FormatSpecifier(m));
-                i = m.end();
+            int nextPercent = s.indexOf('%', i);
+            if (s.charAt(i) != '%') {
+                // This is plain-text part, find the maximal plain-text
+                // sequence and store it.
+                int plainTextStart = i;
+                int plainTextEnd = (nextPercent == -1) ? len: nextPercent;
+                al.add(new FixedString(s.substring(plainTextStart,
+                                                   plainTextEnd)));
+                i = plainTextEnd;
             } else {
-                // No more valid format specifiers.  Check for possible invalid
-                // format specifiers.
-                checkText(s, i, len);
-                // The rest of the string is fixed text
-                al.add(new FixedString(s.substring(i)));
-                break;
+                // We have a format specifier
+                FormatSpecifierParser fsp = new FormatSpecifierParser(s, i + 1);
+                al.add(fsp.getFormatSpecifier());
+                i = fsp.getEndIdx();
             }
         }
         return al.toArray(new FormatString[al.size()]);
     }
 
-    private static void checkText(String s, int start, int end) {
-        for (int i = start; i < end; i++) {
-            // Any '%' found in the region starts an invalid format specifier.
-            if (s.charAt(i) == '%') {
-                char c = (i == end - 1) ? '%' : s.charAt(i + 1);
-                throw new UnknownFormatConversionException(String.valueOf(c));
+    /**
+     * Parses the format specifier.
+     * %[argument_index$][flags][width][.precision][t]conversion
+     */
+    private class FormatSpecifierParser {
+        private final String format;
+        private int cursor;
+        private FormatSpecifier fs;
+
+        private String index;
+        private String flags;
+        private String width;
+        private String precision;
+        private String tT;
+        private String conv;
+
+        private static final String FLAGS = ",-(+# 0<";
+
+        public FormatSpecifierParser(String format, int startIdx) {
+            this.format = format;
+            cursor = startIdx;
+            // Index
+            if (nextIsInt()) {
+                String nint = nextInt();
+                if (peek() == '$') {
+                    index = nint;
+                    advance();
+                } else if (nint.charAt(0) == '0') {
+                    // This is a flag, skip to parsing flags.
+                    back(nint.length());
+                } else {
+                    // This is the width, skip to parsing precision.
+                    width = nint;
+                }
             }
+            // Flags
+            flags = "";
+            while (width == null && FLAGS.indexOf(peek()) >= 0) {
+                flags += advance();
+            }
+            // Width
+            if (width == null && nextIsInt()) {
+                width = nextInt();
+            }
+            // Precision
+            if (peek() == '.') {
+                advance();
+                if (!nextIsInt()) {
+                    throw new IllegalFormatPrecisionException(peek());
+                }
+                precision = nextInt();
+            }
+            // tT
+            if (peek() == 't' || peek() == 'T') {
+                tT = String.valueOf(advance());
+            }
+            // Conversion
+            conv = String.valueOf(advance());
+
+            fs = new FormatSpecifier(index, flags, width, precision, tT, conv);
+        }
+
+        private String nextInt() {
+            int strBegin = cursor;
+            while (nextIsInt()) {
+                advance();
+            }
+            return format.substring(strBegin, cursor);
+        }
+
+        private boolean nextIsInt() {
+            return !isEnd() && Character.isDigit(peek());
+        }
+
+        private char peek() {
+            if (isEnd()) {
+                throw new UnknownFormatConversionException("End of String");
+            }
+            return format.charAt(cursor);
+        }
+
+        private char advance() {
+            if (isEnd()) {
+                throw new UnknownFormatConversionException("End of String");
+            }
+            return format.charAt(cursor++);
+        }
+
+        private void back(int len) {
+            cursor -= len;
+        }
+
+        private boolean isEnd() {
+            return cursor == format.length();
+        }
+
+        public FormatSpecifier getFormatSpecifier() {
+            return fs;
+        }
+
+        public int getEndIdx() {
+            return cursor;
         }
     }
 
@@ -2577,7 +2657,7 @@
         private int index(String s) {
             if (s != null) {
                 try {
-                    index = Integer.parseInt(s.substring(0, s.length() - 1));
+                    index = Integer.parseInt(s);
                 } catch (NumberFormatException x) {
                     assert(false);
                 }
@@ -2624,8 +2704,7 @@
             precision = -1;
             if (s != null) {
                 try {
-                    // remove the '.'
-                    precision = Integer.parseInt(s.substring(1));
+                    precision = Integer.parseInt(s);
                     if (precision < 0)
                         throw new IllegalFormatPrecisionException(precision);
                 } catch (NumberFormatException x) {
@@ -2657,22 +2736,22 @@
             return c;
         }
 
-        FormatSpecifier(Matcher m) {
+        FormatSpecifier(String indexStr, String flagsStr, String widthStr,
+                        String precisionStr, String tTStr, String convStr) {
             int idx = 1;
 
-            index(m.group(idx++));
-            flags(m.group(idx++));
-            width(m.group(idx++));
-            precision(m.group(idx++));
+            index(indexStr);
+            flags(flagsStr);
+            width(widthStr);
+            precision(precisionStr);
 
-            String tT = m.group(idx++);
-            if (tT != null) {
+            if (tTStr != null) {
                 dt = true;
-                if (tT.equals("T"))
+                if (tTStr.equals("T"))
                     f.add(Flags.UPPERCASE);
             }
 
-            conversion(m.group(idx));
+            conversion(convStr);
 
             if (dt)
                 checkDateTime();
diff --git a/ojluni/src/main/java/java/util/TimSort.java b/ojluni/src/main/java/java/util/TimSort.java
index 0c2e1ec..ad051e5 100755
--- a/ojluni/src/main/java/java/util/TimSort.java
+++ b/ojluni/src/main/java/java/util/TimSort.java
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2009 Google Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -158,7 +159,7 @@
          */
         int stackLen = (len <    120  ?  5 :
                         len <   1542  ? 10 :
-                        len < 119151  ? 19 : 40);
+                        len < 119151  ? 24 : 40);
         runBase = new int[stackLen];
         runLen = new int[stackLen];
     }
diff --git a/support/src/test/java/libcore/java/security/TestKeyStore.java b/support/src/test/java/libcore/java/security/TestKeyStore.java
index 425cefa..0fb8f2a 100644
--- a/support/src/test/java/libcore/java/security/TestKeyStore.java
+++ b/support/src/test/java/libcore/java/security/TestKeyStore.java
@@ -75,6 +75,17 @@
  * accessible via TestKeyStore.get().
  */
 public final class TestKeyStore extends Assert {
+    /** Size of DH keys to generate for testing. */
+    private static final int DH_KEY_SIZE_BITS = 1024;
+
+    /** Size of DSA keys to generate for testing. */
+    private static final int DSA_KEY_SIZE_BITS = 1024;
+
+    /** Size of EC keys to generate for testing. */
+    private static final int EC_KEY_SIZE_BITS = 256;
+
+    /** Size of RSA keys to generate for testing. */
+    private static final int RSA_KEY_SIZE_BITS = 1024;
 
     private static TestKeyStore ROOT_CA;
     private static TestKeyStore INTERMEDIATE_CA;
@@ -460,21 +471,19 @@
                     // 1a.) we make the keys
                     int keySize;
                     if (keyAlgorithm.equals("RSA")) {
-                        // 512 breaks SSL_RSA_EXPORT_* on RI and
-                        // TLS_ECDHE_RSA_WITH_RC4_128_SHA for us
-                        keySize = 1024;
+                        keySize = RSA_KEY_SIZE_BITS;
                     } else if (keyAlgorithm.equals("DH_RSA")) {
-                        keySize = 512;
+                        keySize = DH_KEY_SIZE_BITS;
                         keyAlgorithm = "DH";
                     } else if (keyAlgorithm.equals("DSA")) {
-                        keySize = 512;
+                        keySize = DSA_KEY_SIZE_BITS;
                     } else if (keyAlgorithm.equals("DH_DSA")) {
-                        keySize = 512;
+                        keySize = DH_KEY_SIZE_BITS;
                         keyAlgorithm = "DH";
                     } else if (keyAlgorithm.equals("EC")) {
-                        keySize = 256;
+                        keySize = EC_KEY_SIZE_BITS;
                     } else if (keyAlgorithm.equals("EC_RSA")) {
-                        keySize = 256;
+                        keySize = EC_KEY_SIZE_BITS;
                         keyAlgorithm = "EC";
                     } else {
                         throw new IllegalArgumentException("Unknown key algorithm " + keyAlgorithm);
diff --git a/support/src/test/java/tests/support/Support_TestWebServer.java b/support/src/test/java/tests/support/Support_TestWebServer.java
index 5f3cd85..33216a7 100644
--- a/support/src/test/java/tests/support/Support_TestWebServer.java
+++ b/support/src/test/java/tests/support/Support_TestWebServer.java
@@ -732,7 +732,8 @@
                 // 404 status already sent
                 return;
             }
-            SimpleDateFormat df = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss");
+            SimpleDateFormat df = new SimpleDateFormat("EE, dd MMM yyyy HH:mm:ss z");
+            df.setTimeZone(TimeZone.getTimeZone("GMT"));
 
             psPrint(ps,"Server: TestWebServer"+mPort);
             psWriteEOL(ps);