Merge changes Ib8491242,I695758c4

* changes:
  EnumSet.isEmpty(): Provide test coverage.
  Lists: test coverage for misc corner cases.
diff --git a/JavaLibrary.bp b/JavaLibrary.bp
index 968072b..2d26422 100644
--- a/JavaLibrary.bp
+++ b/JavaLibrary.bp
@@ -615,6 +615,8 @@
 
 // Generates stubs for the parts of the public SDK API provided by the core
 // library.
+//
+// Only for use by core.current.stubs target below.
 droidstubs {
     name: "core-current-stubs-gen",
     srcs: [":core_api_files"],
@@ -626,6 +628,25 @@
     merge_inclusion_annotations_dirs: ["ojluni-annotated-mmodule-stubs"],
 }
 
+// A stubs target containing the parts of the public SDK API provided by the
+// core library.
+//
+// Don't use this directly, use "sdk_version: core_current".
+java_library {
+    name: "core.current.stubs",
+    srcs: [":core-current-stubs-gen"],
+    errorprone: {
+        javacflags: [
+            "-Xep:MissingOverride:OFF",
+        ],
+    },
+    openjdk9: {
+        javacflags: ["--patch-module=java.base=."],
+    },
+    no_standard_libs: true,
+    system_modules: "none",
+}
+
 // Target for validating nullability annotations for correctness and
 // completeness. To check that there are no nullability errors:
 //   make core-current-stubs-nullability-validation
@@ -654,25 +675,6 @@
     check_nullability_warnings: "nullability_warnings.txt",
 }
 
-// A stubs target containing the parts of the public SDK API provided by the
-// core library.
-//
-// Don't use this directly, use "sdk_version: core_current".
-java_library {
-    name: "core.current.stubs",
-    srcs: [":core-current-stubs-gen"],
-    errorprone: {
-        javacflags: [
-            "-Xep:MissingOverride:OFF",
-        ],
-    },
-    openjdk9: {
-        javacflags: ["--patch-module=java.base=."],
-    },
-    no_standard_libs: true,
-    system_modules: "none",
-}
-
 // A host library containing time zone related classes. Used for
 // host-side tools and tests that have to deal with Android
 // time zone data.
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
new file mode 100644
index 0000000..78c74dd
--- /dev/null
+++ b/PREUPLOAD.cfg
@@ -0,0 +1,3 @@
+[Hook Scripts]
+checkstyle-luni   = java -jar ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.jar -c tools/checkstyle/checkstyle-forbid-gpl.xml    luni/src/
+checkstyle-ojluni = java -jar ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.jar -c tools/checkstyle/checkstyle-forbid-apache.xml ojluni/src/
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
index 7793169..2eb64fe 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/text/SimpleDateFormatTest.java
@@ -891,51 +891,76 @@
         assertEquals(f2.toPattern(), f2.toLocalizedPattern());
     }
 
-    public void test_parse_with_spaces() {
-        // Regression for HARMONY-502
-        SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");
-        df.setLenient(false);
+    // Regression for HARMONY-502
+    public void test_parse_whitespace_within_date() {
+        Date date = new GregorianCalendar(2003, Calendar.APRIL, 5, 9, 7, 6).getTime();
+        parse_whitespace_variants(
+            new SimpleDateFormat("HH:mm:ss dd/MM/yy"),
+            date,
+            new String[] {
+                "%c9:07:06 05/04/03",
+                "%c09:07:06 05/04/03",
+                "09:%c7:06 05/04/03",
+                "09:%c07:06 05/04/03",
+                "09:07:%c6 05/04/03",
+                "09:07:%c06 05/04/03",
+                "09:07:06 %c05/04/03",
+                "09:07:06 %c5/04/03",
+                "09:07:06 05/%c4/03",
+                "09:07:06 05/%c04/03",
+                "09:07:06 05/04/%c03",
+            });
 
-        char allowed_chars[] = { 0x9, 0x20 };
-        String allowed_char_names[] = { "tab", "space" };
-        for (int i = 0; i < allowed_chars.length; i++) {
-            Date expected = new GregorianCalendar(1970, Calendar.JANUARY, 1, 9, 7, 6).getTime();
-            ParsePosition pp = new ParsePosition(0);
-            Date d = df.parse(allowed_chars[i] + "9:07:06", pp);
-            assertNotNull("hour may be prefixed by " + allowed_char_names[i], d);
-            assertEquals(expected, d);
+        parse_whitespace_variants(
+            new SimpleDateFormat("HH:mm:ss dd/MM/yyyy"),
+            date,
+            new String[] {
+                "09:07:06 05/04/%c2003",
+            });
+    }
 
-            pp = new ParsePosition(0);
-            d = df.parse("09:" + allowed_chars[i] + "7:06", pp);
-            assertNotNull("minute may be prefixed by " + allowed_char_names[i], d);
-            assertEquals(expected, d);
-
-            pp = new ParsePosition(0);
-            d = df.parse("09:07:" + allowed_chars[i] + "6", pp);
-            assertNotNull("second may be prefixed by " + allowed_char_names[i], d);
-            assertEquals(expected, d);
-        }
-
-        char not_allowed_chars[] = {
-                // whitespace
+    // Tests valid and invalid whitespace characters are parsed correctly within
+    // a date string. dateFormat and expected are the SimpleDateFormat and expected date.
+    // variants is a list of input variations where %c will be substituted with
+    // the whitespace characters to test.
+    private void parse_whitespace_variants(SimpleDateFormat dateFormat, Date expected,
+        String[] variants) {
+        char validWhitespace[] = { 0x9, 0x20 };
+        char invalidWhitespace[] = {
+                // Whitespace
                 0x1c, 0x1d, 0x1e, 0x1f, 0xa, 0xb, 0xc, 0xd, 0x2001, 0x2002,
                 0x2003, 0x2004, 0x2005, 0x2006, 0x2008, 0x2009, 0x200a, 0x200b,
                 0x2028, 0x2029, 0x3000,
-                // non-breaking space
+                // Non-breaking space
                 0xA0, 0x2007, 0x202F };
 
-        for (int i = 0; i < not_allowed_chars.length; i++) {
-            ParsePosition pp = new ParsePosition(0);
-            Date d = df.parse(not_allowed_chars[i] + "9:07", pp);
-            assertNull(d);
+        dateFormat.setLenient(false);
+        for (String variant: variants) {
+            for (char c : validWhitespace) {
+                String info = String.format("Parsing variant='%s', c=0x%x:", variant, (int) c);
+                String input = String.format(variant, c);
+                Date date = dateFormat.parse(input, new ParsePosition(0));
+                assertEquals(info, expected, date);
+                try {
+                    date = dateFormat.parse(input);
+                } catch (ParseException e) {
+                    fail(info);
+                }
+                assertEquals(info, expected, date);
 
-            pp = new ParsePosition(0);
-            d = df.parse("09:" + not_allowed_chars[i] + "7", pp);
-            assertNull(d);
-
-            pp = new ParsePosition(0);
-            d = df.parse("09:07:" + not_allowed_chars[i] + "6", pp);
-            assertNull(d);
+            }
+            for (char c : invalidWhitespace) {
+                String info = String.format("Parsing variant='%s', c=0x%x:", variant, (int) c);
+                String input = String.format(variant, c);
+                Date date = dateFormat.parse(input, new ParsePosition(0));
+                assertNull(info, date);
+                try {
+                    dateFormat.parse(input);
+                    fail(info);
+                } catch (ParseException e) {
+                    // Expected
+                }
+            }
         }
     }
 }
diff --git a/libart/src/main/java/java/lang/Daemons.java b/libart/src/main/java/java/lang/Daemons.java
index a04bee8..c827532 100644
--- a/libart/src/main/java/java/lang/Daemons.java
+++ b/libart/src/main/java/java/lang/Daemons.java
@@ -25,6 +25,7 @@
 import java.lang.ref.ReferenceQueue;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeoutException;
 import libcore.util.EmptyArray;
 
@@ -40,28 +41,44 @@
     private static final int NANOS_PER_SECOND = NANOS_PER_MILLI * 1000;
     @UnsupportedAppUsage
     private static final long MAX_FINALIZE_NANOS = 10L * NANOS_PER_SECOND;
+    private static final Daemon[] DAEMONS = new Daemon[] {
+            HeapTaskDaemon.INSTANCE,
+            ReferenceQueueDaemon.INSTANCE,
+            FinalizerDaemon.INSTANCE,
+            FinalizerWatchdogDaemon.INSTANCE,
+    };
+    private static final CountDownLatch POST_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+    private static final CountDownLatch PRE_ZYGOTE_START_LATCH = new CountDownLatch(DAEMONS.length);
+
+    private static boolean postZygoteFork = false;
 
     @UnsupportedAppUsage
     public static void start() {
-        ReferenceQueueDaemon.INSTANCE.start();
-        FinalizerDaemon.INSTANCE.start();
-        FinalizerWatchdogDaemon.INSTANCE.start();
-        HeapTaskDaemon.INSTANCE.start();
+        for (Daemon daemon : DAEMONS) {
+            daemon.start();
+        }
     }
 
     public static void startPostZygoteFork() {
-        ReferenceQueueDaemon.INSTANCE.startPostZygoteFork();
-        FinalizerDaemon.INSTANCE.startPostZygoteFork();
-        FinalizerWatchdogDaemon.INSTANCE.startPostZygoteFork();
-        HeapTaskDaemon.INSTANCE.startPostZygoteFork();
+        postZygoteFork = true;
+        for (Daemon daemon : DAEMONS) {
+            daemon.startPostZygoteFork();
+        }
     }
 
     @UnsupportedAppUsage
     public static void stop() {
-        HeapTaskDaemon.INSTANCE.stop();
-        ReferenceQueueDaemon.INSTANCE.stop();
-        FinalizerDaemon.INSTANCE.stop();
-        FinalizerWatchdogDaemon.INSTANCE.stop();
+        for (Daemon daemon : DAEMONS) {
+            daemon.stop();
+        }
+    }
+
+    private static void waitForDaemonStart() throws Exception {
+        if (postZygoteFork) {
+            POST_ZYGOTE_START_LATCH.await();
+        } else {
+            PRE_ZYGOTE_START_LATCH.await();
+        }
     }
 
     /**
@@ -95,16 +112,20 @@
             }
             thread = new Thread(ThreadGroup.systemThreadGroup, this, name);
             thread.setDaemon(true);
+            thread.setSystemDaemon(true);
             thread.start();
         }
 
-        public void run() {
+        public final void run() {
             if (postZygoteFork) {
                 // We don't set the priority before the Thread.start() call above because
                 // Thread.start() will call SetNativePriority and overwrite the desired native
                 // priority. We (may) use a native priority that doesn't have a corresponding
                 // java.lang.Thread-level priority (native priorities are more coarse-grained.)
                 VMRuntime.getRuntime().setSystemDaemonThreadPriority();
+                POST_ZYGOTE_START_LATCH.countDown();
+            } else {
+                PRE_ZYGOTE_START_LATCH.countDown();
             }
             runInternal();
         }
diff --git a/luni/src/test/java/libcore/java/net/InetAddressTest.java b/luni/src/test/java/libcore/java/net/InetAddressTest.java
index e55d38f..307cd1d 100644
--- a/luni/src/test/java/libcore/java/net/InetAddressTest.java
+++ b/luni/src/test/java/libcore/java/net/InetAddressTest.java
@@ -192,6 +192,20 @@
     }
 
     @Test
+    public void test_isNumeric_notNumeric_null() throws Exception {
+        try {
+            boolean result = InetAddress.isNumeric(null);
+            fail("Expected isNumeric(null) to throw a NPE but instead returned " + result);
+        } catch (NullPointerException expected) {
+        }
+    }
+
+    @Test
+    public void test_isNumeric_notNumeric_empty() throws Exception {
+        assertFalse(InetAddress.isNumeric(""));
+    }
+
+    @Test
     public void test_isNumeric_notNumeric() throws Exception {
         // Negative test
         assertFalse(InetAddress.isNumeric("example.com"));
diff --git a/luni/src/test/java/libcore/libcore/io/OsTest.java b/luni/src/test/java/libcore/libcore/io/OsTest.java
index a4d7326..5d09939 100644
--- a/luni/src/test/java/libcore/libcore/io/OsTest.java
+++ b/luni/src/test/java/libcore/libcore/io/OsTest.java
@@ -423,9 +423,9 @@
     expectBindConnectSendtoErrno(EAFNOSUPPORT, EAFNOSUPPORT, EINVAL,
                                  makeIpv6Socket(), "ipv6", addrUnix);
 
-    expectBindConnectSendtoErrno(EINVAL, EAFNOSUPPORT, EINVAL,
+    expectBindConnectSendtoErrno(EINVAL, EINVAL, EINVAL,
                                  makeUnixSocket(), "unix", addrIpv4);
-    expectBindConnectSendtoErrno(EINVAL, EAFNOSUPPORT, EINVAL,
+    expectBindConnectSendtoErrno(EINVAL, EINVAL, EINVAL,
                                  makeUnixSocket(), "unix", addrIpv6);
     expectBindConnectSendtoSuccess(makeUnixSocket(), "unix", addrUnix);
   }
diff --git a/ojluni/src/main/java/java/lang/Thread.java b/ojluni/src/main/java/java/lang/Thread.java
index 591d14a..0ca9074 100644
--- a/ojluni/src/main/java/java/lang/Thread.java
+++ b/ojluni/src/main/java/java/lang/Thread.java
@@ -236,6 +236,11 @@
     /* For generating thread ID */
     private static long threadSeqNumber;
 
+
+    // Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+    /** True if this thread is managed by {@link Daemons}. */
+    private boolean systemDaemon = false;
+
     /* Java thread status for tools,
      * initialized to indicate thread 'not yet started'
      */
@@ -2182,6 +2187,43 @@
         getUncaughtExceptionHandler().uncaughtException(this, e);
     }
 
+    // BEGIN Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+    /**
+     * Marks this thread as either a special runtime-managed ("system daemon")
+     * thread or a normal (i.e. app code created) daemon thread.)
+     *
+     * <p>System daemon threads get special handling when starting up in some
+     * cases.
+     *
+     * <p>This method must be invoked before the thread is started.
+     *
+     * <p>This method must only be invoked on Thread instances that have already
+     * had {@code setDaemon(true)} called on them.
+     *
+     * <p>Package-private since only {@link java.lang.Daemons} needs to call
+     * this.
+     *
+     * @param  on if {@code true}, marks this thread as a system daemon thread
+     *
+     * @throws  IllegalThreadStateException
+     *          if this thread is {@linkplain #isAlive alive} or not a
+     *          {@linkplain #isDaemon daemon}
+     *
+     * @throws  SecurityException
+     *          if {@link #checkAccess} determines that the current
+     *          thread cannot modify this thread
+     *
+     * @hide For use by Daemons.java only.
+     */
+    final void setSystemDaemon(boolean on) {
+        checkAccess();
+        if (isAlive() || !isDaemon()) {
+            throw new IllegalThreadStateException();
+        }
+        systemDaemon = on;
+    }
+    // END Android-added: The concept of "system-daemon" threads. See java.lang.Daemons.
+
     /**
      * Removes from the specified map any keys that have been enqueued
      * on the specified reference queue.
diff --git a/ojluni/src/main/java/java/lang/Throwable.java b/ojluni/src/main/java/java/lang/Throwable.java
index 09de274..5a3f8a8 100644
--- a/ojluni/src/main/java/java/lang/Throwable.java
+++ b/ojluni/src/main/java/java/lang/Throwable.java
@@ -120,7 +120,7 @@
     /**
      * Native code saves some indication of the stack backtrace in this slot.
      */
-    private transient volatile Object backtrace;
+    private transient Object backtrace;
 
     /**
      * Specific details about the Throwable.  For example, for
@@ -155,6 +155,13 @@
             new StackTraceElement[] {STACK_TRACE_ELEMENT_SENTINEL};
     }
 
+    // Android-removed: Use libcore.util.EmptyArray for the empty stack trace
+    // Adding the constant UNASSIGNED_STACK breaks serialization of some subclasses
+    // /**
+    //  * A shared value for an empty stack.
+    //  */
+    // private static final StackTraceElement[] UNASSIGNED_STACK = new StackTraceElement[0];
+
     /*
      * To allow Throwable objects to be made immutable and safely
      * reused by the JVM, such as OutOfMemoryErrors, fields of
@@ -204,9 +211,19 @@
      * @serial
      * @since 1.4
      */
-    // Android-changed.
+    // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+    // private StackTraceElement[] stackTrace = UNASSIGNED_STACK;
     private StackTraceElement[] stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
 
+    // Android-removed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // Adding this constant breaks serialization of some subclasses
+    /*
+    // Setting this static field introduces an acceptable
+    // initialization dependency on a few java.util classes.
+    private static final List<Throwable> SUPPRESSED_SENTINEL =
+        Collections.unmodifiableList(new ArrayList<Throwable>(0));
+    */
+
     /**
      * The list of suppressed exceptions, as returned by {@link
      * #getSuppressed()}.  The list is initialized to a zero-element
@@ -217,6 +234,8 @@
      * @serial
      * @since 1.7
      */
+    // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+    // private List<Throwable> suppressedExceptions = SUPPRESSED_SENTINEL;
     private List<Throwable> suppressedExceptions = Collections.emptyList();
 
     /** Message for trying to suppress a null exception. */
@@ -670,6 +689,9 @@
                                          String caption,
                                          String prefix,
                                          Set<Throwable> dejaVu) {
+        // Android-removed: Use of assert keyword which breaks serialization of some subclasses
+        // (Using assert adds a static field that determines whether assertions are enabled.)
+        // assert Thread.holdsLock(s.lock());
         if (dejaVu.contains(this)) {
             s.println("\t[CIRCULAR REFERENCE:" + this + "]");
         } else {
@@ -772,12 +794,18 @@
     public synchronized Throwable fillInStackTrace() {
         if (stackTrace != null ||
             backtrace != null /* Out of protocol state */ ) {
+            // Android-changed: Use Android-specific nativeFillInStackTrace
+            // fillInStackTrace(0);
             backtrace = nativeFillInStackTrace();
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // stackTrace = UNASSIGNED_STACK;
             stackTrace = libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
         }
         return this;
     }
 
+    // Android-changed: Use Android-specific nativeFillInStackTrace
+    // private native Throwable fillInStackTrace(int dummy);
     @FastNative
     private static native Object nativeFillInStackTrace();
 
@@ -812,21 +840,26 @@
     private synchronized StackTraceElement[] getOurStackTrace() {
         // Initialize stack trace field with information from
         // backtrace if this is the first call to this method
-        //
-        // Android-changed: test explicitly for equality with
-        // STACK_TRACE_ELEMENT
+        // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+        // if (stackTrace == UNASSIGNED_STACK ||
         if (stackTrace == libcore.util.EmptyArray.STACK_TRACE_ELEMENT ||
             (stackTrace == null && backtrace != null) /* Out of protocol state */) {
+            // BEGIN Android-changed: Use Android-specific nativeGetStackTrace
+            // int depth = getStackTraceDepth();
+            // stackTrace = new StackTraceElement[depth];
+            // for (int i=0; i < depth; i++)
+            //     stackTrace[i] = getStackTraceElement(i);
             stackTrace = nativeGetStackTrace(backtrace);
             backtrace = null;
-        }
-
-        // Android-changed: Return an empty element both when the stack trace
-        // isn't writeable and also when nativeGetStackTrace returns null.
-        if (stackTrace == null) {
+            if (stackTrace == null) {
+                return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
+            }
+            // END Android-changed: Use Android-specific nativeGetStackTrace
+        } else if (stackTrace == null) {
+            // Android-changed: Use libcore.util.EmptyArray for the empty stack trace
+            // return UNASSIGNED_STACK;
             return libcore.util.EmptyArray.STACK_TRACE_ELEMENT;
         }
-
         return stackTrace;
     }
 
@@ -874,6 +907,15 @@
         }
     }
 
+    // Android-removed: Unused native method getStackTraceDepth()
+    // /**
+    //  * Returns the number of elements in the stack trace (or 0 if the stack
+    //  * trace is unavailable).
+    //  *
+    //  * package-protection for use by SharedSecrets.
+    //  */
+    // native int getStackTraceDepth();
+
     /**
      * Returns the specified element of the stack trace.
      *
@@ -883,6 +925,8 @@
      * @throws IndexOutOfBoundsException if {@code index < 0 ||
      *         index >= getStackTraceDepth() }
      */
+    // Android-changed: Use Android-specific nativeGetStackTrace
+    // native StackTraceElement getStackTraceElement(int index);
     @FastNative
     private static native StackTraceElement[] nativeGetStackTrace(Object stackState);
 
@@ -909,6 +953,8 @@
             List<Throwable> suppressed = null;
             if (suppressedExceptions.isEmpty()) {
                 // Use the sentinel for a zero-length list
+                // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+                // suppressed = SUPPRESSED_SENTINEL;
                 suppressed = Collections.emptyList();
             } else { // Copy Throwables to new list
                 suppressed = new ArrayList<>(1);
@@ -936,6 +982,8 @@
          */
         if (stackTrace != null) {
             if (stackTrace.length == 0) {
+                // Android-removed: clone() call not needed because of libcore.util.EmptyArray usage
+                // stackTrace = UNASSIGNED_STACK.clone();
             }  else if (stackTrace.length == 1 &&
                         // Check for the marker of an immutable stack trace
                         SentinelHolder.STACK_TRACE_ELEMENT_SENTINEL.equals(stackTrace[0])) {
@@ -951,6 +999,8 @@
             // from an exception serialized without that field in
             // older JDK releases; treat such exceptions as having
             // empty stack traces.
+            // Android-changed: Directly create empty array instead of cloning UNASSIGNED_STACK
+            // stackTrace = UNASSIGNED_STACK.clone();
             stackTrace = new StackTraceElement[0];
         }
     }
@@ -1040,12 +1090,16 @@
         if (suppressedExceptions == null) // Suppressed exceptions not recorded
             return;
 
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // if (suppressedExceptions == SUPPRESSED_SENTINEL)
         if (suppressedExceptions.isEmpty())
             suppressedExceptions = new ArrayList<>(1);
 
         suppressedExceptions.add(exception);
     }
 
+    // Android-changed: Lazily initialize EMPTY_THROWABLE_ARRAY
+    // private static final Throwable[] EMPTY_THROWABLE_ARRAY = new Throwable[0];
     private static Throwable[] EMPTY_THROWABLE_ARRAY;
 
     /**
@@ -1064,10 +1118,14 @@
      * @since 1.7
      */
     public final synchronized Throwable[] getSuppressed() {
+        // Android-added: Lazily initialize EMPTY_THROWABLE_ARRAY
         if (EMPTY_THROWABLE_ARRAY == null) {
             EMPTY_THROWABLE_ARRAY = new Throwable[0];
         }
 
+        // Android-changed: Use empty collection in place of SUPPRESSED_SENTINEL
+        // if (suppressedExceptions == SUPPRESSED_SENTINEL ||
+        //    suppressedExceptions == null)
         if (suppressedExceptions == null || suppressedExceptions.isEmpty())
             return EMPTY_THROWABLE_ARRAY;
         else
diff --git a/ojluni/src/main/java/java/net/InetAddress.java b/ojluni/src/main/java/java/net/InetAddress.java
index 9685ffa..e4f8660 100644
--- a/ojluni/src/main/java/java/net/InetAddress.java
+++ b/ojluni/src/main/java/java/net/InetAddress.java
@@ -1607,21 +1607,26 @@
     // Particularly those required to deal with scope ids.
     /**
      * Returns true if the string is a valid numeric IPv4 or IPv6 address (such as "192.168.0.1").
-     * This copes with all forms of address that Java supports, detailed in the {@link InetAddress}
-     * class documentation.
+     *
+     * <p>This copes with all forms of address that Java supports, detailed in the
+     * {@link InetAddress} class documentation. An empty string is not treated as numeric.
      *
      * @hide used by frameworks/base to ensure that a getAllByName won't cause a DNS lookup.
      * @deprecated Use {@link InetAddressUtils#isNumericAddress(String)} instead, if possible.
+     * @throws NullPointerException if the {@code address} is {@code null}.
      */
     @Deprecated
     public static boolean isNumeric(String address) {
-        return _parseNumericAddress(address) != null;
+        return InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(address) != null;
     }
 
     /**
      * Returns an InetAddress corresponding to the given numeric address (such
      * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
-     * This method will never do a DNS lookup. Non-numeric addresses are errors.
+     *
+     * <p>This method will never do a DNS lookup. Non-numeric addresses are errors. Passing either
+     * an empty string or a {@code null} as the {@code numericAddress} will return the
+     * {@link Inet6Address#LOOPBACK} address.
      *
      * @hide used by frameworks/base's NetworkUtils.numericToInetAddress
      * @throws IllegalArgumentException if {@code numericAddress} is not a numeric address
@@ -1629,20 +1634,17 @@
      */
     @Deprecated
     public static InetAddress parseNumericAddress(String numericAddress) {
-        InetAddress result = _parseNumericAddress(numericAddress);
+        if (numericAddress == null || numericAddress.isEmpty()) {
+            return Inet6Address.LOOPBACK;
+        }
+        InetAddress result = InetAddressUtils
+                .parseNumericAddressNoThrowStripOptionalBrackets(numericAddress);
         if (result == null) {
             throw new IllegalArgumentException("Not a numeric address: " + numericAddress);
         }
         return result;
     }
 
-    private static InetAddress _parseNumericAddress(String numericAddress) {
-        if (numericAddress == null || numericAddress.isEmpty()) {
-            return Inet6Address.LOOPBACK;
-        }
-        return InetAddressUtils.parseNumericAddressNoThrowStripOptionalBrackets(numericAddress);
-    }
-
     /**
      * Removes all entries from the VM's DNS cache. This does not affect the C library's DNS
      * cache, nor any caching DNS servers between you and the canonical server.
diff --git a/tools/checkstyle/checkstyle-forbid-apache.xml b/tools/checkstyle/checkstyle-forbid-apache.xml
new file mode 100644
index 0000000..1bdb007
--- /dev/null
+++ b/tools/checkstyle/checkstyle-forbid-apache.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+          "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- Copyright (C) 2019 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.
+-->
+<!-- Ensures that files checked with this checker do not contain Apache
+     license text. This is done by searching for license name preceded by
+     comment asterisk:
+     " * ... Apache License ..."
+-->
+
+<module name="Checker">
+  <property name="fileExtensions" value="java"/>
+
+  <module name="RegexpSingleline">
+    <property name="severity" value="error"/>
+    <property name="format" value="^\W+\*.*Apache License.*$" />
+    <property name="message" value="files MUST NOT have Apache license"/>
+  </module>
+
+</module>
diff --git a/tools/checkstyle/checkstyle-forbid-gpl.xml b/tools/checkstyle/checkstyle-forbid-gpl.xml
new file mode 100644
index 0000000..96ce191
--- /dev/null
+++ b/tools/checkstyle/checkstyle-forbid-gpl.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+          "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+          "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- Copyright (C) 2019 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.
+-->
+<!-- Ensures that files checked with this checker do not contain GPL
+     license text. This is done by searching for license name preceded by
+     comment asterisk:
+     " * ... GNU General Public License ..."
+-->
+
+<module name="Checker">
+  <property name="fileExtensions" value="java"/>
+
+  <module name="RegexpSingleline">
+    <property name="severity" value="error"/>
+    <property name="format" value="^\W+\*.*GNU General Public License.*$" />
+    <property name="message" value="files MUST NOT have GPL license"/>
+  </module>
+
+</module>