Merge "Hashtable: Use upstream OpenJDK8u121-b13 versions of Map default methods"
diff --git a/JavaLibrary.mk b/JavaLibrary.mk
index d348239..758b6ce 100644
--- a/JavaLibrary.mk
+++ b/JavaLibrary.mk
@@ -91,7 +91,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-all
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_REQUIRED_MODULES := tzdata
 LOCAL_CORE_LIBRARY := true
 LOCAL_UNINSTALLABLE_MODULE := true
@@ -109,7 +108,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-oj
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
 LOCAL_REQUIRED_MODULES := tzdata
@@ -126,7 +124,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-libart
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all
 ifeq ($(EMMA_INSTRUMENT),true)
 ifneq ($(EMMA_INSTRUMENT_STATIC),true)
@@ -148,7 +145,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-lambda-stubs
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
 LOCAL_CORE_LIBRARY := true
@@ -169,7 +165,6 @@
 LOCAL_DEX_PREOPT := false
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-oj-testdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
 LOCAL_REQUIRED_MODULES := tzdata
@@ -204,7 +199,6 @@
 LOCAL_DEX_PREOPT := false
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-libart-testdex
-LOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all
 LOCAL_CORE_LIBRARY := true
 LOCAL_REQUIRED_MODULES := tzdata
@@ -221,6 +215,9 @@
 LOCAL_JAVA_LIBRARIES := core-oj core-libart
 LOCAL_DEX_PREOPT := false
 include $(BUILD_JAVA_LIBRARY)
+my_filesystemstest_jar := $(intermediates)/filesystemstest.jar
+$(my_filesystemstest_jar): $(LOCAL_BUILT_MODULE)
+	$(call copy-file-to-target)
 endif
 
 ifeq ($(LIBCORE_SKIP_TESTS),)
@@ -230,7 +227,7 @@
 LOCAL_JAVA_RESOURCE_DIRS := $(test_resource_dirs)
 # Include individual dex.jar files (jars containing resources and a classes.dex) so that they
 # be loaded by tests using ClassLoaders but are not in the main classes.dex.
-LOCAL_JAVA_RESOURCE_FILES := $(TARGET_OUT)/framework/filesystemstest.jar
+LOCAL_JAVA_RESOURCE_FILES := $(my_filesystemstest_jar)
 LOCAL_NO_STANDARD_LIBRARIES := true
 LOCAL_JAVA_LIBRARIES := core-oj core-libart okhttp bouncycastle
 LOCAL_STATIC_JAVA_LIBRARIES := \
@@ -248,7 +245,6 @@
 LOCAL_ERROR_PRONE_FLAGS := -Xep:TryFailThrowable:ERROR
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-tests
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
 endif
 
@@ -262,7 +258,6 @@
 LOCAL_STATIC_JAVA_LIBRARIES := bouncycastle-bcpkix bouncycastle-ocsp
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := core-tests-support
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
 endif
 
@@ -276,7 +271,6 @@
 LOCAL_JAVACFLAGS := $(local_javac_flags)
 LOCAL_MODULE := jsr166-tests
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
 endif
 
@@ -292,7 +286,6 @@
     LOCAL_MODULE_TAGS := optional
     LOCAL_JAVA_LANGUAGE_VERSION := 1.8
     LOCAL_MODULE := core-ojtests
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     # jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
     LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
     include $(BUILD_JAVA_LIBRARY)
@@ -317,7 +310,6 @@
     LOCAL_MODULE_TAGS := optional
     LOCAL_JAVA_LANGUAGE_VERSION := 1.8
     LOCAL_MODULE := core-ojtests-public
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     # jack bug workaround: int[] java.util.stream.StatefulTestOp.-getjava-util-stream-StreamShapeSwitchesValues() is a private synthetic method in an interface which causes a hard verifier error
     LOCAL_DEX_PREOPT := false # disable AOT preverification which breaks the build. it will still throw VerifyError at runtime.
     include $(BUILD_JAVA_LIBRARY)
@@ -330,12 +322,6 @@
 ifeq ($(HOST_OS),linux)
 
 include $(CLEAR_VARS)
-LOCAL_SRC_FILES := $(call all-java-files-under, dex/src/main)
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE := dex-host
-include $(BUILD_HOST_JAVA_LIBRARY)
-
-include $(CLEAR_VARS)
 LOCAL_SRC_FILES := $(non_openjdk_java_files) $(openjdk_java_files) $(android_icu4j_src_files) $(openjdk_lambda_stub_files)
 LOCAL_JAVA_RESOURCE_DIRS := $(core_resource_dirs)
 LOCAL_NO_STANDARD_LIBRARIES := true
@@ -344,7 +330,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-all-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_REQUIRED_MODULES := tzdata-host
 LOCAL_CORE_LIBRARY := true
 LOCAL_UNINSTALLABLE_MODULE := true
@@ -360,7 +345,6 @@
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-oj-hostdex
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/ojluni/NOTICE
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all-hostdex
 LOCAL_REQUIRED_MODULES := tzdata-host
 LOCAL_CORE_LIBRARY := true
@@ -376,7 +360,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-libart-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-oj-hostdex
 LOCAL_REQUIRED_MODULES := tzdata-host
 include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
@@ -391,7 +374,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_JAVA_LANGUAGE_VERSION := 1.8
 LOCAL_MODULE := core-lambda-stubs-hostdex
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 LOCAL_JAVA_LIBRARIES := core-all-hostdex
 LOCAL_CORE_LIBRARY := true
 include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
@@ -423,7 +405,6 @@
     LOCAL_MODULE_TAGS := optional
     LOCAL_JAVA_LANGUAGE_VERSION := 1.8
     LOCAL_MODULE := core-tests-hostdex
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 endif
 
@@ -444,7 +425,6 @@
     LOCAL_JAVACFLAGS := $(local_javac_flags)
     LOCAL_MODULE_TAGS := optional
     LOCAL_MODULE := core-tests-support-hostdex
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 endif
 
@@ -464,7 +444,6 @@
     LOCAL_MODULE_TAGS := optional
     LOCAL_JAVA_LANGUAGE_VERSION := 1.8
     LOCAL_MODULE := core-ojtests-hostdex
-    LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
     include $(BUILD_HOST_DALVIK_JAVA_LIBRARY)
 endif
 
@@ -502,7 +481,6 @@
 LOCAL_MODULE_CLASS:=JAVA_LIBRARIES
 
 LOCAL_MODULE := libcore
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/JavaLibrary.mk
 
 LOCAL_DROIDDOC_OPTIONS := \
  -offlinemode \
diff --git a/dalvik/src/main/java/dalvik/system/DexPathList.java b/dalvik/src/main/java/dalvik/system/DexPathList.java
index b9e607a..3693bb2 100644
--- a/dalvik/src/main/java/dalvik/system/DexPathList.java
+++ b/dalvik/src/main/java/dalvik/system/DexPathList.java
@@ -441,8 +441,6 @@
             } else if (file.isDirectory()) {
                 // We support directories for looking up native libraries.
                 elements[elementsPos++] = new NativeLibraryElement(file);
-            } else {
-                System.logW("ClassLoader referenced unknown path: " + file);
             }
         }
         if (elementsPos != elements.length) {
diff --git a/dex/src/main/java/com/android/dex/Annotation.java b/dex/src/main/java/com/android/dex/Annotation.java
deleted file mode 100644
index e5ef978..0000000
--- a/dex/src/main/java/com/android/dex/Annotation.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import static com.android.dex.EncodedValueReader.ENCODED_ANNOTATION;
-
-/**
- * An annotation.
- */
-public final class Annotation implements Comparable<Annotation> {
-    private final Dex dex;
-    private final byte visibility;
-    private final EncodedValue encodedAnnotation;
-
-    public Annotation(Dex dex, byte visibility, EncodedValue encodedAnnotation) {
-        this.dex = dex;
-        this.visibility = visibility;
-        this.encodedAnnotation = encodedAnnotation;
-    }
-
-    public byte getVisibility() {
-        return visibility;
-    }
-
-    public EncodedValueReader getReader() {
-        return new EncodedValueReader(encodedAnnotation, ENCODED_ANNOTATION);
-    }
-
-    public int getTypeIndex() {
-        EncodedValueReader reader = getReader();
-        reader.readAnnotation();
-        return reader.getAnnotationType();
-    }
-
-    public void writeTo(Dex.Section out) {
-        out.writeByte(visibility);
-        encodedAnnotation.writeTo(out);
-    }
-
-    @Override public int compareTo(Annotation other) {
-        return encodedAnnotation.compareTo(other.encodedAnnotation);
-    }
-
-    @Override public String toString() {
-        return dex == null
-                ? visibility + " " + getTypeIndex()
-                : visibility + " " + dex.typeNames().get(getTypeIndex());
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/ClassData.java b/dex/src/main/java/com/android/dex/ClassData.java
deleted file mode 100644
index 840756c..0000000
--- a/dex/src/main/java/com/android/dex/ClassData.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-public final class ClassData {
-    private final Field[] staticFields;
-    private final Field[] instanceFields;
-    private final Method[] directMethods;
-    private final Method[] virtualMethods;
-
-    public ClassData(Field[] staticFields, Field[] instanceFields,
-            Method[] directMethods, Method[] virtualMethods) {
-        this.staticFields = staticFields;
-        this.instanceFields = instanceFields;
-        this.directMethods = directMethods;
-        this.virtualMethods = virtualMethods;
-    }
-
-    public Field[] getStaticFields() {
-        return staticFields;
-    }
-
-    public Field[] getInstanceFields() {
-        return instanceFields;
-    }
-
-    public Method[] getDirectMethods() {
-        return directMethods;
-    }
-
-    public Method[] getVirtualMethods() {
-        return virtualMethods;
-    }
-
-    public Field[] allFields() {
-        Field[] result = new Field[staticFields.length + instanceFields.length];
-        System.arraycopy(staticFields, 0, result, 0, staticFields.length);
-        System.arraycopy(instanceFields, 0, result, staticFields.length, instanceFields.length);
-        return result;
-    }
-
-    public Method[] allMethods() {
-        Method[] result = new Method[directMethods.length + virtualMethods.length];
-        System.arraycopy(directMethods, 0, result, 0, directMethods.length);
-        System.arraycopy(virtualMethods, 0, result, directMethods.length, virtualMethods.length);
-        return result;
-    }
-
-    public static class Field {
-        private final int fieldIndex;
-        private final int accessFlags;
-
-        public Field(int fieldIndex, int accessFlags) {
-            this.fieldIndex = fieldIndex;
-            this.accessFlags = accessFlags;
-        }
-
-        public int getFieldIndex() {
-            return fieldIndex;
-        }
-
-        public int getAccessFlags() {
-            return accessFlags;
-        }
-    }
-
-    public static class Method {
-        private final int methodIndex;
-        private final int accessFlags;
-        private final int codeOffset;
-
-        public Method(int methodIndex, int accessFlags, int codeOffset) {
-            this.methodIndex = methodIndex;
-            this.accessFlags = accessFlags;
-            this.codeOffset = codeOffset;
-        }
-
-        public int getMethodIndex() {
-            return methodIndex;
-        }
-
-        public int getAccessFlags() {
-            return accessFlags;
-        }
-
-        public int getCodeOffset() {
-            return codeOffset;
-        }
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/ClassDef.java b/dex/src/main/java/com/android/dex/ClassDef.java
deleted file mode 100644
index b3225ec..0000000
--- a/dex/src/main/java/com/android/dex/ClassDef.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-/**
- * A type definition.
- */
-public final class ClassDef {
-    public static final int NO_INDEX = -1;
-    private final Dex buffer;
-    private final int offset;
-    private final int typeIndex;
-    private final int accessFlags;
-    private final int supertypeIndex;
-    private final int interfacesOffset;
-    private final int sourceFileIndex;
-    private final int annotationsOffset;
-    private final int classDataOffset;
-    private final int staticValuesOffset;
-
-    public ClassDef(Dex buffer, int offset, int typeIndex, int accessFlags,
-            int supertypeIndex, int interfacesOffset, int sourceFileIndex,
-            int annotationsOffset, int classDataOffset, int staticValuesOffset) {
-        this.buffer = buffer;
-        this.offset = offset;
-        this.typeIndex = typeIndex;
-        this.accessFlags = accessFlags;
-        this.supertypeIndex = supertypeIndex;
-        this.interfacesOffset = interfacesOffset;
-        this.sourceFileIndex = sourceFileIndex;
-        this.annotationsOffset = annotationsOffset;
-        this.classDataOffset = classDataOffset;
-        this.staticValuesOffset = staticValuesOffset;
-    }
-
-    public int getOffset() {
-        return offset;
-    }
-
-    public int getTypeIndex() {
-        return typeIndex;
-    }
-
-    public int getSupertypeIndex() {
-        return supertypeIndex;
-    }
-
-    public int getInterfacesOffset() {
-        return interfacesOffset;
-    }
-
-    public short[] getInterfaces() {
-        return buffer.readTypeList(interfacesOffset).getTypes();
-    }
-
-    public int getAccessFlags() {
-        return accessFlags;
-    }
-
-    public int getSourceFileIndex() {
-        return sourceFileIndex;
-    }
-
-    public int getAnnotationsOffset() {
-        return annotationsOffset;
-    }
-
-    public int getClassDataOffset() {
-        return classDataOffset;
-    }
-
-    public int getStaticValuesOffset() {
-        return staticValuesOffset;
-    }
-
-    @Override public String toString() {
-        if (buffer == null) {
-            return typeIndex + " " + supertypeIndex;
-        }
-
-        StringBuilder result = new StringBuilder();
-        result.append(buffer.typeNames().get(typeIndex));
-        if (supertypeIndex != NO_INDEX) {
-            result.append(" extends ").append(buffer.typeNames().get(supertypeIndex));
-        }
-        return result.toString();
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/Code.java b/dex/src/main/java/com/android/dex/Code.java
deleted file mode 100644
index 9258af7..0000000
--- a/dex/src/main/java/com/android/dex/Code.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-public final class Code {
-    private final int registersSize;
-    private final int insSize;
-    private final int outsSize;
-    private final int debugInfoOffset;
-    private final short[] instructions;
-    private final Try[] tries;
-    private final CatchHandler[] catchHandlers;
-
-    public Code(int registersSize, int insSize, int outsSize, int debugInfoOffset,
-            short[] instructions, Try[] tries, CatchHandler[] catchHandlers) {
-        this.registersSize = registersSize;
-        this.insSize = insSize;
-        this.outsSize = outsSize;
-        this.debugInfoOffset = debugInfoOffset;
-        this.instructions = instructions;
-        this.tries = tries;
-        this.catchHandlers = catchHandlers;
-    }
-
-    public int getRegistersSize() {
-        return registersSize;
-    }
-
-    public int getInsSize() {
-        return insSize;
-    }
-
-    public int getOutsSize() {
-        return outsSize;
-    }
-
-    public int getDebugInfoOffset() {
-        return debugInfoOffset;
-    }
-
-    public short[] getInstructions() {
-        return instructions;
-    }
-
-    public Try[] getTries() {
-        return tries;
-    }
-
-    public CatchHandler[] getCatchHandlers() {
-        return catchHandlers;
-    }
-
-    public static class Try {
-        final int startAddress;
-        final int instructionCount;
-        final int catchHandlerIndex;
-
-        Try(int startAddress, int instructionCount, int catchHandlerIndex) {
-            this.startAddress = startAddress;
-            this.instructionCount = instructionCount;
-            this.catchHandlerIndex = catchHandlerIndex;
-        }
-
-        public int getStartAddress() {
-            return startAddress;
-        }
-
-        public int getInstructionCount() {
-            return instructionCount;
-        }
-
-        /**
-         * Returns this try's catch handler <strong>index</strong>. Note that
-         * this is distinct from the its catch handler <strong>offset</strong>.
-         */
-        public int getCatchHandlerIndex() {
-            return catchHandlerIndex;
-        }
-    }
-
-    public static class CatchHandler {
-        final int[] typeIndexes;
-        final int[] addresses;
-        final int catchAllAddress;
-        final int offset;
-
-        public CatchHandler(int[] typeIndexes, int[] addresses, int catchAllAddress, int offset) {
-            this.typeIndexes = typeIndexes;
-            this.addresses = addresses;
-            this.catchAllAddress = catchAllAddress;
-            this.offset = offset;
-        }
-
-        public int[] getTypeIndexes() {
-            return typeIndexes;
-        }
-
-        public int[] getAddresses() {
-            return addresses;
-        }
-
-        public int getCatchAllAddress() {
-            return catchAllAddress;
-        }
-
-        public int getOffset() {
-            return offset;
-        }
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/Dex.java b/dex/src/main/java/com/android/dex/Dex.java
deleted file mode 100644
index 59e5ffb..0000000
--- a/dex/src/main/java/com/android/dex/Dex.java
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.Code.CatchHandler;
-import com.android.dex.Code.Try;
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-import com.android.dex.util.FileUtils;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UTFDataFormatException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.AbstractList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.RandomAccess;
-import java.util.zip.Adler32;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipFile;
-
-/**
- * The bytes of a dex file in memory for reading and writing. All int offsets
- * are unsigned.
- */
-public final class Dex {
-    private static final int CHECKSUM_OFFSET = 8;
-    private static final int CHECKSUM_SIZE = 4;
-    private static final int SIGNATURE_OFFSET = CHECKSUM_OFFSET + CHECKSUM_SIZE;
-    private static final int SIGNATURE_SIZE = 20;
-    // Provided as a convenience to avoid a memory allocation to benefit Dalvik.
-    // Note: libcore.util.EmptyArray cannot be accessed when this code isn't run on Dalvik.
-    static final short[] EMPTY_SHORT_ARRAY = new short[0];
-
-    private ByteBuffer data;
-    private final TableOfContents tableOfContents = new TableOfContents();
-    private int nextSectionStart = 0;
-    private final StringTable strings = new StringTable();
-    private final TypeIndexToDescriptorIndexTable typeIds = new TypeIndexToDescriptorIndexTable();
-    private final TypeIndexToDescriptorTable typeNames = new TypeIndexToDescriptorTable();
-    private final ProtoIdTable protoIds = new ProtoIdTable();
-    private final FieldIdTable fieldIds = new FieldIdTable();
-    private final MethodIdTable methodIds = new MethodIdTable();
-
-    /**
-     * Creates a new dex that reads from {@code data}. It is an error to modify
-     * {@code data} after using it to create a dex buffer.
-     */
-    public Dex(byte[] data) throws IOException {
-        this(ByteBuffer.wrap(data));
-    }
-
-    private Dex(ByteBuffer data) throws IOException {
-        this.data = data;
-        this.data.order(ByteOrder.LITTLE_ENDIAN);
-        this.tableOfContents.readFrom(this);
-    }
-
-    /**
-     * Creates a new empty dex of the specified size.
-     */
-    public Dex(int byteCount) throws IOException {
-        this.data = ByteBuffer.wrap(new byte[byteCount]);
-        this.data.order(ByteOrder.LITTLE_ENDIAN);
-    }
-
-    /**
-     * Creates a new dex buffer of the dex in {@code in}, and closes {@code in}.
-     */
-    public Dex(InputStream in) throws IOException {
-        try {
-            loadFrom(in);
-        } finally {
-            in.close();
-        }
-    }
-
-    /**
-     * Creates a new dex buffer from the dex file {@code file}.
-     */
-    public Dex(File file) throws IOException {
-        if (FileUtils.hasArchiveSuffix(file.getName())) {
-            ZipFile zipFile = new ZipFile(file);
-            ZipEntry entry = zipFile.getEntry(DexFormat.DEX_IN_JAR_NAME);
-            if (entry != null) {
-                try (InputStream inputStream = zipFile.getInputStream(entry)) {
-                    loadFrom(inputStream);
-                }
-                zipFile.close();
-            } else {
-                throw new DexException("Expected " + DexFormat.DEX_IN_JAR_NAME + " in " + file);
-            }
-        } else if (file.getName().endsWith(".dex")) {
-            try (InputStream inputStream = new FileInputStream(file)) {
-                loadFrom(inputStream);
-            }
-        } else {
-            throw new DexException("unknown output extension: " + file);
-        }
-    }
-
-    /**
-     * Creates a new dex from the contents of {@code bytes}. This API supports
-     * both {@code .dex} and {@code .odex} input. Calling this constructor
-     * transfers ownership of {@code bytes} to the returned Dex: it is an error
-     * to access the buffer after calling this method.
-     *
-     * NOTE: This method is called by the runtime.
-     */
-    public static Dex create(ByteBuffer data) throws IOException {
-        data.order(ByteOrder.LITTLE_ENDIAN);
-
-        // if it's an .odex file, set position and limit to the .dex section
-        if (data.get(0) == 'd'
-                && data.get(1) == 'e'
-                && data.get(2) == 'y'
-                && data.get(3) == '\n') {
-            data.position(8);
-            int offset = data.getInt();
-            int length = data.getInt();
-            data.position(offset);
-            data.limit(offset + length);
-            data = data.slice();
-        }
-
-        return new Dex(data);
-    }
-
-    /**
-     * It is the caller's responsibility to close {@code in}.
-     */
-    private void loadFrom(InputStream in) throws IOException {
-        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
-        byte[] buffer = new byte[8192];
-
-        int count;
-        while ((count = in.read(buffer)) != -1) {
-            bytesOut.write(buffer, 0, count);
-        }
-
-        this.data = ByteBuffer.wrap(bytesOut.toByteArray());
-        this.data.order(ByteOrder.LITTLE_ENDIAN);
-        this.tableOfContents.readFrom(this);
-    }
-
-    private static void checkBounds(int index, int length) {
-        if (index < 0 || index >= length) {
-            throw new IndexOutOfBoundsException("index:" + index + ", length=" + length);
-        }
-    }
-
-    public void writeTo(OutputStream out) throws IOException {
-        byte[] buffer = new byte[8192];
-        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
-        data.clear();
-        while (data.hasRemaining()) {
-            int count = Math.min(buffer.length, data.remaining());
-            data.get(buffer, 0, count);
-            out.write(buffer, 0, count);
-        }
-    }
-
-    public void writeTo(File dexOut) throws IOException {
-        try (OutputStream out = new FileOutputStream(dexOut)) {
-            writeTo(out);
-        }
-    }
-
-    public TableOfContents getTableOfContents() {
-        return tableOfContents;
-    }
-
-    public Section open(int position) {
-        if (position < 0 || position >= data.capacity()) {
-            throw new IllegalArgumentException("position=" + position
-                    + " length=" + data.capacity());
-        }
-        ByteBuffer sectionData = data.duplicate();
-        sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
-        sectionData.position(position);
-        sectionData.limit(data.capacity());
-        return new Section("section", sectionData);
-    }
-
-    public Section appendSection(int maxByteCount, String name) {
-        if ((maxByteCount & 3) != 0) {
-            throw new IllegalStateException("Not four byte aligned!");
-        }
-        int limit = nextSectionStart + maxByteCount;
-        ByteBuffer sectionData = data.duplicate();
-        sectionData.order(ByteOrder.LITTLE_ENDIAN); // necessary?
-        sectionData.position(nextSectionStart);
-        sectionData.limit(limit);
-        Section result = new Section(name, sectionData);
-        nextSectionStart = limit;
-        return result;
-    }
-
-    public int getLength() {
-        return data.capacity();
-    }
-
-    public int getNextSectionStart() {
-        return nextSectionStart;
-    }
-
-    /**
-     * Returns a copy of the the bytes of this dex.
-     */
-    public byte[] getBytes() {
-        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
-        byte[] result = new byte[data.capacity()];
-        data.position(0);
-        data.get(result);
-        return result;
-    }
-
-    public List<String> strings() {
-        return strings;
-    }
-
-    public List<Integer> typeIds() {
-        return typeIds;
-    }
-
-    public List<String> typeNames() {
-        return typeNames;
-    }
-
-    public List<ProtoId> protoIds() {
-        return protoIds;
-    }
-
-    public List<FieldId> fieldIds() {
-        return fieldIds;
-    }
-
-    public List<MethodId> methodIds() {
-        return methodIds;
-    }
-
-    public Iterable<ClassDef> classDefs() {
-        return new ClassDefIterable();
-    }
-
-    public TypeList readTypeList(int offset) {
-        if (offset == 0) {
-            return TypeList.EMPTY;
-        }
-        return open(offset).readTypeList();
-    }
-
-    public ClassData readClassData(ClassDef classDef) {
-        int offset = classDef.getClassDataOffset();
-        if (offset == 0) {
-            throw new IllegalArgumentException("offset == 0");
-        }
-        return open(offset).readClassData();
-    }
-
-    public Code readCode(ClassData.Method method) {
-        int offset = method.getCodeOffset();
-        if (offset == 0) {
-            throw new IllegalArgumentException("offset == 0");
-        }
-        return open(offset).readCode();
-    }
-
-    /**
-     * Returns the signature of all but the first 32 bytes of this dex. The
-     * first 32 bytes of dex files are not specified to be included in the
-     * signature.
-     */
-    public byte[] computeSignature() throws IOException {
-        MessageDigest digest;
-        try {
-            digest = MessageDigest.getInstance("SHA-1");
-        } catch (NoSuchAlgorithmException e) {
-            throw new AssertionError();
-        }
-        byte[] buffer = new byte[8192];
-        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
-        data.limit(data.capacity());
-        data.position(SIGNATURE_OFFSET + SIGNATURE_SIZE);
-        while (data.hasRemaining()) {
-            int count = Math.min(buffer.length, data.remaining());
-            data.get(buffer, 0, count);
-            digest.update(buffer, 0, count);
-        }
-        return digest.digest();
-    }
-
-    /**
-     * Returns the checksum of all but the first 12 bytes of {@code dex}.
-     */
-    public int computeChecksum() throws IOException {
-        Adler32 adler32 = new Adler32();
-        byte[] buffer = new byte[8192];
-        ByteBuffer data = this.data.duplicate(); // positioned ByteBuffers aren't thread safe
-        data.limit(data.capacity());
-        data.position(CHECKSUM_OFFSET + CHECKSUM_SIZE);
-        while (data.hasRemaining()) {
-            int count = Math.min(buffer.length, data.remaining());
-            data.get(buffer, 0, count);
-            adler32.update(buffer, 0, count);
-        }
-        return (int) adler32.getValue();
-    }
-
-    /**
-     * Generates the signature and checksum of the dex file {@code out} and
-     * writes them to the file.
-     */
-    public void writeHashes() throws IOException {
-        open(SIGNATURE_OFFSET).write(computeSignature());
-        open(CHECKSUM_OFFSET).writeInt(computeChecksum());
-    }
-
-    /**
-     * Look up a field id name index from a field index. Cheaper than:
-     * {@code fieldIds().get(fieldDexIndex).getNameIndex();}
-     */
-    public int nameIndexFromFieldIndex(int fieldIndex) {
-        checkBounds(fieldIndex, tableOfContents.fieldIds.size);
-        int position = tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * fieldIndex);
-        position += SizeOf.USHORT;  // declaringClassIndex
-        position += SizeOf.USHORT;  // typeIndex
-        return data.getInt(position);  // nameIndex
-    }
-
-    /**
-     * Look up a method id name index from a method index. Cheaper than:
-     * {@code methodIds().get(methodIndex).getNameIndex();}
-     */
-    public int nameIndexFromMethodIndex(int methodIndex) {
-        checkBounds(methodIndex, tableOfContents.methodIds.size);
-        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
-        position += SizeOf.USHORT;  // declaringClassIndex
-        position += SizeOf.USHORT;  // protoIndex
-        return data.getInt(position);  // nameIndex
-    }
-
-    /**
-     * Look up a parameter type ids from a method index. Cheaper than:
-     * {@code readTypeList(protoIds.get(methodIds().get(methodDexIndex).getProtoIndex()).getParametersOffset()).getTypes();}
-     */
-    public short[] parameterTypeIndicesFromMethodIndex(int methodIndex) {
-        checkBounds(methodIndex, tableOfContents.methodIds.size);
-        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
-        position += SizeOf.USHORT;  // declaringClassIndex
-        int protoIndex = data.getShort(position) & 0xFFFF;
-        checkBounds(protoIndex, tableOfContents.protoIds.size);
-        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);
-        position += SizeOf.UINT;  // shortyIndex
-        position += SizeOf.UINT;  // returnTypeIndex
-        int parametersOffset = data.getInt(position);
-        if (parametersOffset == 0) {
-            return EMPTY_SHORT_ARRAY;
-        }
-        position = parametersOffset;
-        int size = data.getInt(position);
-        if (size <= 0) {
-            throw new AssertionError("Unexpected parameter type list size: " + size);
-        }
-        position += SizeOf.UINT;
-        short[] types = new short[size];
-        for (int i = 0; i < size; i++) {
-            types[i] = data.getShort(position);
-            position += SizeOf.USHORT;
-        }
-        return types;
-    }
-
-    /**
-     * Look up a method id return type index from a method index. Cheaper than:
-     * {@code protoIds().get(methodIds().get(methodDexIndex).getProtoIndex()).getReturnTypeIndex();}
-     */
-    public int returnTypeIndexFromMethodIndex(int methodIndex) {
-        checkBounds(methodIndex, tableOfContents.methodIds.size);
-        int position = tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * methodIndex);
-        position += SizeOf.USHORT;  // declaringClassIndex
-        int protoIndex = data.getShort(position) & 0xFFFF;
-        checkBounds(protoIndex, tableOfContents.protoIds.size);
-        position = tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * protoIndex);
-        position += SizeOf.UINT;  // shortyIndex
-        return data.getInt(position);  // returnTypeIndex
-    }
-
-    /**
-     * Look up a descriptor index from a type index. Cheaper than:
-     * {@code open(tableOfContents.typeIds.off + (index * SizeOf.TYPE_ID_ITEM)).readInt();}
-     */
-    public int descriptorIndexFromTypeIndex(int typeIndex) {
-       checkBounds(typeIndex, tableOfContents.typeIds.size);
-       int position = tableOfContents.typeIds.off + (SizeOf.TYPE_ID_ITEM * typeIndex);
-       return data.getInt(position);
-    }
-
-    /**
-     * Look up interface types indices from a  return type index from a method index. Cheaper than:
-     * {@code ...getClassDef(classDefIndex).getInterfaces();}
-     */
-    public short[] interfaceTypeIndicesFromClassDefIndex(int classDefIndex) {
-        checkBounds(classDefIndex, tableOfContents.classDefs.size);
-        int position = tableOfContents.classDefs.off + (SizeOf.CLASS_DEF_ITEM * classDefIndex);
-        position += SizeOf.UINT;  // type
-        position += SizeOf.UINT;  // accessFlags
-        position += SizeOf.UINT;  // superType
-        int interfacesOffset = data.getInt(position);
-        if (interfacesOffset == 0) {
-            return EMPTY_SHORT_ARRAY;
-        }
-        position = interfacesOffset;
-        int size = data.getInt(position);
-        if (size <= 0) {
-            throw new AssertionError("Unexpected interfaces list size: " + size);
-        }
-        position += SizeOf.UINT;
-        short[] types = new short[size];
-        for (int i = 0; i < size; i++) {
-            types[i] = data.getShort(position);
-            position += SizeOf.USHORT;
-        }
-        return types;
-    }
-
-    public final class Section implements ByteInput, ByteOutput {
-        private final String name;
-        private final ByteBuffer data;
-        private final int initialPosition;
-
-        private Section(String name, ByteBuffer data) {
-            this.name = name;
-            this.data = data;
-            this.initialPosition = data.position();
-        }
-
-        public int getPosition() {
-            return data.position();
-        }
-
-        public int readInt() {
-            return data.getInt();
-        }
-
-        public short readShort() {
-            return data.getShort();
-        }
-
-        public int readUnsignedShort() {
-            return readShort() & 0xffff;
-        }
-
-        public byte readByte() {
-            return data.get();
-        }
-
-        public byte[] readByteArray(int length) {
-            byte[] result = new byte[length];
-            data.get(result);
-            return result;
-        }
-
-        public short[] readShortArray(int length) {
-            if (length == 0) {
-                return EMPTY_SHORT_ARRAY;
-            }
-            short[] result = new short[length];
-            for (int i = 0; i < length; i++) {
-                result[i] = readShort();
-            }
-            return result;
-        }
-
-        public int readUleb128() {
-            return Leb128.readUnsignedLeb128(this);
-        }
-
-        public int readUleb128p1() {
-            return Leb128.readUnsignedLeb128(this) - 1;
-        }
-
-        public int readSleb128() {
-            return Leb128.readSignedLeb128(this);
-        }
-
-        public void writeUleb128p1(int i) {
-            writeUleb128(i + 1);
-        }
-
-        public TypeList readTypeList() {
-            int size = readInt();
-            short[] types = readShortArray(size);
-            alignToFourBytes();
-            return new TypeList(Dex.this, types);
-        }
-
-        public String readString() {
-            int offset = readInt();
-            int savedPosition = data.position();
-            int savedLimit = data.limit();
-            data.position(offset);
-            data.limit(data.capacity());
-            try {
-                int expectedLength = readUleb128();
-                String result = Mutf8.decode(this, new char[expectedLength]);
-                if (result.length() != expectedLength) {
-                    throw new DexException("Declared length " + expectedLength
-                            + " doesn't match decoded length of " + result.length());
-                }
-                return result;
-            } catch (UTFDataFormatException e) {
-                throw new DexException(e);
-            } finally {
-                data.position(savedPosition);
-                data.limit(savedLimit);
-            }
-        }
-
-        public FieldId readFieldId() {
-            int declaringClassIndex = readUnsignedShort();
-            int typeIndex = readUnsignedShort();
-            int nameIndex = readInt();
-            return new FieldId(Dex.this, declaringClassIndex, typeIndex, nameIndex);
-        }
-
-        public MethodId readMethodId() {
-            int declaringClassIndex = readUnsignedShort();
-            int protoIndex = readUnsignedShort();
-            int nameIndex = readInt();
-            return new MethodId(Dex.this, declaringClassIndex, protoIndex, nameIndex);
-        }
-
-        public ProtoId readProtoId() {
-            int shortyIndex = readInt();
-            int returnTypeIndex = readInt();
-            int parametersOffset = readInt();
-            return new ProtoId(Dex.this, shortyIndex, returnTypeIndex, parametersOffset);
-        }
-
-        public ClassDef readClassDef() {
-            int offset = getPosition();
-            int type = readInt();
-            int accessFlags = readInt();
-            int supertype = readInt();
-            int interfacesOffset = readInt();
-            int sourceFileIndex = readInt();
-            int annotationsOffset = readInt();
-            int classDataOffset = readInt();
-            int staticValuesOffset = readInt();
-            return new ClassDef(Dex.this, offset, type, accessFlags, supertype,
-                    interfacesOffset, sourceFileIndex, annotationsOffset, classDataOffset,
-                    staticValuesOffset);
-        }
-
-        private Code readCode() {
-            int registersSize = readUnsignedShort();
-            int insSize = readUnsignedShort();
-            int outsSize = readUnsignedShort();
-            int triesSize = readUnsignedShort();
-            int debugInfoOffset = readInt();
-            int instructionsSize = readInt();
-            short[] instructions = readShortArray(instructionsSize);
-            Try[] tries;
-            CatchHandler[] catchHandlers;
-            if (triesSize > 0) {
-                if (instructions.length % 2 == 1) {
-                    readShort(); // padding
-                }
-
-                /*
-                 * We can't read the tries until we've read the catch handlers.
-                 * Unfortunately they're in the opposite order in the dex file
-                 * so we need to read them out-of-order.
-                 */
-                Section triesSection = open(data.position());
-                skip(triesSize * SizeOf.TRY_ITEM);
-                catchHandlers = readCatchHandlers();
-                tries = triesSection.readTries(triesSize, catchHandlers);
-            } else {
-                tries = new Try[0];
-                catchHandlers = new CatchHandler[0];
-            }
-            return new Code(registersSize, insSize, outsSize, debugInfoOffset, instructions,
-                            tries, catchHandlers);
-        }
-
-        private CatchHandler[] readCatchHandlers() {
-            int baseOffset = data.position();
-            int catchHandlersSize = readUleb128();
-            CatchHandler[] result = new CatchHandler[catchHandlersSize];
-            for (int i = 0; i < catchHandlersSize; i++) {
-                int offset = data.position() - baseOffset;
-                result[i] = readCatchHandler(offset);
-            }
-            return result;
-        }
-
-        private Try[] readTries(int triesSize, CatchHandler[] catchHandlers) {
-            Try[] result = new Try[triesSize];
-            for (int i = 0; i < triesSize; i++) {
-                int startAddress = readInt();
-                int instructionCount = readUnsignedShort();
-                int handlerOffset = readUnsignedShort();
-                int catchHandlerIndex = findCatchHandlerIndex(catchHandlers, handlerOffset);
-                result[i] = new Try(startAddress, instructionCount, catchHandlerIndex);
-            }
-            return result;
-        }
-
-        private int findCatchHandlerIndex(CatchHandler[] catchHandlers, int offset) {
-            for (int i = 0; i < catchHandlers.length; i++) {
-                CatchHandler catchHandler = catchHandlers[i];
-                if (catchHandler.getOffset() == offset) {
-                    return i;
-                }
-            }
-            throw new IllegalArgumentException();
-        }
-
-        private CatchHandler readCatchHandler(int offset) {
-            int size = readSleb128();
-            int handlersCount = Math.abs(size);
-            int[] typeIndexes = new int[handlersCount];
-            int[] addresses = new int[handlersCount];
-            for (int i = 0; i < handlersCount; i++) {
-                typeIndexes[i] = readUleb128();
-                addresses[i] = readUleb128();
-            }
-            int catchAllAddress = size <= 0 ? readUleb128() : -1;
-            return new CatchHandler(typeIndexes, addresses, catchAllAddress, offset);
-        }
-
-        private ClassData readClassData() {
-            int staticFieldsSize = readUleb128();
-            int instanceFieldsSize = readUleb128();
-            int directMethodsSize = readUleb128();
-            int virtualMethodsSize = readUleb128();
-            ClassData.Field[] staticFields = readFields(staticFieldsSize);
-            ClassData.Field[] instanceFields = readFields(instanceFieldsSize);
-            ClassData.Method[] directMethods = readMethods(directMethodsSize);
-            ClassData.Method[] virtualMethods = readMethods(virtualMethodsSize);
-            return new ClassData(staticFields, instanceFields, directMethods, virtualMethods);
-        }
-
-        private ClassData.Field[] readFields(int count) {
-            ClassData.Field[] result = new ClassData.Field[count];
-            int fieldIndex = 0;
-            for (int i = 0; i < count; i++) {
-                fieldIndex += readUleb128(); // field index diff
-                int accessFlags = readUleb128();
-                result[i] = new ClassData.Field(fieldIndex, accessFlags);
-            }
-            return result;
-        }
-
-        private ClassData.Method[] readMethods(int count) {
-            ClassData.Method[] result = new ClassData.Method[count];
-            int methodIndex = 0;
-            for (int i = 0; i < count; i++) {
-                methodIndex += readUleb128(); // method index diff
-                int accessFlags = readUleb128();
-                int codeOff = readUleb128();
-                result[i] = new ClassData.Method(methodIndex, accessFlags, codeOff);
-            }
-            return result;
-        }
-
-        /**
-         * Returns a byte array containing the bytes from {@code start} to this
-         * section's current position.
-         */
-        private byte[] getBytesFrom(int start) {
-            int end = data.position();
-            byte[] result = new byte[end - start];
-            data.position(start);
-            data.get(result);
-            return result;
-        }
-
-        public Annotation readAnnotation() {
-            byte visibility = readByte();
-            int start = data.position();
-            new EncodedValueReader(this, EncodedValueReader.ENCODED_ANNOTATION).skipValue();
-            return new Annotation(Dex.this, visibility, new EncodedValue(getBytesFrom(start)));
-        }
-
-        public EncodedValue readEncodedArray() {
-            int start = data.position();
-            new EncodedValueReader(this, EncodedValueReader.ENCODED_ARRAY).skipValue();
-            return new EncodedValue(getBytesFrom(start));
-        }
-
-        public void skip(int count) {
-            if (count < 0) {
-                throw new IllegalArgumentException();
-            }
-            data.position(data.position() + count);
-        }
-
-        /**
-         * Skips bytes until the position is aligned to a multiple of 4.
-         */
-        public void alignToFourBytes() {
-            data.position((data.position() + 3) & ~3);
-        }
-
-        /**
-         * Writes 0x00 until the position is aligned to a multiple of 4.
-         */
-        public void alignToFourBytesWithZeroFill() {
-            while ((data.position() & 3) != 0) {
-                data.put((byte) 0);
-            }
-        }
-
-        public void assertFourByteAligned() {
-            if ((data.position() & 3) != 0) {
-                throw new IllegalStateException("Not four byte aligned!");
-            }
-        }
-
-        public void write(byte[] bytes) {
-            this.data.put(bytes);
-        }
-
-        public void writeByte(int b) {
-            data.put((byte) b);
-        }
-
-        public void writeShort(short i) {
-            data.putShort(i);
-        }
-
-        public void writeUnsignedShort(int i) {
-            short s = (short) i;
-            if (i != (s & 0xffff)) {
-                throw new IllegalArgumentException("Expected an unsigned short: " + i);
-            }
-            writeShort(s);
-        }
-
-        public void write(short[] shorts) {
-            for (short s : shorts) {
-                writeShort(s);
-            }
-        }
-
-        public void writeInt(int i) {
-            data.putInt(i);
-        }
-
-        public void writeUleb128(int i) {
-            try {
-                Leb128.writeUnsignedLeb128(this, i);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
-            }
-        }
-
-        public void writeSleb128(int i) {
-            try {
-                Leb128.writeSignedLeb128(this, i);
-            } catch (ArrayIndexOutOfBoundsException e) {
-                throw new DexException("Section limit " + data.limit() + " exceeded by " + name);
-            }
-        }
-
-        public void writeStringData(String value) {
-            try {
-                int length = value.length();
-                writeUleb128(length);
-                write(Mutf8.encode(value));
-                writeByte(0);
-            } catch (UTFDataFormatException e) {
-                throw new AssertionError();
-            }
-        }
-
-        public void writeTypeList(TypeList typeList) {
-            short[] types = typeList.getTypes();
-            writeInt(types.length);
-            for (short type : types) {
-                writeShort(type);
-            }
-            alignToFourBytesWithZeroFill();
-        }
-
-        /**
-         * Returns the number of bytes used by this section.
-         */
-        public int used() {
-            return data.position() - initialPosition;
-        }
-    }
-
-    private final class StringTable extends AbstractList<String> implements RandomAccess {
-        @Override public String get(int index) {
-            checkBounds(index, tableOfContents.stringIds.size);
-            return open(tableOfContents.stringIds.off + (index * SizeOf.STRING_ID_ITEM))
-                    .readString();
-        }
-        @Override public int size() {
-            return tableOfContents.stringIds.size;
-        }
-    }
-
-    private final class TypeIndexToDescriptorIndexTable extends AbstractList<Integer>
-            implements RandomAccess {
-        @Override public Integer get(int index) {
-            return descriptorIndexFromTypeIndex(index);
-        }
-        @Override public int size() {
-            return tableOfContents.typeIds.size;
-        }
-    }
-
-    private final class TypeIndexToDescriptorTable extends AbstractList<String>
-            implements RandomAccess {
-        @Override public String get(int index) {
-            return strings.get(descriptorIndexFromTypeIndex(index));
-        }
-        @Override public int size() {
-            return tableOfContents.typeIds.size;
-        }
-    }
-
-    private final class ProtoIdTable extends AbstractList<ProtoId> implements RandomAccess {
-        @Override public ProtoId get(int index) {
-            checkBounds(index, tableOfContents.protoIds.size);
-            return open(tableOfContents.protoIds.off + (SizeOf.PROTO_ID_ITEM * index))
-                    .readProtoId();
-        }
-        @Override public int size() {
-            return tableOfContents.protoIds.size;
-        }
-    }
-
-    private final class FieldIdTable extends AbstractList<FieldId> implements RandomAccess {
-        @Override public FieldId get(int index) {
-            checkBounds(index, tableOfContents.fieldIds.size);
-            return open(tableOfContents.fieldIds.off + (SizeOf.MEMBER_ID_ITEM * index))
-                    .readFieldId();
-        }
-        @Override public int size() {
-            return tableOfContents.fieldIds.size;
-        }
-    }
-
-    private final class MethodIdTable extends AbstractList<MethodId> implements RandomAccess {
-        @Override public MethodId get(int index) {
-            checkBounds(index, tableOfContents.methodIds.size);
-            return open(tableOfContents.methodIds.off + (SizeOf.MEMBER_ID_ITEM * index))
-                    .readMethodId();
-        }
-        @Override public int size() {
-            return tableOfContents.methodIds.size;
-        }
-    }
-
-    private final class ClassDefIterator implements Iterator<ClassDef> {
-        private final Dex.Section in = open(tableOfContents.classDefs.off);
-        private int count = 0;
-
-        @Override
-        public boolean hasNext() {
-            return count < tableOfContents.classDefs.size;
-        }
-        @Override
-        public ClassDef next() {
-            if (!hasNext()) {
-                throw new NoSuchElementException();
-            }
-            count++;
-            return in.readClassDef();
-        }
-        @Override
-            public void remove() {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    private final class ClassDefIterable implements Iterable<ClassDef> {
-        public Iterator<ClassDef> iterator() {
-            return !tableOfContents.classDefs.exists()
-               ? Collections.<ClassDef>emptySet().iterator()
-               : new ClassDefIterator();
-        }
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/DexException.java b/dex/src/main/java/com/android/dex/DexException.java
deleted file mode 100644
index ee0af18..0000000
--- a/dex/src/main/java/com/android/dex/DexException.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.ExceptionWithContext;
-
-/**
- * Thrown when there's a format problem reading, writing, or generally
- * processing a dex file.
- */
-public class DexException extends ExceptionWithContext {
-    public DexException(String message) {
-        super(message);
-    }
-
-    public DexException(Throwable cause) {
-        super(cause);
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/DexFormat.java b/dex/src/main/java/com/android/dex/DexFormat.java
deleted file mode 100644
index 97771d8..0000000
--- a/dex/src/main/java/com/android/dex/DexFormat.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-/**
- * Constants that show up in and are otherwise related to {@code .dex}
- * files, and helper methods for same.
- */
-public final class DexFormat {
-    private DexFormat() {}
-
-    /** API level to target in order to generate invoke-polymorphic */
-    public static final int API_INVOKE_POLYMORPHIC = 26;
-
-    /** API level to target in order to pass through default and static interface methods */
-    public static final int API_DEFAULT_INTERFACE_METHODS = 24;
-
-    /** API level to target in order to suppress extended opcode usage */
-    public static final int API_NO_EXTENDED_OPCODES = 13;
-
-    /**
-     * API level to target in order to produce the most modern file
-     * format
-     */
-    public static final int API_CURRENT = API_INVOKE_POLYMORPHIC;
-
-    /** dex file version number for API level 26 and earlier */
-    public static final String VERSION_FOR_API_26 = "038";
-
-    /** dex file version number for API level 24 and earlier */
-    public static final String VERSION_FOR_API_24 = "037";
-
-    /** dex file version number for API level 13 and earlier */
-    public static final String VERSION_FOR_API_13 = "035";
-
-    /**
-     * Dex file version number for dalvik.
-     * <p>
-     * Note: Dex version 36 was loadable in some versions of Dalvik but was never fully supported or
-     * completed and is not considered a valid dex file format.
-     * </p>
-     */
-    public static final String VERSION_CURRENT = VERSION_FOR_API_26;
-
-    /**
-     * file name of the primary {@code .dex} file inside an
-     * application or library {@code .jar} file
-     */
-    public static final String DEX_IN_JAR_NAME = "classes.dex";
-
-    /** common prefix for all dex file "magic numbers" */
-    public static final String MAGIC_PREFIX = "dex\n";
-
-    /** common suffix for all dex file "magic numbers" */
-    public static final String MAGIC_SUFFIX = "\0";
-
-    /**
-     * value used to indicate endianness of file contents
-     */
-    public static final int ENDIAN_TAG = 0x12345678;
-
-    /**
-     * Maximum addressable field or method index.
-     * The largest addressable member is 0xffff, in the "instruction formats" spec as field@CCCC or
-     * meth@CCCC.
-     */
-    public static final int MAX_MEMBER_IDX = 0xFFFF;
-
-    /**
-     * Maximum addressable type index.
-     * The largest addressable type is 0xffff, in the "instruction formats" spec as type@CCCC.
-     */
-    public static final int MAX_TYPE_IDX = 0xFFFF;
-
-    /**
-     * Returns the API level corresponding to the given magic number,
-     * or {@code -1} if the given array is not a well-formed dex file
-     * magic number.
-     */
-    public static int magicToApi(byte[] magic) {
-        if (magic.length != 8) {
-            return -1;
-        }
-
-        if ((magic[0] != 'd') || (magic[1] != 'e') || (magic[2] != 'x') || (magic[3] != '\n') ||
-                (magic[7] != '\0')) {
-            return -1;
-        }
-
-        String version = "" + ((char) magic[4]) + ((char) magic[5]) +((char) magic[6]);
-
-        if (version.equals(VERSION_FOR_API_13)) {
-            return API_NO_EXTENDED_OPCODES;
-        } else if (version.equals(VERSION_FOR_API_24)) {
-            return API_DEFAULT_INTERFACE_METHODS;
-        } else if (version.equals(VERSION_FOR_API_26)) {
-            return API_INVOKE_POLYMORPHIC;
-        } else if (version.equals(VERSION_CURRENT)) {
-            return API_CURRENT;
-        }
-
-        return -1;
-    }
-
-    /**
-     * Returns the magic number corresponding to the given target API level.
-     */
-    public static String apiToMagic(int targetApiLevel) {
-        String version;
-
-        if (targetApiLevel >= API_CURRENT) {
-            version = VERSION_CURRENT;
-        } else if (targetApiLevel >= API_INVOKE_POLYMORPHIC) {
-            version = VERSION_FOR_API_26;
-        } else if (targetApiLevel >= API_DEFAULT_INTERFACE_METHODS) {
-            version = VERSION_FOR_API_24;
-        } else {
-            version = VERSION_FOR_API_13;
-        }
-
-        return MAGIC_PREFIX + version + MAGIC_SUFFIX;
-    }
-
-    public static boolean isSupportedDexMagic(byte[] magic) {
-        int api = magicToApi(magic);
-        return api > 0;
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java b/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
deleted file mode 100644
index 3226207..0000000
--- a/dex/src/main/java/com/android/dex/DexIndexOverflowException.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2013 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 com.android.dex;
-
-/**
- * Thrown when there's an index overflow writing a dex file.
- */
-public final class DexIndexOverflowException extends DexException {
-    public DexIndexOverflowException(String message) {
-        super(message);
-    }
-
-    public DexIndexOverflowException(Throwable cause) {
-        super(cause);
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValue.java b/dex/src/main/java/com/android/dex/EncodedValue.java
deleted file mode 100644
index 8d0c3ad..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValue.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.ByteArrayByteInput;
-import com.android.dex.util.ByteInput;
-
-/**
- * An encoded value or array.
- */
-public final class EncodedValue implements Comparable<EncodedValue> {
-    private final byte[] data;
-
-    public EncodedValue(byte[] data) {
-        this.data = data;
-    }
-
-    public ByteInput asByteInput() {
-        return new ByteArrayByteInput(data);
-    }
-
-    public byte[] getBytes() {
-        return data;
-    }
-
-    public void writeTo(Dex.Section out) {
-        out.write(data);
-    }
-
-    @Override public int compareTo(EncodedValue other) {
-        int size = Math.min(data.length, other.data.length);
-        for (int i = 0; i < size; i++) {
-            if (data[i] != other.data[i]) {
-                return (data[i] & 0xff) - (other.data[i] & 0xff);
-            }
-        }
-        return data.length - other.data.length;
-    }
-
-    @Override public String toString() {
-        return Integer.toHexString(data[0] & 0xff) + "...(" + data.length + ")";
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValueCodec.java b/dex/src/main/java/com/android/dex/EncodedValueCodec.java
deleted file mode 100644
index 7fc1724..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValueCodec.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-
-/**
- * Read and write {@code encoded_value} primitives.
- */
-public final class EncodedValueCodec {
-    private EncodedValueCodec() {
-    }
-
-    /**
-     * Writes a signed integral to {@code out}.
-     */
-    public static void writeSignedIntegralValue(ByteOutput out, int type, long value) {
-        /*
-         * Figure out how many bits are needed to represent the value,
-         * including a sign bit: The bit count is subtracted from 65
-         * and not 64 to account for the sign bit. The xor operation
-         * has the effect of leaving non-negative values alone and
-         * unary complementing negative values (so that a leading zero
-         * count always returns a useful number for our present
-         * purpose).
-         */
-        int requiredBits = 65 - Long.numberOfLeadingZeros(value ^ (value >> 63));
-
-        // Round up the requiredBits to a number of bytes.
-        int requiredBytes = (requiredBits + 0x07) >> 3;
-
-        /*
-         * Write the header byte, which includes the type and
-         * requiredBytes - 1.
-         */
-        out.writeByte(type | ((requiredBytes - 1) << 5));
-
-        // Write the value, per se.
-        while (requiredBytes > 0) {
-            out.writeByte((byte) value);
-            value >>= 8;
-            requiredBytes--;
-        }
-    }
-
-    /**
-     * Writes an unsigned integral to {@code out}.
-     */
-    public static void writeUnsignedIntegralValue(ByteOutput out, int type, long value) {
-        // Figure out how many bits are needed to represent the value.
-        int requiredBits = 64 - Long.numberOfLeadingZeros(value);
-        if (requiredBits == 0) {
-            requiredBits = 1;
-        }
-
-        // Round up the requiredBits to a number of bytes.
-        int requiredBytes = (requiredBits + 0x07) >> 3;
-
-        /*
-         * Write the header byte, which includes the type and
-         * requiredBytes - 1.
-         */
-        out.writeByte(type | ((requiredBytes - 1) << 5));
-
-        // Write the value, per se.
-        while (requiredBytes > 0) {
-            out.writeByte((byte) value);
-            value >>= 8;
-            requiredBytes--;
-        }
-    }
-
-    /**
-     * Writes a right-zero-extended value to {@code out}.
-     */
-    public static void writeRightZeroExtendedValue(ByteOutput out, int type, long value) {
-        // Figure out how many bits are needed to represent the value.
-        int requiredBits = 64 - Long.numberOfTrailingZeros(value);
-        if (requiredBits == 0) {
-            requiredBits = 1;
-        }
-
-        // Round up the requiredBits to a number of bytes.
-        int requiredBytes = (requiredBits + 0x07) >> 3;
-
-        // Scootch the first bits to be written down to the low-order bits.
-        value >>= 64 - (requiredBytes * 8);
-
-        /*
-         * Write the header byte, which includes the type and
-         * requiredBytes - 1.
-         */
-        out.writeByte(type | ((requiredBytes - 1) << 5));
-
-        // Write the value, per se.
-        while (requiredBytes > 0) {
-            out.writeByte((byte) value);
-            value >>= 8;
-            requiredBytes--;
-        }
-    }
-
-    /**
-     * Read a signed integer.
-     *
-     * @param zwidth byte count minus one
-     */
-    public static int readSignedInt(ByteInput in, int zwidth) {
-        int result = 0;
-        for (int i = zwidth; i >= 0; i--) {
-            result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
-        }
-        result >>= (3 - zwidth) * 8;
-        return result;
-    }
-
-    /**
-     * Read an unsigned integer.
-     *
-     * @param zwidth byte count minus one
-     * @param fillOnRight true to zero fill on the right; false on the left
-     */
-    public static int readUnsignedInt(ByteInput in, int zwidth, boolean fillOnRight) {
-        int result = 0;
-        if (!fillOnRight) {
-            for (int i = zwidth; i >= 0; i--) {
-                result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
-            }
-            result >>>= (3 - zwidth) * 8;
-        } else {
-            for (int i = zwidth; i >= 0; i--) {
-                result = (result >>> 8) | ((in.readByte() & 0xff) << 24);
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Read a signed long.
-     *
-     * @param zwidth byte count minus one
-     */
-    public static long readSignedLong(ByteInput in, int zwidth) {
-        long result = 0;
-        for (int i = zwidth; i >= 0; i--) {
-            result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
-        }
-        result >>= (7 - zwidth) * 8;
-        return result;
-    }
-
-    /**
-     * Read an unsigned long.
-     *
-     * @param zwidth byte count minus one
-     * @param fillOnRight true to zero fill on the right; false on the left
-     */
-    public static long readUnsignedLong(ByteInput in, int zwidth, boolean fillOnRight) {
-        long result = 0;
-        if (!fillOnRight) {
-            for (int i = zwidth; i >= 0; i--) {
-                result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
-            }
-            result >>>= (7 - zwidth) * 8;
-        } else {
-            for (int i = zwidth; i >= 0; i--) {
-                result = (result >>> 8) | ((in.readByte() & 0xffL) << 56);
-            }
-        }
-        return result;
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/EncodedValueReader.java b/dex/src/main/java/com/android/dex/EncodedValueReader.java
deleted file mode 100644
index 6f60538..0000000
--- a/dex/src/main/java/com/android/dex/EncodedValueReader.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-
-/**
- * Pull parser for encoded values.
- */
-public final class EncodedValueReader {
-    public static final int ENCODED_BYTE = 0x00;
-    public static final int ENCODED_SHORT = 0x02;
-    public static final int ENCODED_CHAR = 0x03;
-    public static final int ENCODED_INT = 0x04;
-    public static final int ENCODED_LONG = 0x06;
-    public static final int ENCODED_FLOAT = 0x10;
-    public static final int ENCODED_DOUBLE = 0x11;
-    public static final int ENCODED_STRING = 0x17;
-    public static final int ENCODED_TYPE = 0x18;
-    public static final int ENCODED_FIELD = 0x19;
-    public static final int ENCODED_ENUM = 0x1b;
-    public static final int ENCODED_METHOD = 0x1a;
-    public static final int ENCODED_ARRAY = 0x1c;
-    public static final int ENCODED_ANNOTATION = 0x1d;
-    public static final int ENCODED_NULL = 0x1e;
-    public static final int ENCODED_BOOLEAN = 0x1f;
-
-    /** placeholder type if the type is not yet known */
-    private static final int MUST_READ = -1;
-
-    protected final ByteInput in;
-    private int type = MUST_READ;
-    private int annotationType;
-    private int arg;
-
-    public EncodedValueReader(ByteInput in) {
-        this.in = in;
-    }
-
-    public EncodedValueReader(EncodedValue in) {
-        this(in.asByteInput());
-    }
-
-    /**
-     * Creates a new encoded value reader whose only value is the specified
-     * known type. This is useful for encoded values without a type prefix,
-     * such as class_def_item's encoded_array or annotation_item's
-     * encoded_annotation.
-     */
-    public EncodedValueReader(ByteInput in, int knownType) {
-        this.in = in;
-        this.type = knownType;
-    }
-
-    public EncodedValueReader(EncodedValue in, int knownType) {
-        this(in.asByteInput(), knownType);
-    }
-
-    /**
-     * Returns the type of the next value to read.
-     */
-    public int peek() {
-        if (type == MUST_READ) {
-            int argAndType = in.readByte() & 0xff;
-            type = argAndType & 0x1f;
-            arg = (argAndType & 0xe0) >> 5;
-        }
-        return type;
-    }
-
-    /**
-     * Begins reading the elements of an array, returning the array's size. The
-     * caller must follow up by calling a read method for each element in the
-     * array. For example, this reads a byte array: <pre>   {@code
-     *   int arraySize = readArray();
-     *   for (int i = 0, i < arraySize; i++) {
-     *     readByte();
-     *   }
-     * }</pre>
-     */
-    public int readArray() {
-        checkType(ENCODED_ARRAY);
-        type = MUST_READ;
-        return Leb128.readUnsignedLeb128(in);
-    }
-
-    /**
-     * Begins reading the fields of an annotation, returning the number of
-     * fields. The caller must follow up by making alternating calls to {@link
-     * #readAnnotationName()} and another read method. For example, this reads
-     * an annotation whose fields are all bytes: <pre>   {@code
-     *   int fieldCount = readAnnotation();
-     *   int annotationType = getAnnotationType();
-     *   for (int i = 0; i < fieldCount; i++) {
-     *       readAnnotationName();
-     *       readByte();
-     *   }
-     * }</pre>
-     */
-    public int readAnnotation() {
-        checkType(ENCODED_ANNOTATION);
-        type = MUST_READ;
-        annotationType = Leb128.readUnsignedLeb128(in);
-        return Leb128.readUnsignedLeb128(in);
-    }
-
-    /**
-     * Returns the type of the annotation just returned by {@link
-     * #readAnnotation()}. This method's value is undefined unless the most
-     * recent call was to {@link #readAnnotation()}.
-     */
-    public int getAnnotationType() {
-        return annotationType;
-    }
-
-    public int readAnnotationName() {
-        return Leb128.readUnsignedLeb128(in);
-    }
-
-    public byte readByte() {
-        checkType(ENCODED_BYTE);
-        type = MUST_READ;
-        return (byte) EncodedValueCodec.readSignedInt(in, arg);
-    }
-
-    public short readShort() {
-        checkType(ENCODED_SHORT);
-        type = MUST_READ;
-        return (short) EncodedValueCodec.readSignedInt(in, arg);
-    }
-
-    public char readChar() {
-        checkType(ENCODED_CHAR);
-        type = MUST_READ;
-        return (char) EncodedValueCodec.readUnsignedInt(in, arg, false);
-    }
-
-    public int readInt() {
-        checkType(ENCODED_INT);
-        type = MUST_READ;
-        return EncodedValueCodec.readSignedInt(in, arg);
-    }
-
-    public long readLong() {
-        checkType(ENCODED_LONG);
-        type = MUST_READ;
-        return EncodedValueCodec.readSignedLong(in, arg);
-    }
-
-    public float readFloat() {
-        checkType(ENCODED_FLOAT);
-        type = MUST_READ;
-        return Float.intBitsToFloat(EncodedValueCodec.readUnsignedInt(in, arg, true));
-    }
-
-    public double readDouble() {
-        checkType(ENCODED_DOUBLE);
-        type = MUST_READ;
-        return Double.longBitsToDouble(EncodedValueCodec.readUnsignedLong(in, arg, true));
-    }
-
-    public int readString() {
-        checkType(ENCODED_STRING);
-        type = MUST_READ;
-        return EncodedValueCodec.readUnsignedInt(in, arg, false);
-    }
-
-    public int readType() {
-        checkType(ENCODED_TYPE);
-        type = MUST_READ;
-        return EncodedValueCodec.readUnsignedInt(in, arg, false);
-    }
-
-    public int readField() {
-        checkType(ENCODED_FIELD);
-        type = MUST_READ;
-        return EncodedValueCodec.readUnsignedInt(in, arg, false);
-    }
-
-    public int readEnum() {
-        checkType(ENCODED_ENUM);
-        type = MUST_READ;
-        return EncodedValueCodec.readUnsignedInt(in, arg, false);
-    }
-
-    public int readMethod() {
-        checkType(ENCODED_METHOD);
-        type = MUST_READ;
-        return EncodedValueCodec.readUnsignedInt(in, arg, false);
-    }
-
-    public void readNull() {
-        checkType(ENCODED_NULL);
-        type = MUST_READ;
-    }
-
-    public boolean readBoolean() {
-        checkType(ENCODED_BOOLEAN);
-        type = MUST_READ;
-        return arg != 0;
-    }
-
-    /**
-     * Skips a single value, including its nested values if it is an array or
-     * annotation.
-     */
-    public void skipValue() {
-        switch (peek()) {
-        case ENCODED_BYTE:
-            readByte();
-            break;
-        case ENCODED_SHORT:
-            readShort();
-            break;
-        case ENCODED_CHAR:
-            readChar();
-            break;
-        case ENCODED_INT:
-            readInt();
-            break;
-        case ENCODED_LONG:
-            readLong();
-            break;
-        case ENCODED_FLOAT:
-            readFloat();
-            break;
-        case ENCODED_DOUBLE:
-            readDouble();
-            break;
-        case ENCODED_STRING:
-            readString();
-            break;
-        case ENCODED_TYPE:
-            readType();
-            break;
-        case ENCODED_FIELD:
-            readField();
-            break;
-        case ENCODED_ENUM:
-            readEnum();
-            break;
-        case ENCODED_METHOD:
-            readMethod();
-            break;
-        case ENCODED_ARRAY:
-            for (int i = 0, size = readArray(); i < size; i++) {
-                skipValue();
-            }
-            break;
-        case ENCODED_ANNOTATION:
-            for (int i = 0, size = readAnnotation(); i < size; i++) {
-                readAnnotationName();
-                skipValue();
-            }
-            break;
-        case ENCODED_NULL:
-            readNull();
-            break;
-        case ENCODED_BOOLEAN:
-            readBoolean();
-            break;
-        default:
-            throw new DexException("Unexpected type: " + Integer.toHexString(type));
-        }
-    }
-
-    private void checkType(int expected) {
-        if (peek() != expected) {
-            throw new IllegalStateException(
-                    String.format("Expected %x but was %x", expected, peek()));
-        }
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/FieldId.java b/dex/src/main/java/com/android/dex/FieldId.java
deleted file mode 100644
index 2f41708..0000000
--- a/dex/src/main/java/com/android/dex/FieldId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class FieldId implements Comparable<FieldId> {
-    private final Dex dex;
-    private final int declaringClassIndex;
-    private final int typeIndex;
-    private final int nameIndex;
-
-    public FieldId(Dex dex, int declaringClassIndex, int typeIndex, int nameIndex) {
-        this.dex = dex;
-        this.declaringClassIndex = declaringClassIndex;
-        this.typeIndex = typeIndex;
-        this.nameIndex = nameIndex;
-    }
-
-    public int getDeclaringClassIndex() {
-        return declaringClassIndex;
-    }
-
-    public int getTypeIndex() {
-        return typeIndex;
-    }
-
-    public int getNameIndex() {
-        return nameIndex;
-    }
-
-    public int compareTo(FieldId other) {
-        if (declaringClassIndex != other.declaringClassIndex) {
-            return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
-        }
-        if (nameIndex != other.nameIndex) {
-            return Unsigned.compare(nameIndex, other.nameIndex);
-        }
-        return Unsigned.compare(typeIndex, other.typeIndex); // should always be 0
-    }
-
-    public void writeTo(Dex.Section out) {
-        out.writeUnsignedShort(declaringClassIndex);
-        out.writeUnsignedShort(typeIndex);
-        out.writeInt(nameIndex);
-    }
-
-    @Override public String toString() {
-        if (dex == null) {
-            return declaringClassIndex + " " + typeIndex + " " + nameIndex;
-        }
-        return dex.typeNames().get(typeIndex) + "." + dex.strings().get(nameIndex);
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/Leb128.java b/dex/src/main/java/com/android/dex/Leb128.java
deleted file mode 100644
index e4ca500..0000000
--- a/dex/src/main/java/com/android/dex/Leb128.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2008 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import com.android.dex.util.ByteOutput;
-
-/**
- * Reads and writes DWARFv3 LEB 128 signed and unsigned integers. See DWARF v3
- * section 7.6.
- */
-public final class Leb128 {
-    private Leb128() {
-    }
-
-    /**
-     * Gets the number of bytes in the unsigned LEB128 encoding of the
-     * given value.
-     *
-     * @param value the value in question
-     * @return its write size, in bytes
-     */
-    public static int unsignedLeb128Size(int value) {
-        // TODO: This could be much cleverer.
-
-        int remaining = value >> 7;
-        int count = 0;
-
-        while (remaining != 0) {
-            remaining >>= 7;
-            count++;
-        }
-
-        return count + 1;
-    }
-
-    /**
-     * Reads an signed integer from {@code in}.
-     */
-    public static int readSignedLeb128(ByteInput in) {
-        int result = 0;
-        int cur;
-        int count = 0;
-        int signBits = -1;
-
-        do {
-            cur = in.readByte() & 0xff;
-            result |= (cur & 0x7f) << (count * 7);
-            signBits <<= 7;
-            count++;
-        } while (((cur & 0x80) == 0x80) && count < 5);
-
-        if ((cur & 0x80) == 0x80) {
-            throw new DexException("invalid LEB128 sequence");
-        }
-
-        // Sign extend if appropriate
-        if (((signBits >> 1) & result) != 0 ) {
-            result |= signBits;
-        }
-
-        return result;
-    }
-
-    /**
-     * Reads an unsigned integer from {@code in}.
-     */
-    public static int readUnsignedLeb128(ByteInput in) {
-        int result = 0;
-        int cur;
-        int count = 0;
-
-        do {
-            cur = in.readByte() & 0xff;
-            result |= (cur & 0x7f) << (count * 7);
-            count++;
-        } while (((cur & 0x80) == 0x80) && count < 5);
-
-        if ((cur & 0x80) == 0x80) {
-            throw new DexException("invalid LEB128 sequence");
-        }
-
-        return result;
-    }
-
-    /**
-     * Writes {@code value} as an unsigned integer to {@code out}, starting at
-     * {@code offset}. Returns the number of bytes written.
-     */
-    public static void writeUnsignedLeb128(ByteOutput out, int value) {
-        int remaining = value >>> 7;
-
-        while (remaining != 0) {
-            out.writeByte((byte) ((value & 0x7f) | 0x80));
-            value = remaining;
-            remaining >>>= 7;
-        }
-
-        out.writeByte((byte) (value & 0x7f));
-    }
-
-    /**
-     * Writes {@code value} as a signed integer to {@code out}, starting at
-     * {@code offset}. Returns the number of bytes written.
-     */
-    public static void writeSignedLeb128(ByteOutput out, int value) {
-        int remaining = value >> 7;
-        boolean hasMore = true;
-        int end = ((value & Integer.MIN_VALUE) == 0) ? 0 : -1;
-
-        while (hasMore) {
-            hasMore = (remaining != end)
-                    || ((remaining & 1) != ((value >> 6) & 1));
-
-            out.writeByte((byte) ((value & 0x7f) | (hasMore ? 0x80 : 0)));
-            value = remaining;
-            remaining >>= 7;
-        }
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/MethodId.java b/dex/src/main/java/com/android/dex/MethodId.java
deleted file mode 100644
index e518740..0000000
--- a/dex/src/main/java/com/android/dex/MethodId.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class MethodId implements Comparable<MethodId> {
-    private final Dex dex;
-    private final int declaringClassIndex;
-    private final int protoIndex;
-    private final int nameIndex;
-
-    public MethodId(Dex dex, int declaringClassIndex, int protoIndex, int nameIndex) {
-        this.dex = dex;
-        this.declaringClassIndex = declaringClassIndex;
-        this.protoIndex = protoIndex;
-        this.nameIndex = nameIndex;
-    }
-
-    public int getDeclaringClassIndex() {
-        return declaringClassIndex;
-    }
-
-    public int getProtoIndex() {
-        return protoIndex;
-    }
-
-    public int getNameIndex() {
-        return nameIndex;
-    }
-
-    public int compareTo(MethodId other) {
-        if (declaringClassIndex != other.declaringClassIndex) {
-            return Unsigned.compare(declaringClassIndex, other.declaringClassIndex);
-        }
-        if (nameIndex != other.nameIndex) {
-            return Unsigned.compare(nameIndex, other.nameIndex);
-        }
-        return Unsigned.compare(protoIndex, other.protoIndex);
-    }
-
-    public void writeTo(Dex.Section out) {
-        out.writeUnsignedShort(declaringClassIndex);
-        out.writeUnsignedShort(protoIndex);
-        out.writeInt(nameIndex);
-    }
-
-    @Override public String toString() {
-        if (dex == null) {
-            return declaringClassIndex + " " + protoIndex + " " + nameIndex;
-        }
-        return dex.typeNames().get(declaringClassIndex)
-                + "." + dex.strings().get(nameIndex)
-                + dex.readTypeList(dex.protoIds().get(protoIndex).getParametersOffset());
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/Mutf8.java b/dex/src/main/java/com/android/dex/Mutf8.java
deleted file mode 100644
index c64da33..0000000
--- a/dex/src/main/java/com/android/dex/Mutf8.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.ByteInput;
-import java.io.UTFDataFormatException;
-
-/**
- * Modified UTF-8 as described in the dex file format spec.
- *
- * <p>Derived from libcore's MUTF-8 encoder at java.nio.charset.ModifiedUtf8.
- */
-public final class Mutf8 {
-    private Mutf8() {}
-
-    /**
-     * Decodes bytes from {@code in} into {@code out} until a delimiter 0x00 is
-     * encountered. Returns a new string containing the decoded characters.
-     */
-    public static String decode(ByteInput in, char[] out) throws UTFDataFormatException {
-        int s = 0;
-        while (true) {
-            char a = (char) (in.readByte() & 0xff);
-            if (a == 0) {
-                return new String(out, 0, s);
-            }
-            out[s] = a;
-            if (a < '\u0080') {
-                s++;
-            } else if ((a & 0xe0) == 0xc0) {
-                int b = in.readByte() & 0xff;
-                if ((b & 0xC0) != 0x80) {
-                    throw new UTFDataFormatException("bad second byte");
-                }
-                out[s++] = (char) (((a & 0x1F) << 6) | (b & 0x3F));
-            } else if ((a & 0xf0) == 0xe0) {
-                int b = in.readByte() & 0xff;
-                int c = in.readByte() & 0xff;
-                if (((b & 0xC0) != 0x80) || ((c & 0xC0) != 0x80)) {
-                    throw new UTFDataFormatException("bad second or third byte");
-                }
-                out[s++] = (char) (((a & 0x0F) << 12) | ((b & 0x3F) << 6) | (c & 0x3F));
-            } else {
-                throw new UTFDataFormatException("bad byte");
-            }
-        }
-    }
-
-    /**
-     * Returns the number of bytes the modified UTF8 representation of 's' would take.
-     */
-    private static long countBytes(String s, boolean shortLength) throws UTFDataFormatException {
-        long result = 0;
-        final int length = s.length();
-        for (int i = 0; i < length; ++i) {
-            char ch = s.charAt(i);
-            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
-                ++result;
-            } else if (ch <= 2047) {
-                result += 2;
-            } else {
-                result += 3;
-            }
-            if (shortLength && result > 65535) {
-                throw new UTFDataFormatException("String more than 65535 UTF bytes long");
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Encodes the modified UTF-8 bytes corresponding to {@code s} into  {@code
-     * dst}, starting at {@code offset}.
-     */
-    public static void encode(byte[] dst, int offset, String s) {
-        final int length = s.length();
-        for (int i = 0; i < length; i++) {
-            char ch = s.charAt(i);
-            if (ch != 0 && ch <= 127) { // U+0000 uses two bytes.
-                dst[offset++] = (byte) ch;
-            } else if (ch <= 2047) {
-                dst[offset++] = (byte) (0xc0 | (0x1f & (ch >> 6)));
-                dst[offset++] = (byte) (0x80 | (0x3f & ch));
-            } else {
-                dst[offset++] = (byte) (0xe0 | (0x0f & (ch >> 12)));
-                dst[offset++] = (byte) (0x80 | (0x3f & (ch >> 6)));
-                dst[offset++] = (byte) (0x80 | (0x3f & ch));
-            }
-        }
-    }
-
-    /**
-     * Returns an array containing the <i>modified UTF-8</i> form of {@code s}.
-     */
-    public static byte[] encode(String s) throws UTFDataFormatException {
-        int utfCount = (int) countBytes(s, true);
-        byte[] result = new byte[utfCount];
-        encode(result, 0, s);
-        return result;
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/ProtoId.java b/dex/src/main/java/com/android/dex/ProtoId.java
deleted file mode 100644
index 9d9f484..0000000
--- a/dex/src/main/java/com/android/dex/ProtoId.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class ProtoId implements Comparable<ProtoId> {
-    private final Dex dex;
-    private final int shortyIndex;
-    private final int returnTypeIndex;
-    private final int parametersOffset;
-
-    public ProtoId(Dex dex, int shortyIndex, int returnTypeIndex, int parametersOffset) {
-        this.dex = dex;
-        this.shortyIndex = shortyIndex;
-        this.returnTypeIndex = returnTypeIndex;
-        this.parametersOffset = parametersOffset;
-    }
-
-    public int compareTo(ProtoId other) {
-        if (returnTypeIndex != other.returnTypeIndex) {
-            return Unsigned.compare(returnTypeIndex, other.returnTypeIndex);
-        }
-        return Unsigned.compare(parametersOffset, other.parametersOffset);
-    }
-
-    public int getShortyIndex() {
-        return shortyIndex;
-    }
-
-    public int getReturnTypeIndex() {
-        return returnTypeIndex;
-    }
-
-    public int getParametersOffset() {
-        return parametersOffset;
-    }
-
-    public void writeTo(Dex.Section out) {
-        out.writeInt(shortyIndex);
-        out.writeInt(returnTypeIndex);
-        out.writeInt(parametersOffset);
-    }
-
-    @Override public String toString() {
-        if (dex == null) {
-            return shortyIndex + " " + returnTypeIndex + " " + parametersOffset;
-        }
-
-        return dex.strings().get(shortyIndex)
-                + ": " + dex.typeNames().get(returnTypeIndex)
-                + " " + dex.readTypeList(parametersOffset);
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/SizeOf.java b/dex/src/main/java/com/android/dex/SizeOf.java
deleted file mode 100644
index 65fab56..0000000
--- a/dex/src/main/java/com/android/dex/SizeOf.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-public final class SizeOf {
-    private SizeOf() {}
-
-    public static final int UBYTE = 1;
-    public static final int USHORT = 2;
-    public static final int UINT = 4;
-
-    public static final int SIGNATURE = UBYTE * 20;
-
-    /**
-     * magic ubyte[8]
-     * checksum uint
-     * signature ubyte[20]
-     * file_size uint
-     * header_size uint
-     * endian_tag uint
-     * link_size uint
-     * link_off uint
-     * map_off uint
-     * string_ids_size uint
-     * string_ids_off uint
-     * type_ids_size uint
-     * type_ids_off uint
-     * proto_ids_size uint
-     * proto_ids_off uint
-     * field_ids_size uint
-     * field_ids_off uint
-     * method_ids_size uint
-     * method_ids_off uint
-     * class_defs_size uint
-     * class_defs_off uint
-     * data_size uint
-     * data_off uint
-     */
-    public static final int HEADER_ITEM = (8 * UBYTE) + UINT + SIGNATURE + (20 * UINT); // 0x70
-
-    /**
-     * string_data_off uint
-     */
-    public static final int STRING_ID_ITEM = UINT;
-
-    /**
-     * descriptor_idx uint
-     */
-    public static final int TYPE_ID_ITEM = UINT;
-
-    /**
-     * type_idx ushort
-     */
-    public static final int TYPE_ITEM = USHORT;
-
-    /**
-     * shorty_idx uint
-     * return_type_idx uint
-     * return_type_idx uint
-     */
-    public static final int PROTO_ID_ITEM = UINT + UINT + UINT;
-
-    /**
-     * class_idx ushort
-     * type_idx/proto_idx ushort
-     * name_idx uint
-     */
-    public static final int MEMBER_ID_ITEM = USHORT + USHORT + UINT;
-
-    /**
-     * class_idx uint
-     * access_flags uint
-     * superclass_idx uint
-     * interfaces_off uint
-     * source_file_idx uint
-     * annotations_off uint
-     * class_data_off uint
-     * static_values_off uint
-     */
-    public static final int CLASS_DEF_ITEM = 8 * UINT;
-
-    /**
-     * type ushort
-     * unused ushort
-     * size uint
-     * offset uint
-     */
-    public static final int MAP_ITEM = USHORT + USHORT + UINT + UINT;
-
-    /**
-     * start_addr uint
-     * insn_count ushort
-     * handler_off ushort
-     */
-    public static final int TRY_ITEM = UINT + USHORT + USHORT;
-}
diff --git a/dex/src/main/java/com/android/dex/TableOfContents.java b/dex/src/main/java/com/android/dex/TableOfContents.java
deleted file mode 100644
index b33a749..0000000
--- a/dex/src/main/java/com/android/dex/TableOfContents.java
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Arrays;
-
-/**
- * The file header and map.
- */
-public final class TableOfContents {
-
-    /*
-     * TODO: factor out ID constants.
-     */
-
-    public final Section header = new Section(0x0000);
-    public final Section stringIds = new Section(0x0001);
-    public final Section typeIds = new Section(0x0002);
-    public final Section protoIds = new Section(0x0003);
-    public final Section fieldIds = new Section(0x0004);
-    public final Section methodIds = new Section(0x0005);
-    public final Section classDefs = new Section(0x0006);
-    public final Section callSiteIds = new Section(0x0007);
-    public final Section methodHandles = new Section(0x0008);
-    public final Section mapList = new Section(0x1000);
-    public final Section typeLists = new Section(0x1001);
-    public final Section annotationSetRefLists = new Section(0x1002);
-    public final Section annotationSets = new Section(0x1003);
-    public final Section classDatas = new Section(0x2000);
-    public final Section codes = new Section(0x2001);
-    public final Section stringDatas = new Section(0x2002);
-    public final Section debugInfos = new Section(0x2003);
-    public final Section annotations = new Section(0x2004);
-    public final Section encodedArrays = new Section(0x2005);
-    public final Section annotationsDirectories = new Section(0x2006);
-    public final Section[] sections = {
-        header, stringIds, typeIds, protoIds, fieldIds, methodIds, classDefs, mapList, callSiteIds,
-        methodHandles, typeLists, annotationSetRefLists, annotationSets, classDatas, codes,
-        stringDatas, debugInfos, annotations, encodedArrays, annotationsDirectories
-    };
-
-    public int apiLevel;
-    public int checksum;
-    public byte[] signature;
-    public int fileSize;
-    public int linkSize;
-    public int linkOff;
-    public int dataSize;
-    public int dataOff;
-
-    public TableOfContents() {
-        signature = new byte[20];
-    }
-
-    public void readFrom(Dex dex) throws IOException {
-        readHeader(dex.open(0));
-        readMap(dex.open(mapList.off));
-        computeSizesFromOffsets();
-    }
-
-    private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {
-        byte[] magic = headerIn.readByteArray(8);
-
-        if (!DexFormat.isSupportedDexMagic(magic)) {
-            String msg =
-                    String.format("Unexpected magic: [0x%02x, 0x%02x, 0x%02x, 0x%02x, "
-                                  + "0x%02x, 0x%02x, 0x%02x, 0x%02x]",
-                                  magic[0], magic[1], magic[2], magic[3],
-                                  magic[4], magic[5], magic[6], magic[7]);
-            throw new DexException(msg);
-        }
-
-        apiLevel = DexFormat.magicToApi(magic);
-        checksum = headerIn.readInt();
-        signature = headerIn.readByteArray(20);
-        fileSize = headerIn.readInt();
-        int headerSize = headerIn.readInt();
-        if (headerSize != SizeOf.HEADER_ITEM) {
-            throw new DexException("Unexpected header: 0x" + Integer.toHexString(headerSize));
-        }
-        int endianTag = headerIn.readInt();
-        if (endianTag != DexFormat.ENDIAN_TAG) {
-            throw new DexException("Unexpected endian tag: 0x" + Integer.toHexString(endianTag));
-        }
-        linkSize = headerIn.readInt();
-        linkOff = headerIn.readInt();
-        mapList.off = headerIn.readInt();
-        if (mapList.off == 0) {
-            throw new DexException("Cannot merge dex files that do not contain a map");
-        }
-        stringIds.size = headerIn.readInt();
-        stringIds.off = headerIn.readInt();
-        typeIds.size = headerIn.readInt();
-        typeIds.off = headerIn.readInt();
-        protoIds.size = headerIn.readInt();
-        protoIds.off = headerIn.readInt();
-        fieldIds.size = headerIn.readInt();
-        fieldIds.off = headerIn.readInt();
-        methodIds.size = headerIn.readInt();
-        methodIds.off = headerIn.readInt();
-        classDefs.size = headerIn.readInt();
-        classDefs.off = headerIn.readInt();
-        dataSize = headerIn.readInt();
-        dataOff = headerIn.readInt();
-    }
-
-    private void readMap(Dex.Section in) throws IOException {
-        int mapSize = in.readInt();
-        Section previous = null;
-        for (int i = 0; i < mapSize; i++) {
-            short type = in.readShort();
-            in.readShort(); // unused
-            Section section = getSection(type);
-            int size = in.readInt();
-            int offset = in.readInt();
-
-            if ((section.size != 0 && section.size != size)
-                    || (section.off != -1 && section.off != offset)) {
-                throw new DexException("Unexpected map value for 0x" + Integer.toHexString(type));
-            }
-
-            section.size = size;
-            section.off = offset;
-
-            if (previous != null && previous.off > section.off) {
-                throw new DexException("Map is unsorted at " + previous + ", " + section);
-            }
-
-            previous = section;
-        }
-        Arrays.sort(sections);
-    }
-
-    public void computeSizesFromOffsets() {
-        int end = dataOff + dataSize;
-        for (int i = sections.length - 1; i >= 0; i--) {
-            Section section = sections[i];
-            if (section.off == -1) {
-                continue;
-            }
-            if (section.off > end) {
-                throw new DexException("Map is unsorted at " + section);
-            }
-            section.byteCount = end - section.off;
-            end = section.off;
-        }
-    }
-
-    private Section getSection(short type) {
-        for (Section section : sections) {
-            if (section.type == type) {
-                return section;
-            }
-        }
-        throw new IllegalArgumentException("No such map item: " + type);
-    }
-
-    public void writeHeader(Dex.Section out, int api) throws IOException {
-        out.write(DexFormat.apiToMagic(api).getBytes("UTF-8"));
-        out.writeInt(checksum);
-        out.write(signature);
-        out.writeInt(fileSize);
-        out.writeInt(SizeOf.HEADER_ITEM);
-        out.writeInt(DexFormat.ENDIAN_TAG);
-        out.writeInt(linkSize);
-        out.writeInt(linkOff);
-        out.writeInt(mapList.off);
-        out.writeInt(stringIds.size);
-        out.writeInt(stringIds.off);
-        out.writeInt(typeIds.size);
-        out.writeInt(typeIds.off);
-        out.writeInt(protoIds.size);
-        out.writeInt(protoIds.off);
-        out.writeInt(fieldIds.size);
-        out.writeInt(fieldIds.off);
-        out.writeInt(methodIds.size);
-        out.writeInt(methodIds.off);
-        out.writeInt(classDefs.size);
-        out.writeInt(classDefs.off);
-        out.writeInt(dataSize);
-        out.writeInt(dataOff);
-    }
-
-    public void writeMap(Dex.Section out) throws IOException {
-        int count = 0;
-        for (Section section : sections) {
-            if (section.exists()) {
-                count++;
-            }
-        }
-
-        out.writeInt(count);
-        for (Section section : sections) {
-            if (section.exists()) {
-                out.writeShort(section.type);
-                out.writeShort((short) 0);
-                out.writeInt(section.size);
-                out.writeInt(section.off);
-            }
-        }
-    }
-
-    public static class Section implements Comparable<Section> {
-        public final short type;
-        public int size = 0;
-        public int off = -1;
-        public int byteCount = 0;
-
-        public Section(int type) {
-            this.type = (short) type;
-        }
-
-        public boolean exists() {
-            return size > 0;
-        }
-
-        public int compareTo(Section section) {
-            if (off != section.off) {
-                return off < section.off ? -1 : 1;
-            }
-            return 0;
-        }
-
-        @Override public String toString() {
-            return String.format("Section[type=%#x,off=%#x,size=%#x]", type, off, size);
-        }
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/TypeList.java b/dex/src/main/java/com/android/dex/TypeList.java
deleted file mode 100644
index 123e82c..0000000
--- a/dex/src/main/java/com/android/dex/TypeList.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.Unsigned;
-
-public final class TypeList implements Comparable<TypeList> {
-
-    public static final TypeList EMPTY = new TypeList(null, Dex.EMPTY_SHORT_ARRAY);
-
-    private final Dex dex;
-    private final short[] types;
-
-    public TypeList(Dex dex, short[] types) {
-        this.dex = dex;
-        this.types = types;
-    }
-
-    public short[] getTypes() {
-        return types;
-    }
-
-    @Override public int compareTo(TypeList other) {
-        for (int i = 0; i < types.length && i < other.types.length; i++) {
-            if (types[i] != other.types[i]) {
-                return Unsigned.compare(types[i], other.types[i]);
-            }
-        }
-        return Unsigned.compare(types.length, other.types.length);
-    }
-
-    @Override public String toString() {
-        StringBuilder result = new StringBuilder();
-        result.append("(");
-        for (int i = 0, typesLength = types.length; i < typesLength; i++) {
-            result.append(dex != null ? dex.typeNames().get(types[i]) : types[i]);
-        }
-        result.append(")");
-        return result.toString();
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java b/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java
deleted file mode 100644
index 889a936..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex.util;
-
-public final class ByteArrayByteInput implements ByteInput {
-
-    private final byte[] bytes;
-    private int position;
-
-    public ByteArrayByteInput(byte... bytes) {
-        this.bytes = bytes;
-    }
-
-    @Override public byte readByte() {
-        return bytes[position++];
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteInput.java b/dex/src/main/java/com/android/dex/util/ByteInput.java
deleted file mode 100644
index f1a7196..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteInput.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex.util;
-
-/**
- * A byte source.
- */
-public interface ByteInput {
-
-    /**
-     * Returns a byte.
-     *
-     * @throws IndexOutOfBoundsException if all bytes have been read.
-     */
-    byte readByte();
-}
diff --git a/dex/src/main/java/com/android/dex/util/ByteOutput.java b/dex/src/main/java/com/android/dex/util/ByteOutput.java
deleted file mode 100644
index eb77040..0000000
--- a/dex/src/main/java/com/android/dex/util/ByteOutput.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex.util;
-
-/**
- * A byte sink.
- */
-public interface ByteOutput {
-
-    /**
-     * Writes a byte.
-     *
-     * @throws IndexOutOfBoundsException if all bytes have been written.
-     */
-    void writeByte(int i);
-}
diff --git a/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java b/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java
deleted file mode 100644
index 5dfd954..0000000
--- a/dex/src/main/java/com/android/dex/util/ExceptionWithContext.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.dex.util;
-
-import java.io.PrintStream;
-import java.io.PrintWriter;
-
-/**
- * Exception which carries around structured context.
- */
-public class ExceptionWithContext extends RuntimeException {
-    /** {@code non-null;} human-oriented context of the exception */
-    private StringBuffer context;
-
-    /**
-     * Augments the given exception with the given context, and return the
-     * result. The result is either the given exception if it was an
-     * {@link ExceptionWithContext}, or a newly-constructed exception if it
-     * was not.
-     *
-     * @param ex {@code non-null;} the exception to augment
-     * @param str {@code non-null;} context to add
-     * @return {@code non-null;} an appropriate instance
-     */
-    public static ExceptionWithContext withContext(Throwable ex, String str) {
-        ExceptionWithContext ewc;
-
-        if (ex instanceof ExceptionWithContext) {
-            ewc = (ExceptionWithContext) ex;
-        } else {
-            ewc = new ExceptionWithContext(ex);
-        }
-
-        ewc.addContext(str);
-        return ewc;
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param message human-oriented message
-     */
-    public ExceptionWithContext(String message) {
-        this(message, null);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param cause {@code null-ok;} exception that caused this one
-     */
-    public ExceptionWithContext(Throwable cause) {
-        this(null, cause);
-    }
-
-    /**
-     * Constructs an instance.
-     *
-     * @param message human-oriented message
-     * @param cause {@code null-ok;} exception that caused this one
-     */
-    public ExceptionWithContext(String message, Throwable cause) {
-        super((message != null) ? message :
-              (cause != null) ? cause.getMessage() : null,
-              cause);
-
-        if (cause instanceof ExceptionWithContext) {
-            String ctx = ((ExceptionWithContext) cause).context.toString();
-            context = new StringBuffer(ctx.length() + 200);
-            context.append(ctx);
-        } else {
-            context = new StringBuffer(200);
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void printStackTrace(PrintStream out) {
-        super.printStackTrace(out);
-        out.println(context);
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    public void printStackTrace(PrintWriter out) {
-        super.printStackTrace(out);
-        out.println(context);
-    }
-
-    /**
-     * Adds a line of context to this instance.
-     *
-     * @param str {@code non-null;} new context
-     */
-    public void addContext(String str) {
-        if (str == null) {
-            throw new NullPointerException("str == null");
-        }
-
-        context.append(str);
-        if (!str.endsWith("\n")) {
-            context.append('\n');
-        }
-    }
-
-    /**
-     * Gets the context.
-     *
-     * @return {@code non-null;} the context
-     */
-    public String getContext() {
-        return context.toString();
-    }
-
-    /**
-     * Prints the message and context.
-     *
-     * @param out {@code non-null;} where to print to
-     */
-    public void printContext(PrintStream out) {
-        out.println(getMessage());
-        out.print(context);
-    }
-
-    /**
-     * Prints the message and context.
-     *
-     * @param out {@code non-null;} where to print to
-     */
-    public void printContext(PrintWriter out) {
-        out.println(getMessage());
-        out.print(context);
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/util/FileUtils.java b/dex/src/main/java/com/android/dex/util/FileUtils.java
deleted file mode 100644
index 4cea95c..0000000
--- a/dex/src/main/java/com/android/dex/util/FileUtils.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2007 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 com.android.dex.util;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-/**
- * File I/O utilities.
- */
-public final class FileUtils {
-    private FileUtils() {
-    }
-
-    /**
-     * Reads the named file, translating {@link IOException} to a
-     * {@link RuntimeException} of some sort.
-     *
-     * @param fileName {@code non-null;} name of the file to read
-     * @return {@code non-null;} contents of the file
-     */
-    public static byte[] readFile(String fileName) {
-        File file = new File(fileName);
-        return readFile(file);
-    }
-
-    /**
-     * Reads the given file, translating {@link IOException} to a
-     * {@link RuntimeException} of some sort.
-     *
-     * @param file {@code non-null;} the file to read
-     * @return {@code non-null;} contents of the file
-     */
-    public static byte[] readFile(File file) {
-        if (!file.exists()) {
-            throw new RuntimeException(file + ": file not found");
-        }
-
-        if (!file.isFile()) {
-            throw new RuntimeException(file + ": not a file");
-        }
-
-        if (!file.canRead()) {
-            throw new RuntimeException(file + ": file not readable");
-        }
-
-        long longLength = file.length();
-        int length = (int) longLength;
-        if (length != longLength) {
-            throw new RuntimeException(file + ": file too long");
-        }
-
-        byte[] result = new byte[length];
-
-        try {
-            FileInputStream in = new FileInputStream(file);
-            int at = 0;
-            while (length > 0) {
-                int amt = in.read(result, at, length);
-                if (amt == -1) {
-                    throw new RuntimeException(file + ": unexpected EOF");
-                }
-                at += amt;
-                length -= amt;
-            }
-            in.close();
-        } catch (IOException ex) {
-            throw new RuntimeException(file + ": trouble reading", ex);
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns true if {@code fileName} names a .zip, .jar, or .apk.
-     */
-    public static boolean hasArchiveSuffix(String fileName) {
-        return fileName.endsWith(".zip")
-                || fileName.endsWith(".jar")
-                || fileName.endsWith(".apk");
-    }
-}
diff --git a/dex/src/main/java/com/android/dex/util/Unsigned.java b/dex/src/main/java/com/android/dex/util/Unsigned.java
deleted file mode 100644
index cb50d0a..0000000
--- a/dex/src/main/java/com/android/dex/util/Unsigned.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex.util;
-
-/**
- * Unsigned arithmetic over Java's signed types.
- */
-public final class Unsigned {
-    private Unsigned() {}
-
-    public static int compare(short ushortA, short ushortB) {
-        if (ushortA == ushortB) {
-            return 0;
-        }
-        int a = ushortA & 0xFFFF;
-        int b = ushortB & 0xFFFF;
-        return a < b ? -1 : 1;
-    }
-
-    public static int compare(int uintA, int uintB) {
-        if (uintA == uintB) {
-            return 0;
-        }
-        long a = uintA & 0xFFFFFFFFL;
-        long b = uintB & 0xFFFFFFFFL;
-        return a < b ? -1 : 1;
-    }
-}
diff --git a/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java b/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java
deleted file mode 100644
index a4ca376..0000000
--- a/dex/src/test/java/com/android/dex/EncodedValueReaderTest.java
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright (C) 2011 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 com.android.dex;
-
-import com.android.dex.util.ByteArrayByteInput;
-import junit.framework.TestCase;
-
-public final class EncodedValueReaderTest extends TestCase {
-
-    public void testReadByte() {
-        assertEquals((byte) 0x80, readerOf(0, 0x80).readByte());
-        assertEquals((byte) 0xff, readerOf(0, 0xff).readByte());
-        assertEquals((byte) 0x00, readerOf(0, 0x00).readByte());
-        assertEquals((byte) 0x01, readerOf(0, 0x01).readByte());
-        assertEquals((byte) 0x7f, readerOf(0, 0x7f).readByte());
-    }
-
-    public void testReadShort() {
-        assertEquals((short) 0x8000, readerOf(34, 0x00, 0x80).readShort());
-        assertEquals((short)      0, readerOf( 2, 0x00).readShort());
-        assertEquals((short)   0xab, readerOf(34, 0xab, 0x00).readShort());
-        assertEquals((short) 0xabcd, readerOf(34, 0xcd, 0xab).readShort());
-        assertEquals((short) 0x7FFF, readerOf(34, 0xff, 0x7f).readShort());
-    }
-
-    public void testReadInt() {
-        assertEquals(0x80000000, readerOf(100, 0x00, 0x00, 0x00, 0x80).readInt());
-        assertEquals(      0x00, readerOf(  4, 0x00).readInt());
-        assertEquals(      0xab, readerOf( 36, 0xab, 0x00).readInt());
-        assertEquals(    0xabcd, readerOf( 68, 0xcd, 0xab, 0x00).readInt());
-        assertEquals(  0xabcdef, readerOf(100, 0xef, 0xcd, 0xab, 0x00).readInt());
-        assertEquals(0xabcdef01, readerOf(100, 0x01, 0xef, 0xcd, 0xab).readInt());
-        assertEquals(0x7fffffff, readerOf(100, 0xff, 0xff, 0xff, 127).readInt());
-    }
-
-    public void testReadLong() {
-        assertEquals(0x8000000000000000L, readerOf( -26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80).readLong());
-        assertEquals(              0x00L, readerOf(   6, 0x00).readLong());
-        assertEquals(              0xabL, readerOf(  38, 0xab, 0x00).readLong());
-        assertEquals(            0xabcdL, readerOf(  70, 0xcd, 0xab, 0x00).readLong());
-        assertEquals(          0xabcdefL, readerOf( 102, 0xef, 0xcd, 0xab, 0x00).readLong());
-        assertEquals(        0xabcdef01L, readerOf(-122, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
-        assertEquals(      0xabcdef0123L, readerOf( -90, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
-        assertEquals(    0xabcdef012345L, readerOf( -58, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
-        assertEquals(  0xabcdef01234567L, readerOf( -26, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab, 0x00).readLong());
-        assertEquals(0xabcdef0123456789L, readerOf( -26, 0x89, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab).readLong());
-        assertEquals(0x7fffffffffffffffL, readerOf( -26, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f).readLong());
-    }
-
-    public void testReadFloat() {
-        assertEquals(Float.NEGATIVE_INFINITY, readerOf(48, -128, -1).readFloat());
-        assertEquals(Float.POSITIVE_INFINITY, readerOf(48, -128, 127).readFloat());
-        assertEquals(Float.NaN, readerOf(48, -64, 127).readFloat());
-        assertEquals(-0.0f, readerOf(16, -128).readFloat());
-        assertEquals(0.0f, readerOf(16, 0).readFloat());
-        assertEquals(0.5f, readerOf(16, 63).readFloat());
-        assertEquals(1f, readerOf(48, -128, 63).readFloat());
-        assertEquals(1.0E06f, readerOf(80, 36, 116, 73).readFloat());
-        assertEquals(1.0E12f, readerOf(112, -91, -44, 104, 83).readFloat());
-    }
-
-    public void testReadDouble() {
-        assertEquals(Double.NEGATIVE_INFINITY, readerOf(49, -16, -1).readDouble());
-        assertEquals(Double.POSITIVE_INFINITY, readerOf(49, -16, 127).readDouble());
-        assertEquals(Double.NaN, readerOf(49, -8, 127).readDouble());
-        assertEquals(-0.0, readerOf(17, -128).readDouble());
-        assertEquals(0.0, readerOf(17, 0).readDouble());
-        assertEquals(0.5, readerOf(49, -32, 63).readDouble());
-        assertEquals(1.0, readerOf(49, -16, 63).readDouble());
-        assertEquals(1.0E06, readerOf(113, -128, -124, 46, 65).readDouble());
-        assertEquals(1.0E12, readerOf(-111, -94, -108, 26, 109, 66).readDouble());
-        assertEquals(1.0E24, readerOf(-15, -76, -99, -39, 121, 67, 120, -22, 68).readDouble());
-    }
-
-    public void testReadChar() {
-        assertEquals('\u0000', readerOf( 3, 0x00).readChar());
-        assertEquals('\u00ab', readerOf( 3, 0xab).readChar());
-        assertEquals('\uabcd', readerOf(35, 0xcd, 0xab).readChar());
-        assertEquals('\uffff', readerOf(35, 0xff, 0xff).readChar());
-    }
-
-    public void testReadBoolean() {
-        assertEquals(true, readerOf(63).readBoolean());
-        assertEquals(false, readerOf(31).readBoolean());
-    }
-
-    public void testReadNull() {
-        readerOf(30).readNull();
-    }
-
-    public void testReadReference() {
-        assertEquals(      0xab, readerOf(0x17, 0xab).readString());
-        assertEquals(    0xabcd, readerOf(0x37, 0xcd, 0xab).readString());
-        assertEquals(  0xabcdef, readerOf(0x57, 0xef, 0xcd, 0xab).readString());
-        assertEquals(0xabcdef01, readerOf(0x77, 0x01, 0xef, 0xcd, 0xab).readString());
-    }
-
-    public void testReadWrongType() {
-        try {
-            readerOf(0x17, 0xab).readField();
-            fail();
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    private EncodedValueReader readerOf(int... bytes) {
-        byte[] data = new byte[bytes.length];
-        for (int i = 0; i < bytes.length; i++) {
-            data[i] = (byte) bytes[i];
-        }
-        return new EncodedValueReader(new ByteArrayByteInput(data));
-    }
-}
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
index fc99502..9d6c950 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/net/ServerSocketTest.java
@@ -17,10 +17,12 @@
 
 package org.apache.harmony.tests.java.net;
 
+import libcore.io.Libcore;
 import libcore.junit.junit3.TestCaseWithRules;
 import libcore.junit.util.ResourceLeakageDetector;
 import org.junit.Rule;
 import org.junit.rules.TestRule;
+
 import tests.support.Support_Configuration;
 import java.io.IOException;
 import java.io.InputStream;
@@ -42,6 +44,9 @@
 import java.util.Locale;
 import java.util.Properties;
 
+import static android.system.OsConstants.F_GETFL;
+import static android.system.OsConstants.O_NONBLOCK;
+
 public class ServerSocketTest extends TestCaseWithRules {
     @Rule
     public TestRule guardRule = ResourceLeakageDetector.getRule();
@@ -174,12 +179,16 @@
     /**
      * java.net.ServerSocket#accept()
      */
-    public void test_accept() throws IOException {
+    public void test_accept() throws Exception {
         s = new ServerSocket(0);
         try {
             s.setSoTimeout(5000);
             startClient(s.getLocalPort());
             sconn = s.accept();
+
+            // The new socket should not be blocking.
+            assertEquals(0, Libcore.os.fcntlVoid(sconn.getFileDescriptor$(), F_GETFL) & O_NONBLOCK);
+
             int localPort1 = s.getLocalPort();
             int localPort2 = sconn.getLocalPort();
             sconn.close();
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
index 94ad327..b4cf99b 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/LocaleTest.java
@@ -172,11 +172,6 @@
         assertTrue("Returned incorrect country: "
                 + testLocale.getDisplayCountry(), testLocale
                 .getDisplayCountry().equals("Canada"));
-
-        // Regression for Harmony-1146
-        Locale l_countryCD = new Locale("", "CD");
-        assertEquals("Congo (DRC)",
-                l_countryCD.getDisplayCountry());
     }
 
     public void test_getDisplayCountryLjava_util_Locale() {
diff --git a/libart/src/main/java/dalvik/system/ClassExt.java b/libart/src/main/java/dalvik/system/ClassExt.java
index 772bd2e..9c9fa7a 100644
--- a/libart/src/main/java/dalvik/system/ClassExt.java
+++ b/libart/src/main/java/dalvik/system/ClassExt.java
@@ -48,7 +48,8 @@
     private Object obsoleteMethods;
 
     /**
-     * If set, the bytes of the original dex-file associated with the related class.
+     * If set, the bytes, native pointer (as a java.lang.Long), or DexCache of the original dex-file
+     * associated with the related class.
      *
      * In this instance 'original' means either (1) the dex-file loaded for this class when it was
      * first loaded after all non-retransformation capable transformations had been performed but
@@ -59,7 +60,7 @@
      *
      * This field is a logical part of the 'Class' type.
      */
-    private byte[] originalDexFile;
+    private Object originalDexFile;
 
     /**
      * If class verify fails, we must return same error on subsequent tries. We may store either
diff --git a/libart/src/main/java/java/lang/DexCache.java b/libart/src/main/java/java/lang/DexCache.java
index 7e5bdff..864196d 100644
--- a/libart/src/main/java/java/lang/DexCache.java
+++ b/libart/src/main/java/java/lang/DexCache.java
@@ -33,17 +33,13 @@
 package java.lang;
 
 import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
 
 /**
  * A dex cache holds resolved copies of strings, fields, methods, and classes from the dexfile.
  */
 final class DexCache {
-    /** Lazily initialized dex file wrapper. Volatile to avoid double-check locking issues. */
-    private volatile Dex dex;
-
     /** The location of the associated dex file. */
-    String location;
+    private String location;
 
     /** Holds C pointer to dexFile. */
     private long dexFile;
@@ -116,29 +112,5 @@
 
     // Only created by the VM.
     private DexCache() {}
-
-    Dex getDex() {
-        Dex result = dex;
-        if (result == null) {
-            synchronized (this) {
-                result = dex;
-                if (result == null) {
-                    dex = result = getDexNative();
-                }
-            }
-        }
-        return result;
-    }
-
-    @FastNative
-    native Class<?> getResolvedType(int typeIndex);
-    @FastNative
-    native String getResolvedString(int stringIndex);
-    @FastNative
-    native void setResolvedType(int typeIndex, Class<?> type);
-    @FastNative
-    native void setResolvedString(int stringIndex, String string);
-    @FastNative
-    private native Dex getDexNative();
 }
 
diff --git a/luni/src/main/java/android/system/Os.java b/luni/src/main/java/android/system/Os.java
index cae8083..7db7f75 100644
--- a/luni/src/main/java/android/system/Os.java
+++ b/luni/src/main/java/android/system/Os.java
@@ -63,6 +63,25 @@
   /** @hide */ public static void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { Libcore.os.bind(fd, address); }
 
   /**
+   * See <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+   *
+   * @hide
+   */
+  public static StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+      return Libcore.os.capget(hdr);
+  }
+
+  /**
+   * See <a href="http://man7.org/linux/man-pages/man2/capset.2.html">capset(2)</a>.
+   *
+   * @hide
+   */
+  public static void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+          throws ErrnoException {
+      Libcore.os.capset(hdr, data);
+  }
+
+  /**
    * See <a href="http://man7.org/linux/man-pages/man2/chmod.2.html">chmod(2)</a>.
    */
   public static void chmod(String path, int mode) throws ErrnoException { Libcore.os.chmod(path, mode); }
diff --git a/luni/src/main/java/android/system/OsConstants.java b/luni/src/main/java/android/system/OsConstants.java
index 10ea52f..adad301 100644
--- a/luni/src/main/java/android/system/OsConstants.java
+++ b/luni/src/main/java/android/system/OsConstants.java
@@ -24,6 +24,20 @@
     }
 
     /**
+     * Returns the index of the element in the cap_user_data array that this capability is stored
+     * in.
+     * @hide
+     */
+    public static int CAP_TO_INDEX(int x) { return x >>> 5; }
+
+    /**
+     * Returns the mask for the given capability. This is relative to the capability's cap_user_data
+     * element, the index of which can be retrieved with CAP_TO_INDEX.
+     * @hide
+     */
+    public static int CAP_TO_MASK(int x) { return 1 << (x & 31); }
+
+    /**
      * Tests whether the given mode is a block device.
      */
     public static boolean S_ISBLK(int mode) { return (mode & S_IFMT) == S_IFBLK; }
@@ -320,6 +334,7 @@
     /** @hide */ public static final int IP_RECVTOS = placeholder();
     public static final int IP_TOS = placeholder();
     public static final int IP_TTL = placeholder();
+    /** @hide */ public static final int _LINUX_CAPABILITY_VERSION_3 = placeholder();
     public static final int MAP_FIXED = placeholder();
     /** @hide */ public static final int MAP_POPULATE = placeholder();
     public static final int MAP_PRIVATE = placeholder();
@@ -372,6 +387,8 @@
     public static final int POLLRDNORM = placeholder();
     public static final int POLLWRBAND = placeholder();
     public static final int POLLWRNORM = placeholder();
+    /** @hide */ public static final int PR_CAP_AMBIENT = placeholder();
+    /** @hide */ public static final int PR_CAP_AMBIENT_RAISE = placeholder();
     public static final int PR_GET_DUMPABLE = placeholder();
     public static final int PR_SET_DUMPABLE = placeholder();
     public static final int PR_SET_NO_NEW_PRIVS = placeholder();
diff --git a/luni/src/main/java/android/system/StructCapUserData.java b/luni/src/main/java/android/system/StructCapUserData.java
new file mode 100644
index 0000000..af63caf
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCapUserData.java
@@ -0,0 +1,48 @@
+/*
+ * 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 android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to Linux' __user_cap_data_struct for capget and capset.
+ *
+ * @hide
+ */
+public final class StructCapUserData {
+  /** Effective capability mask. */
+  public final int effective; /* __u32 */
+
+  /** Permitted capability mask. */
+  public final int permitted; /* __u32 */
+
+  /** Inheritable capability mask. */
+  public final int inheritable; /* __u32 */
+
+  /**
+   * Constructs an instance with the given field values.
+   */
+  public StructCapUserData(int effective, int permitted, int inheritable) {
+    this.effective = effective;
+    this.permitted = permitted;
+    this.inheritable = inheritable;
+  }
+
+  @Override public String toString() {
+    return Objects.toString(this);
+  }
+}
diff --git a/luni/src/main/java/android/system/StructCapUserHeader.java b/luni/src/main/java/android/system/StructCapUserHeader.java
new file mode 100644
index 0000000..abbb395
--- /dev/null
+++ b/luni/src/main/java/android/system/StructCapUserHeader.java
@@ -0,0 +1,48 @@
+/*
+ * 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 android.system;
+
+import libcore.util.Objects;
+
+/**
+ * Corresponds to Linux' __user_cap_header_struct for capget and capset.
+ *
+ * @hide
+ */
+public final class StructCapUserHeader {
+  /**
+   * Version of the header. Note this is not final as capget() may mutate the field when an
+   * invalid version is provided. See
+   * <a href="http://man7.org/linux/man-pages/man2/capget.2.html">capget(2)</a>.
+   */
+  public int version; /* __u32 */
+
+  /** Pid of the header. The pid a call applies to. */
+  public final int pid;
+
+  /**
+   * Constructs an instance with the given field values.
+   */
+  public StructCapUserHeader(int version, int pid) {
+    this.version = version;
+    this.pid = pid;
+  }
+
+  @Override public String toString() {
+    return Objects.toString(this);
+  }
+}
diff --git a/luni/src/main/java/libcore/io/ForwardingOs.java b/luni/src/main/java/libcore/io/ForwardingOs.java
index ac805e8..55d4d82 100644
--- a/luni/src/main/java/libcore/io/ForwardingOs.java
+++ b/luni/src/main/java/libcore/io/ForwardingOs.java
@@ -19,6 +19,8 @@
 import android.system.ErrnoException;
 import android.system.GaiException;
 import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
 import android.system.StructFlock;
 import android.system.StructGroupReq;
 import android.system.StructGroupSourceReq;
@@ -56,6 +58,14 @@
     public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException { return os.android_getaddrinfo(node, hints, netId); }
     public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException { os.bind(fd, address, port); }
     public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException { os.bind(fd, address); }
+    @Override
+    public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException {
+        return os.capget(hdr);
+    }
+    @Override
+    public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException {
+        os.capset(hdr, data);
+    }
     public void chmod(String path, int mode) throws ErrnoException { os.chmod(path, mode); }
     public void chown(String path, int uid, int gid) throws ErrnoException { os.chown(path, uid, gid); }
     public void close(FileDescriptor fd) throws ErrnoException { os.close(fd); }
diff --git a/luni/src/main/java/libcore/io/IoBridge.java b/luni/src/main/java/libcore/io/IoBridge.java
index 0c34d5e..7adae8b 100644
--- a/luni/src/main/java/libcore/io/IoBridge.java
+++ b/luni/src/main/java/libcore/io/IoBridge.java
@@ -34,6 +34,7 @@
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.NetworkInterface;
+import java.net.NoRouteToHostException;
 import java.net.PortUnreachableException;
 import java.net.SocketAddress;
 import java.net.SocketException;
@@ -128,6 +129,12 @@
         try {
             connectErrno(fd, inetAddress, port, timeoutMs);
         } catch (ErrnoException errnoException) {
+            if (errnoException.errno == EHOSTUNREACH) {
+                throw new NoRouteToHostException("Host unreachable");
+            }
+            if (errnoException.errno == EADDRNOTAVAIL) {
+                throw new NoRouteToHostException("Address not available");
+            }
             throw new ConnectException(connectDetail(fd, inetAddress, port, timeoutMs,
                     errnoException), errnoException);
         } catch (SocketException ex) {
@@ -141,7 +148,7 @@
 
     private static void connectErrno(FileDescriptor fd, InetAddress inetAddress, int port, int timeoutMs) throws ErrnoException, IOException {
         // With no timeout, just call connect(2) directly.
-        if (timeoutMs == 0) {
+        if (timeoutMs <= 0) {
             Libcore.os.connect(fd, inetAddress, port);
             return;
         }
diff --git a/luni/src/main/java/libcore/io/Libcore.java b/luni/src/main/java/libcore/io/Libcore.java
index 478ed6d..cbc5a55 100644
--- a/luni/src/main/java/libcore/io/Libcore.java
+++ b/luni/src/main/java/libcore/io/Libcore.java
@@ -24,7 +24,7 @@
      * unless it has a strong reason to bypass the helpful checks/guards that it
      * provides.
      */
-    public static Os rawOs = new Posix();
+    public static Os rawOs = new Linux();
 
     /**
      * Access to syscalls with helpful checks/guards.
diff --git a/luni/src/main/java/libcore/io/Posix.java b/luni/src/main/java/libcore/io/Linux.java
similarity index 97%
rename from luni/src/main/java/libcore/io/Posix.java
rename to luni/src/main/java/libcore/io/Linux.java
index 1a74678..09adb09 100644
--- a/luni/src/main/java/libcore/io/Posix.java
+++ b/luni/src/main/java/libcore/io/Linux.java
@@ -19,6 +19,8 @@
 import android.system.ErrnoException;
 import android.system.GaiException;
 import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
 import android.system.StructFlock;
 import android.system.StructGroupReq;
 import android.system.StructGroupSourceReq;
@@ -42,14 +44,19 @@
 import java.nio.ByteBuffer;
 import java.nio.NioUtils;
 
-public final class Posix implements Os {
-    Posix() { }
+public final class Linux implements Os {
+    Linux() { }
 
     public native FileDescriptor accept(FileDescriptor fd, SocketAddress peerAddress) throws ErrnoException, SocketException;
     public native boolean access(String path, int mode) throws ErrnoException;
     public native InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
     public native void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
     public native void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
+    @Override
+    public native StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+    @Override
+    public native void capset(StructCapUserHeader hdr, StructCapUserData[] data)
+            throws ErrnoException;
     public native void chmod(String path, int mode) throws ErrnoException;
     public native void chown(String path, int uid, int gid) throws ErrnoException;
     public native void close(FileDescriptor fd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/io/Os.java b/luni/src/main/java/libcore/io/Os.java
index 41b034b..20a84bd 100644
--- a/luni/src/main/java/libcore/io/Os.java
+++ b/luni/src/main/java/libcore/io/Os.java
@@ -19,6 +19,8 @@
 import android.system.ErrnoException;
 import android.system.GaiException;
 import android.system.StructAddrinfo;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
 import android.system.StructFlock;
 import android.system.StructGroupReq;
 import android.system.StructGroupSourceReq;
@@ -47,6 +49,8 @@
     public InetAddress[] android_getaddrinfo(String node, StructAddrinfo hints, int netId) throws GaiException;
     public void bind(FileDescriptor fd, InetAddress address, int port) throws ErrnoException, SocketException;
     public void bind(FileDescriptor fd, SocketAddress address) throws ErrnoException, SocketException;
+    public StructCapUserData[] capget(StructCapUserHeader hdr) throws ErrnoException;
+    public void capset(StructCapUserHeader hdr, StructCapUserData[] data) throws ErrnoException;
     public void chmod(String path, int mode) throws ErrnoException;
     public void chown(String path, int uid, int gid) throws ErrnoException;
     public void close(FileDescriptor fd) throws ErrnoException;
diff --git a/luni/src/main/java/libcore/util/TimeZoneDataFiles.java b/luni/src/main/java/libcore/util/TimeZoneDataFiles.java
new file mode 100644
index 0000000..8361339
--- /dev/null
+++ b/luni/src/main/java/libcore/util/TimeZoneDataFiles.java
@@ -0,0 +1,76 @@
+/*
+ * 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.util;
+
+/**
+ * Utility methods associated with finding updateable time zone data files.
+ */
+public final class TimeZoneDataFiles {
+
+    private static final String ANDROID_ROOT_ENV = "ANDROID_ROOT";
+    private static final String ANDROID_DATA_ENV = "ANDROID_DATA";
+
+    private TimeZoneDataFiles() {}
+
+    // VisibleForTesting
+    public static String[] getTimeZoneFilePaths(String fileName) {
+        return new String[] {
+                getDataTimeZoneFile(fileName),
+                getSystemTimeZoneFile(fileName)
+        };
+    }
+
+    private static String getDataTimeZoneFile(String fileName) {
+        return System.getenv(ANDROID_DATA_ENV) + "/misc/zoneinfo/current/" + fileName;
+    }
+
+    // VisibleForTesting
+    public static String getSystemTimeZoneFile(String fileName) {
+        return System.getenv(ANDROID_ROOT_ENV) + "/usr/share/zoneinfo/" + fileName;
+    }
+
+    public static String generateIcuDataPath() {
+        StringBuilder icuDataPathBuilder = new StringBuilder();
+        // ICU should first look in ANDROID_DATA. This is used for (optional) timezone data.
+        String dataIcuDataPath = getEnvironmentPath(ANDROID_DATA_ENV, "/misc/zoneinfo/current/icu");
+        if (dataIcuDataPath != null) {
+            icuDataPathBuilder.append(dataIcuDataPath);
+        }
+
+        // ICU should always look in ANDROID_ROOT.
+        String systemIcuDataPath = getEnvironmentPath(ANDROID_ROOT_ENV, "/usr/icu");
+        if (systemIcuDataPath != null) {
+            if (icuDataPathBuilder.length() > 0) {
+                icuDataPathBuilder.append(":");
+            }
+            icuDataPathBuilder.append(systemIcuDataPath);
+        }
+        return icuDataPathBuilder.toString();
+    }
+
+    /**
+     * Creates a path by combining the value of an environment variable with a relative path.
+     * Returns {@code null} if the environment variable is not set.
+     */
+    private static String getEnvironmentPath(String environmentVariable, String path) {
+        String variable = System.getenv(environmentVariable);
+        if (variable == null) {
+            return null;
+        }
+        return variable + path;
+    }
+}
diff --git a/luni/src/main/java/libcore/util/ZoneInfoDB.java b/luni/src/main/java/libcore/util/ZoneInfoDB.java
index d9ff323..acb9c12 100644
--- a/luni/src/main/java/libcore/util/ZoneInfoDB.java
+++ b/luni/src/main/java/libcore/util/ZoneInfoDB.java
@@ -37,9 +37,12 @@
  * @hide - used to implement TimeZone
  */
 public final class ZoneInfoDB {
-  private static final TzData DATA = TzData.loadTzDataWithFallback(
-          System.getenv("ANDROID_DATA") + "/misc/zoneinfo/current/tzdata",
-          System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata");
+
+  // VisibleForTesting
+  public static final String TZDATA_FILE = "tzdata";
+
+  private static final TzData DATA =
+          TzData.loadTzDataWithFallback(TimeZoneDataFiles.getTimeZoneFilePaths(TZDATA_FILE));
 
   public static class TzData {
 
@@ -114,7 +117,7 @@
       // We didn't find any usable tzdata on disk, so let's just hard-code knowledge of "GMT".
       // This is actually implemented in TimeZone itself, so if this is the only time zone
       // we report, we won't be asked any more questions.
-      System.logE("Couldn't find any tzdata!");
+      System.logE("Couldn't find any " + TZDATA_FILE + " file!");
       return TzData.createFallback();
     }
 
@@ -183,7 +186,7 @@
 
         // Something's wrong with the file.
         // Log the problem and return false so we try the next choice.
-        System.logE("tzdata file \"" + path + "\" was present but invalid!", ex);
+        System.logE(TZDATA_FILE + " file \"" + path + "\" was present but invalid!", ex);
         return false;
       }
     }
diff --git a/luni/src/main/native/Register.cpp b/luni/src/main/native/Register.cpp
index 3c244ef..f642211 100644
--- a/luni/src/main/native/Register.cpp
+++ b/luni/src/main/native/Register.cpp
@@ -44,8 +44,8 @@
     REGISTER(register_libcore_icu_NativeConverter);
     REGISTER(register_libcore_icu_TimeZoneNames);
     REGISTER(register_libcore_io_AsynchronousCloseMonitor);
+    REGISTER(register_libcore_io_Linux);
     REGISTER(register_libcore_io_Memory);
-    REGISTER(register_libcore_io_Posix);
     REGISTER(register_libcore_util_NativeAllocationRegistry);
     REGISTER(register_org_apache_harmony_dalvik_NativeTestTarget);
     REGISTER(register_org_apache_harmony_xml_ExpatParser);
diff --git a/luni/src/main/native/android_system_OsConstants.cpp b/luni/src/main/native/android_system_OsConstants.cpp
index 3cb3ee9..3ae4af6 100644
--- a/luni/src/main/native/android_system_OsConstants.cpp
+++ b/luni/src/main/native/android_system_OsConstants.cpp
@@ -342,6 +342,9 @@
     initConstant(env, c, "IP_RECVTOS", IP_RECVTOS);
     initConstant(env, c, "IP_TOS", IP_TOS);
     initConstant(env, c, "IP_TTL", IP_TTL);
+#if defined(_LINUX_CAPABILITY_VERSION_3)
+    initConstant(env, c, "_LINUX_CAPABILITY_VERSION_3", _LINUX_CAPABILITY_VERSION_3);
+#endif
     initConstant(env, c, "MAP_FIXED", MAP_FIXED);
     initConstant(env, c, "MAP_POPULATE", MAP_POPULATE);
     initConstant(env, c, "MAP_PRIVATE", MAP_PRIVATE);
@@ -406,6 +409,12 @@
     initConstant(env, c, "POLLRDNORM", POLLRDNORM);
     initConstant(env, c, "POLLWRBAND", POLLWRBAND);
     initConstant(env, c, "POLLWRNORM", POLLWRNORM);
+#if defined(PR_CAP_AMBIENT)
+    initConstant(env, c, "PR_CAP_AMBIENT", PR_CAP_AMBIENT);
+#endif
+#if defined(PR_CAP_AMBIENT_RAISE)
+    initConstant(env, c, "PR_CAP_AMBIENT_RAISE", PR_CAP_AMBIENT_RAISE);
+#endif
 #if defined(PR_GET_DUMPABLE)
     initConstant(env, c, "PR_GET_DUMPABLE", PR_GET_DUMPABLE);
 #endif
diff --git a/luni/src/main/native/libcore_icu_ICU.cpp b/luni/src/main/native/libcore_icu_ICU.cpp
index 46594c6..0e9a2bc 100644
--- a/luni/src/main/native/libcore_icu_ICU.cpp
+++ b/luni/src/main/native/libcore_icu_ICU.cpp
@@ -57,6 +57,7 @@
 #include "unicode/timezone.h"
 #include "unicode/ubrk.h"
 #include "unicode/ucal.h"
+#include "unicode/ucasemap.h"
 #include "unicode/uclean.h"
 #include "unicode/ucol.h"
 #include "unicode/ucurr.h"
diff --git a/luni/src/main/native/libcore_io_Posix.cpp b/luni/src/main/native/libcore_io_Linux.cpp
similarity index 77%
rename from luni/src/main/native/libcore_io_Posix.cpp
rename to luni/src/main/native/libcore_io_Linux.cpp
index d150052..1e2f3a5 100644
--- a/luni/src/main/native/libcore_io_Posix.cpp
+++ b/luni/src/main/native/libcore_io_Linux.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "Posix"
+#define LOG_TAG "Linux"
 
 #include <arpa/inet.h>
 #include <errno.h>
@@ -29,6 +29,7 @@
 #include <pwd.h>
 #include <signal.h>
 #include <stdlib.h>
+#include <sys/capability.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
 #include <sys/prctl.h>
@@ -100,7 +101,7 @@
  *
  * This is needed because all sockets created by the java.net APIs are IPv6 sockets, and on those
  * sockets, IPv4 operations use IPv4-mapped addresses stored in a struct sockaddr_in6. But sockets
- * created using Posix.socket(AF_INET, ...) are IPv4 sockets and only support operations using IPv4
+ * created using Linux.socket(AF_INET, ...) are IPv4 sockets and only support operations using IPv4
  * socket addresses structures.
  */
 #define NET_IPV4_FALLBACK(jni_env, return_type, syscall_name, java_fd, java_addr, port, null_addr_ok, args...) ({ \
@@ -732,7 +733,155 @@
     struct passwd* mResult;
 };
 
-static jobject Posix_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
+static void AssertException(JNIEnv* env) {
+    if (env->ExceptionCheck() == JNI_FALSE) {
+        env->FatalError("Expected exception");
+    }
+}
+
+// Note for capabilities functions:
+// We assume the calls are rare enough that it does not make sense to cache class objects. The
+// advantage is lower maintenance burden.
+
+static bool ReadStructCapUserHeader(
+        JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
+    if (java_header == nullptr) {
+        jniThrowNullPointerException(env, "header is null");
+        return false;
+    }
+
+    ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+    if (header_class.get() == nullptr) {
+        return false;
+    }
+
+    {
+        static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
+        if (version_fid == nullptr) {
+            return false;
+        }
+        c_header->version = env->GetIntField(java_header, version_fid);
+    }
+
+    {
+        static jfieldID pid_fid = env->GetFieldID(header_class.get(), "pid", "I");
+        if (pid_fid == nullptr) {
+            return false;
+        }
+        c_header->pid = env->GetIntField(java_header, pid_fid);
+    }
+
+    return true;
+}
+
+static void SetStructCapUserHeaderVersion(
+        JNIEnv* env, jobject java_header, __user_cap_header_struct* c_header) {
+    ScopedLocalRef<jclass> header_class(env, env->FindClass("android/system/StructCapUserHeader"));
+    if (header_class.get() == nullptr) {
+        env->ExceptionClear();
+        return;
+    }
+
+    static jfieldID version_fid = env->GetFieldID(header_class.get(), "version", "I");
+    if (version_fid == nullptr) {
+        env->ExceptionClear();
+        return;
+    }
+    env->SetIntField(java_header, version_fid, c_header->version);
+}
+
+static jobject CreateStructCapUserData(
+        JNIEnv* env, jclass data_class, __user_cap_data_struct* c_data) {
+    if (c_data == nullptr) {
+        // Should not happen.
+        jniThrowNullPointerException(env, "data is null");
+        return nullptr;
+    }
+
+    static jmethodID data_cons = env->GetMethodID(data_class, "<init>", "(III)V");
+    if (data_cons == nullptr) {
+        return nullptr;
+    }
+
+    jint e = static_cast<jint>(c_data->effective);
+    jint p = static_cast<jint>(c_data->permitted);
+    jint i = static_cast<jint>(c_data->inheritable);
+    return env->NewObject(data_class, data_cons, e, p, i);
+}
+
+static bool ReadStructCapUserData(JNIEnv* env, jobject java_data, __user_cap_data_struct* c_data) {
+    if (java_data == nullptr) {
+        jniThrowNullPointerException(env, "data is null");
+        return false;
+    }
+
+    ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+    if (data_class.get() == nullptr) {
+        return false;
+    }
+
+    {
+        static jfieldID effective_fid = env->GetFieldID(data_class.get(), "effective", "I");
+        if (effective_fid == nullptr) {
+            return false;
+        }
+        c_data->effective = env->GetIntField(java_data, effective_fid);
+    }
+
+    {
+        static jfieldID permitted_fid = env->GetFieldID(data_class.get(), "permitted", "I");
+        if (permitted_fid == nullptr) {
+            return false;
+        }
+        c_data->permitted = env->GetIntField(java_data, permitted_fid);
+    }
+
+
+    {
+        static jfieldID inheritable_fid = env->GetFieldID(data_class.get(), "inheritable", "I");
+        if (inheritable_fid == nullptr) {
+            return false;
+        }
+        c_data->inheritable = env->GetIntField(java_data, inheritable_fid);
+    }
+
+    return true;
+}
+
+static constexpr size_t kMaxCapUserDataLength = 2U;
+#ifdef _LINUX_CAPABILITY_VERSION_1
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_1, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_2
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_2, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_3
+static_assert(kMaxCapUserDataLength >= _LINUX_CAPABILITY_U32S_3, "Length too small.");
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_4
+static_assert(false, "Unsupported capability version, please update.");
+#endif
+
+static size_t GetCapUserDataLength(uint32_t version) {
+#ifdef _LINUX_CAPABILITY_VERSION_1
+    if (version == _LINUX_CAPABILITY_VERSION_1) {
+        return _LINUX_CAPABILITY_U32S_1;
+    }
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_2
+    if (version == _LINUX_CAPABILITY_VERSION_2) {
+        return _LINUX_CAPABILITY_U32S_2;
+    }
+#endif
+#ifdef _LINUX_CAPABILITY_VERSION_3
+    if (version == _LINUX_CAPABILITY_VERSION_3) {
+        return _LINUX_CAPABILITY_U32S_3;
+    }
+#endif
+    return 0;
+}
+
+static jobject Linux_accept(JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
     sockaddr_storage ss;
     socklen_t sl = sizeof(ss);
     memset(&ss, 0, sizeof(ss));
@@ -746,7 +895,7 @@
     return (clientFd != -1) ? jniCreateFileDescriptor(env, clientFd) : NULL;
 }
 
-static jboolean Posix_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static jboolean Linux_access(JNIEnv* env, jobject, jstring javaPath, jint mode) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return JNI_FALSE;
@@ -758,12 +907,12 @@
     return (rc == 0);
 }
 
-static void Posix_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
+static void Linux_bind(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
     // We don't need the return value because we'll already have thrown.
     (void) NET_IPV4_FALLBACK(env, int, bind, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN);
 }
 
-static void Posix_bindSocketAddress(
+static void Linux_bindSocketAddress(
         JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
     sockaddr_storage ss;
     socklen_t sa_len;
@@ -776,7 +925,84 @@
     (void) NET_FAILURE_RETRY(env, int, bind, javaFd, sa, sa_len);
 }
 
-static void Posix_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static jobjectArray Linux_capget(JNIEnv* env, jobject, jobject header) {
+    // Convert Java header struct to kernel datastructure.
+    __user_cap_header_struct cap_header;
+    if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+        AssertException(env);
+        return nullptr;
+    }
+
+    // Call capget.
+    __user_cap_data_struct cap_data[kMaxCapUserDataLength];
+    if (capget(&cap_header, &cap_data[0]) == -1) {
+        // Check for EINVAL. In that case, mutate the header.
+        if (errno == EINVAL) {
+            int saved_errno = errno;
+            SetStructCapUserHeaderVersion(env, header, &cap_header);
+            errno = saved_errno;
+        }
+        throwErrnoException(env, "capget");
+        return nullptr;
+    }
+
+    // Create the result array.
+    ScopedLocalRef<jclass> data_class(env, env->FindClass("android/system/StructCapUserData"));
+    if (data_class.get() == nullptr) {
+        return nullptr;
+    }
+    size_t result_size = GetCapUserDataLength(cap_header.version);
+    ScopedLocalRef<jobjectArray> result(
+            env, env->NewObjectArray(result_size, data_class.get(), nullptr));
+    if (result.get() == nullptr) {
+        return nullptr;
+    }
+    // Translate the values we got.
+    for (size_t i = 0; i < result_size; ++i) {
+        ScopedLocalRef<jobject> value(
+                env, CreateStructCapUserData(env, data_class.get(), &cap_data[i]));
+        if (value.get() == nullptr) {
+            AssertException(env);
+            return nullptr;
+        }
+        env->SetObjectArrayElement(result.get(), i, value.get());
+    }
+    return result.release();
+}
+
+static void Linux_capset(
+        JNIEnv* env, jobject, jobject header, jobjectArray data) {
+    // Convert Java header struct to kernel datastructure.
+    __user_cap_header_struct cap_header;
+    if (!ReadStructCapUserHeader(env, header, &cap_header)) {
+        AssertException(env);
+        return;
+    }
+    size_t result_size = GetCapUserDataLength(cap_header.version);
+    // Ensure that the array has the expected length.
+    if (env->GetArrayLength(data) != static_cast<jint>(result_size)) {
+        jniThrowExceptionFmt(env,
+                             "java/lang/IllegalArgumentException",
+                             "Unsupported input length %d (expected %zu)",
+                             env->GetArrayLength(data),
+                             result_size);
+        return;
+    }
+
+    __user_cap_data_struct cap_data[kMaxCapUserDataLength];
+    // Translate the values we got.
+    for (size_t i = 0; i < result_size; ++i) {
+        ScopedLocalRef<jobject> value(env, env->GetObjectArrayElement(data, i));
+        if (!ReadStructCapUserData(env, value.get(), &cap_data[i])) {
+            AssertException(env);
+            return;
+        }
+    }
+
+    throwIfMinusOne(env, "capset", capset(&cap_header, &cap_data[0]));
+}
+
+static void Linux_chmod(JNIEnv* env, jobject, jstring javaPath, jint mode) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -784,7 +1010,7 @@
     throwIfMinusOne(env, "chmod", TEMP_FAILURE_RETRY(chmod(path.c_str(), mode)));
 }
 
-static void Posix_chown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
+static void Linux_chown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -792,7 +1018,7 @@
     throwIfMinusOne(env, "chown", TEMP_FAILURE_RETRY(chown(path.c_str(), uid, gid)));
 }
 
-static void Posix_close(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_close(JNIEnv* env, jobject, jobject javaFd) {
     // Get the FileDescriptor's 'fd' field and clear it.
     // We need to do this before we can throw an IOException (http://b/3222087).
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -804,11 +1030,11 @@
     throwIfMinusOne(env, "close", close(fd));
 }
 
-static void Posix_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
+static void Linux_connect(JNIEnv* env, jobject, jobject javaFd, jobject javaAddress, jint port) {
     (void) NET_IPV4_FALLBACK(env, int, connect, javaFd, javaAddress, port, NULL_ADDR_FORBIDDEN);
 }
 
-static void Posix_connectSocketAddress(
+static void Linux_connectSocketAddress(
         JNIEnv* env, jobject, jobject javaFd, jobject javaSocketAddress) {
     sockaddr_storage ss;
     socklen_t sa_len;
@@ -821,24 +1047,24 @@
     (void) NET_FAILURE_RETRY(env, int, connect, javaFd, sa, sa_len);
 }
 
-static jobject Posix_dup(JNIEnv* env, jobject, jobject javaOldFd) {
+static jobject Linux_dup(JNIEnv* env, jobject, jobject javaOldFd) {
     int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
     int newFd = throwIfMinusOne(env, "dup", TEMP_FAILURE_RETRY(dup(oldFd)));
     return (newFd != -1) ? jniCreateFileDescriptor(env, newFd) : NULL;
 }
 
-static jobject Posix_dup2(JNIEnv* env, jobject, jobject javaOldFd, jint newFd) {
+static jobject Linux_dup2(JNIEnv* env, jobject, jobject javaOldFd, jint newFd) {
     int oldFd = jniGetFDFromFileDescriptor(env, javaOldFd);
     int fd = throwIfMinusOne(env, "dup2", TEMP_FAILURE_RETRY(dup2(oldFd, newFd)));
     return (fd != -1) ? jniCreateFileDescriptor(env, fd) : NULL;
 }
 
-static jobjectArray Posix_environ(JNIEnv* env, jobject) {
+static jobjectArray Linux_environ(JNIEnv* env, jobject) {
     extern char** environ; // Standard, but not in any header file.
     return toStringArray(env, environ);
 }
 
-static void Posix_execve(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv, jobjectArray javaEnvp) {
+static void Linux_execve(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv, jobjectArray javaEnvp) {
     ScopedUtfChars path(env, javaFilename);
     if (path.c_str() == NULL) {
         return;
@@ -851,7 +1077,7 @@
     throwErrnoException(env, "execve");
 }
 
-static void Posix_execv(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv) {
+static void Linux_execv(JNIEnv* env, jobject, jstring javaFilename, jobjectArray javaArgv) {
     ScopedUtfChars path(env, javaFilename);
     if (path.c_str() == NULL) {
         return;
@@ -863,17 +1089,17 @@
     throwErrnoException(env, "execv");
 }
 
-static void Posix_fchmod(JNIEnv* env, jobject, jobject javaFd, jint mode) {
+static void Linux_fchmod(JNIEnv* env, jobject, jobject javaFd, jint mode) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "fchmod", TEMP_FAILURE_RETRY(fchmod(fd, mode)));
 }
 
-static void Posix_fchown(JNIEnv* env, jobject, jobject javaFd, jint uid, jint gid) {
+static void Linux_fchown(JNIEnv* env, jobject, jobject javaFd, jint uid, jint gid) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "fchown", TEMP_FAILURE_RETRY(fchown(fd, uid, gid)));
 }
 
-static jint Posix_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) {
+static jint Linux_fcntlFlock(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaFlock) {
     static jfieldID typeFid = env->GetFieldID(JniConstants::structFlockClass, "l_type", "S");
     static jfieldID whenceFid = env->GetFieldID(JniConstants::structFlockClass, "l_whence", "S");
     static jfieldID startFid = env->GetFieldID(JniConstants::structFlockClass, "l_start", "J");
@@ -899,22 +1125,22 @@
     return rc;
 }
 
-static jint Posix_fcntlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jint arg) {
+static jint Linux_fcntlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jint arg) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd, arg)));
 }
 
-static jint Posix_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) {
+static jint Linux_fcntlVoid(JNIEnv* env, jobject, jobject javaFd, jint cmd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     return throwIfMinusOne(env, "fcntl", TEMP_FAILURE_RETRY(fcntl(fd, cmd)));
 }
 
-static void Posix_fdatasync(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_fdatasync(JNIEnv* env, jobject, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "fdatasync", TEMP_FAILURE_RETRY(fdatasync(fd)));
 }
 
-static jobject Posix_fstat(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_fstat(JNIEnv* env, jobject, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     struct stat64 sb;
     int rc = TEMP_FAILURE_RETRY(fstat64(fd, &sb));
@@ -925,7 +1151,7 @@
     return makeStructStat(env, sb);
 }
 
-static jobject Posix_fstatvfs(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_fstatvfs(JNIEnv* env, jobject, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     struct statvfs sb;
     int rc = TEMP_FAILURE_RETRY(fstatvfs(fd, &sb));
@@ -936,21 +1162,21 @@
     return makeStructStatVfs(env, sb);
 }
 
-static void Posix_fsync(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_fsync(JNIEnv* env, jobject, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "fsync", TEMP_FAILURE_RETRY(fsync(fd)));
 }
 
-static void Posix_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) {
+static void Linux_ftruncate(JNIEnv* env, jobject, jobject javaFd, jlong length) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "ftruncate", TEMP_FAILURE_RETRY(ftruncate64(fd, length)));
 }
 
-static jstring Posix_gai_strerror(JNIEnv* env, jobject, jint error) {
+static jstring Linux_gai_strerror(JNIEnv* env, jobject, jint error) {
     return env->NewStringUTF(gai_strerror(error));
 }
 
-static jobjectArray Posix_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
+static jobjectArray Linux_android_getaddrinfo(JNIEnv* env, jobject, jstring javaNode,
         jobject javaHints, jint netId) {
     ScopedUtfChars node(env, javaNode);
     if (node.c_str() == NULL) {
@@ -1018,19 +1244,19 @@
     return result;
 }
 
-static jint Posix_getegid(JNIEnv*, jobject) {
+static jint Linux_getegid(JNIEnv*, jobject) {
     return getegid();
 }
 
-static jint Posix_geteuid(JNIEnv*, jobject) {
+static jint Linux_geteuid(JNIEnv*, jobject) {
     return geteuid();
 }
 
-static jint Posix_getgid(JNIEnv*, jobject) {
+static jint Linux_getgid(JNIEnv*, jobject) {
     return getgid();
 }
 
-static jstring Posix_getenv(JNIEnv* env, jobject, jstring javaName) {
+static jstring Linux_getenv(JNIEnv* env, jobject, jstring javaName) {
     ScopedUtfChars name(env, javaName);
     if (name.c_str() == NULL) {
         return NULL;
@@ -1038,7 +1264,7 @@
     return env->NewStringUTF(getenv(name.c_str()));
 }
 
-static jstring Posix_getnameinfo(JNIEnv* env, jobject, jobject javaAddress, jint flags) {
+static jstring Linux_getnameinfo(JNIEnv* env, jobject, jobject javaAddress, jint flags) {
     sockaddr_storage ss;
     socklen_t sa_len;
     if (!inetAddressToSockaddrVerbatim(env, javaAddress, 0, ss, sa_len)) {
@@ -1054,23 +1280,23 @@
     return env->NewStringUTF(buf);
 }
 
-static jobject Posix_getpeername(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_getpeername(JNIEnv* env, jobject, jobject javaFd) {
   return doGetSockName(env, javaFd, false);
 }
 
-static jint Posix_getpgid(JNIEnv* env, jobject, jint pid) {
+static jint Linux_getpgid(JNIEnv* env, jobject, jint pid) {
     return throwIfMinusOne(env, "getpgid", TEMP_FAILURE_RETRY(getpgid(pid)));
 }
 
-static jint Posix_getpid(JNIEnv*, jobject) {
+static jint Linux_getpid(JNIEnv*, jobject) {
     return TEMP_FAILURE_RETRY(getpid());
 }
 
-static jint Posix_getppid(JNIEnv*, jobject) {
+static jint Linux_getppid(JNIEnv*, jobject) {
     return TEMP_FAILURE_RETRY(getppid());
 }
 
-static jobject Posix_getpwnam(JNIEnv* env, jobject, jstring javaName) {
+static jobject Linux_getpwnam(JNIEnv* env, jobject, jstring javaName) {
     ScopedUtfChars name(env, javaName);
     if (name.c_str() == NULL) {
         return NULL;
@@ -1078,15 +1304,15 @@
     return Passwd(env).getpwnam(name.c_str());
 }
 
-static jobject Posix_getpwuid(JNIEnv* env, jobject, jint uid) {
+static jobject Linux_getpwuid(JNIEnv* env, jobject, jint uid) {
     return Passwd(env).getpwuid(uid);
 }
 
-static jobject Posix_getsockname(JNIEnv* env, jobject, jobject javaFd) {
+static jobject Linux_getsockname(JNIEnv* env, jobject, jobject javaFd) {
   return doGetSockName(env, javaFd, true);
 }
 
-static jint Posix_getsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jint Linux_getsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     u_char result = 0;
     socklen_t size = sizeof(result);
@@ -1094,7 +1320,7 @@
     return result;
 }
 
-static jobject Posix_getsockoptInAddr(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptInAddr(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     sockaddr_storage ss;
     memset(&ss, 0, sizeof(ss));
@@ -1109,7 +1335,7 @@
     return sockaddrToInetAddress(env, ss, NULL);
 }
 
-static jint Posix_getsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jint Linux_getsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     jint result = 0;
     socklen_t size = sizeof(result);
@@ -1117,7 +1343,7 @@
     return result;
 }
 
-static jobject Posix_getsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     struct linger l;
     socklen_t size = sizeof(l);
@@ -1130,7 +1356,7 @@
     return makeStructLinger(env, l);
 }
 
-static jobject Posix_getsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     struct timeval tv;
     socklen_t size = sizeof(tv);
@@ -1143,7 +1369,7 @@
     return makeStructTimeval(env, tv);
 }
 
-static jobject Posix_getsockoptUcred(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
+static jobject Linux_getsockoptUcred(JNIEnv* env, jobject, jobject javaFd, jint level, jint option) {
   int fd = jniGetFDFromFileDescriptor(env, javaFd);
   struct ucred u;
   socklen_t size = sizeof(u);
@@ -1156,7 +1382,7 @@
   return makeStructUcred(env, u);
 }
 
-static jint Posix_gettid(JNIEnv* env __unused, jobject) {
+static jint Linux_gettid(JNIEnv* env __unused, jobject) {
 #if defined(__BIONIC__)
   return TEMP_FAILURE_RETRY(gettid());
 #else
@@ -1164,11 +1390,11 @@
 #endif
 }
 
-static jint Posix_getuid(JNIEnv*, jobject) {
+static jint Linux_getuid(JNIEnv*, jobject) {
     return getuid();
 }
 
-static jbyteArray Posix_getxattr(JNIEnv* env, jobject, jstring javaPath,
+static jbyteArray Linux_getxattr(JNIEnv* env, jobject, jstring javaPath,
         jstring javaName) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
@@ -1207,7 +1433,7 @@
     }
 }
 
-static jobjectArray Posix_getifaddrs(JNIEnv* env, jobject) {
+static jobjectArray Linux_getifaddrs(JNIEnv* env, jobject) {
     static jmethodID ctor = env->GetMethodID(JniConstants::structIfaddrs, "<init>",
             "(Ljava/lang/String;ILjava/net/InetAddress;Ljava/net/InetAddress;Ljava/net/InetAddress;[B)V");
 
@@ -1302,7 +1528,7 @@
     return result;
 }
 
-static jstring Posix_if_indextoname(JNIEnv* env, jobject, jint index) {
+static jstring Linux_if_indextoname(JNIEnv* env, jobject, jint index) {
     char buf[IF_NAMESIZE];
     char* name = if_indextoname(index, buf);
     // if_indextoname(3) returns NULL on failure, which will come out of NewStringUTF unscathed.
@@ -1310,7 +1536,7 @@
     return env->NewStringUTF(name);
 }
 
-static jint Posix_if_nametoindex(JNIEnv* env, jobject, jstring name) {
+static jint Linux_if_nametoindex(JNIEnv* env, jobject, jstring name) {
     ScopedUtfChars cname(env, name);
     if (cname.c_str() == NULL) {
         return 0;
@@ -1320,7 +1546,7 @@
     return if_nametoindex(cname.c_str());
 }
 
-static jobject Posix_inet_pton(JNIEnv* env, jobject, jint family, jstring javaName) {
+static jobject Linux_inet_pton(JNIEnv* env, jobject, jint family, jstring javaName) {
     ScopedUtfChars name(env, javaName);
     if (name.c_str() == NULL) {
         return NULL;
@@ -1336,7 +1562,7 @@
     return sockaddrToInetAddress(env, ss, NULL);
 }
 
-static jint Posix_ioctlFlags(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
+static jint Linux_ioctlFlags(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
      struct ifreq req;
      if (!fillIfreq(env, javaInterfaceName, req)) {
         return 0;
@@ -1346,7 +1572,7 @@
      return req.ifr_flags;
 }
 
-static jobject Posix_ioctlInetAddress(JNIEnv* env, jobject, jobject javaFd, jint cmd, jstring javaInterfaceName) {
+static jobject Linux_ioctlInetAddress(JNIEnv* env, jobject, jobject javaFd, jint cmd, jstring javaInterfaceName) {
     struct ifreq req;
     if (!fillIfreq(env, javaInterfaceName, req)) {
         return NULL;
@@ -1359,7 +1585,7 @@
     return sockaddrToInetAddress(env, reinterpret_cast<sockaddr_storage&>(req.ifr_addr), NULL);
 }
 
-static jint Posix_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaArg) {
+static jint Linux_ioctlInt(JNIEnv* env, jobject, jobject javaFd, jint cmd, jobject javaArg) {
     // This is complicated because ioctls may return their result by updating their argument
     // or via their return value, so we need to support both.
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -1372,7 +1598,7 @@
     return rc;
 }
 
-static jint Posix_ioctlMTU(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
+static jint Linux_ioctlMTU(JNIEnv* env, jobject, jobject javaFd, jstring javaInterfaceName) {
      struct ifreq req;
      if (!fillIfreq(env, javaInterfaceName, req)) {
         return 0;
@@ -1382,16 +1608,16 @@
      return req.ifr_mtu;
 }
 
-static jboolean Posix_isatty(JNIEnv* env, jobject, jobject javaFd) {
+static jboolean Linux_isatty(JNIEnv* env, jobject, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     return TEMP_FAILURE_RETRY(isatty(fd)) == 1;
 }
 
-static void Posix_kill(JNIEnv* env, jobject, jint pid, jint sig) {
+static void Linux_kill(JNIEnv* env, jobject, jint pid, jint sig) {
     throwIfMinusOne(env, "kill", TEMP_FAILURE_RETRY(kill(pid, sig)));
 }
 
-static void Posix_lchown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
+static void Linux_lchown(JNIEnv* env, jobject, jstring javaPath, jint uid, jint gid) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -1399,7 +1625,7 @@
     throwIfMinusOne(env, "lchown", TEMP_FAILURE_RETRY(lchown(path.c_str(), uid, gid)));
 }
 
-static void Posix_link(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+static void Linux_link(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
     ScopedUtfChars oldPath(env, javaOldPath);
     if (oldPath.c_str() == NULL) {
         return;
@@ -1411,12 +1637,12 @@
     throwIfMinusOne(env, "link", TEMP_FAILURE_RETRY(link(oldPath.c_str(), newPath.c_str())));
 }
 
-static void Posix_listen(JNIEnv* env, jobject, jobject javaFd, jint backlog) {
+static void Linux_listen(JNIEnv* env, jobject, jobject javaFd, jint backlog) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "listen", TEMP_FAILURE_RETRY(listen(fd, backlog)));
 }
 
-static jobjectArray Posix_listxattr(JNIEnv* env, jobject, jstring javaPath) {
+static jobjectArray Linux_listxattr(JNIEnv* env, jobject, jstring javaPath) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return NULL;
@@ -1451,16 +1677,16 @@
     }
 }
 
-static jlong Posix_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) {
+static jlong Linux_lseek(JNIEnv* env, jobject, jobject javaFd, jlong offset, jint whence) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     return throwIfMinusOne(env, "lseek", TEMP_FAILURE_RETRY(lseek64(fd, offset, whence)));
 }
 
-static jobject Posix_lstat(JNIEnv* env, jobject, jstring javaPath) {
+static jobject Linux_lstat(JNIEnv* env, jobject, jstring javaPath) {
     return doStat(env, javaPath, true);
 }
 
-static void Posix_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
+static void Linux_mincore(JNIEnv* env, jobject, jlong address, jlong byteCount, jbyteArray javaVector) {
     ScopedByteArrayRW vector(env, javaVector);
     if (vector.get() == NULL) {
         return;
@@ -1470,7 +1696,7 @@
     throwIfMinusOne(env, "mincore", TEMP_FAILURE_RETRY(mincore(ptr, byteCount, vec)));
 }
 
-static void Posix_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static void Linux_mkdir(JNIEnv* env, jobject, jstring javaPath, jint mode) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -1478,7 +1704,7 @@
     throwIfMinusOne(env, "mkdir", TEMP_FAILURE_RETRY(mkdir(path.c_str(), mode)));
 }
 
-static void Posix_mkfifo(JNIEnv* env, jobject, jstring javaPath, jint mode) {
+static void Linux_mkfifo(JNIEnv* env, jobject, jstring javaPath, jint mode) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -1486,12 +1712,12 @@
     throwIfMinusOne(env, "mkfifo", TEMP_FAILURE_RETRY(mkfifo(path.c_str(), mode)));
 }
 
-static void Posix_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
+static void Linux_mlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
     throwIfMinusOne(env, "mlock", TEMP_FAILURE_RETRY(mlock(ptr, byteCount)));
 }
 
-static jlong Posix_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) {
+static jlong Linux_mmap(JNIEnv* env, jobject, jlong address, jlong byteCount, jint prot, jint flags, jobject javaFd, jlong offset) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     void* suggestedPtr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
     void* ptr = mmap64(suggestedPtr, byteCount, prot, flags, fd, offset);
@@ -1501,22 +1727,22 @@
     return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr));
 }
 
-static void Posix_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) {
+static void Linux_msync(JNIEnv* env, jobject, jlong address, jlong byteCount, jint flags) {
     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
     throwIfMinusOne(env, "msync", TEMP_FAILURE_RETRY(msync(ptr, byteCount, flags)));
 }
 
-static void Posix_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
+static void Linux_munlock(JNIEnv* env, jobject, jlong address, jlong byteCount) {
     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
     throwIfMinusOne(env, "munlock", TEMP_FAILURE_RETRY(munlock(ptr, byteCount)));
 }
 
-static void Posix_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) {
+static void Linux_munmap(JNIEnv* env, jobject, jlong address, jlong byteCount) {
     void* ptr = reinterpret_cast<void*>(static_cast<uintptr_t>(address));
     throwIfMinusOne(env, "munmap", TEMP_FAILURE_RETRY(munmap(ptr, byteCount)));
 }
 
-static jobject Posix_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) {
+static jobject Linux_open(JNIEnv* env, jobject, jstring javaPath, jint flags, jint mode) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return NULL;
@@ -1525,7 +1751,7 @@
     return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
 }
 
-static jobjectArray Posix_pipe2(JNIEnv* env, jobject, jint flags __unused) {
+static jobjectArray Linux_pipe2(JNIEnv* env, jobject, jint flags __unused) {
     int fds[2];
     throwIfMinusOne(env, "pipe2", TEMP_FAILURE_RETRY(pipe2(&fds[0], flags)));
     jobjectArray result = env->NewObjectArray(2, JniConstants::fileDescriptorClass, NULL);
@@ -1545,7 +1771,7 @@
     return result;
 }
 
-static jint Posix_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
+static jint Linux_poll(JNIEnv* env, jobject, jobjectArray javaStructs, jint timeoutMs) {
     static jfieldID fdFid = env->GetFieldID(JniConstants::structPollfdClass, "fd", "Ljava/io/FileDescriptor;");
     static jfieldID eventsFid = env->GetFieldID(JniConstants::structPollfdClass, "events", "S");
     static jfieldID reventsFid = env->GetFieldID(JniConstants::structPollfdClass, "revents", "S");
@@ -1626,7 +1852,7 @@
     return rc;
 }
 
-static void Posix_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
+static void Linux_posix_fallocate(JNIEnv* env, jobject, jobject javaFd __unused,
                                   jlong offset __unused, jlong length __unused) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     while ((errno = posix_fallocate64(fd, offset, length)) == EINTR) {
@@ -1636,7 +1862,7 @@
     }
 }
 
-static jint Posix_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
+static jint Linux_prctl(JNIEnv* env, jobject, jint option __unused, jlong arg2 __unused,
                         jlong arg3 __unused, jlong arg4 __unused, jlong arg5 __unused) {
     int result = TEMP_FAILURE_RETRY(prctl(static_cast<int>(option),
                                           static_cast<unsigned long>(arg2),
@@ -1646,7 +1872,7 @@
     return throwIfMinusOne(env, "prctl", result);
 }
 
-static jint Posix_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
+static jint Linux_preadBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jlong offset) {
     ScopedBytesRW bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -1654,7 +1880,7 @@
     return IO_FAILURE_RETRY(env, ssize_t, pread64, javaFd, bytes.get() + byteOffset, byteCount, offset);
 }
 
-static jint Posix_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
+static jint Linux_pwriteBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount, jlong offset) {
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -1662,7 +1888,7 @@
     return IO_FAILURE_RETRY(env, ssize_t, pwrite64, javaFd, bytes.get() + byteOffset, byteCount, offset);
 }
 
-static jint Posix_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
+static jint Linux_readBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount) {
     ScopedBytesRW bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -1670,7 +1896,7 @@
     return IO_FAILURE_RETRY(env, ssize_t, read, javaFd, bytes.get() + byteOffset, byteCount);
 }
 
-static jstring Posix_readlink(JNIEnv* env, jobject, jstring javaPath) {
+static jstring Linux_readlink(JNIEnv* env, jobject, jstring javaPath) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return NULL;
@@ -1684,7 +1910,7 @@
     return env->NewStringUTF(result.c_str());
 }
 
-static jstring Posix_realpath(JNIEnv* env, jobject, jstring javaPath) {
+static jstring Linux_realpath(JNIEnv* env, jobject, jstring javaPath) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return NULL;
@@ -1699,7 +1925,7 @@
     return env->NewStringUTF(real_path.get());
 }
 
-static jint Posix_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
+static jint Linux_readv(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
     IoVec<ScopedBytesRW> ioVec(env, env->GetArrayLength(buffers));
     if (!ioVec.init(buffers, offsets, byteCounts)) {
         return -1;
@@ -1707,7 +1933,7 @@
     return IO_FAILURE_RETRY(env, ssize_t, readv, javaFd, ioVec.get(), ioVec.size());
 }
 
-static jint Posix_recvfromBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetSocketAddress) {
+static jint Linux_recvfromBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetSocketAddress) {
     ScopedBytesRW bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -1729,7 +1955,7 @@
     return recvCount;
 }
 
-static void Posix_remove(JNIEnv* env, jobject, jstring javaPath) {
+static void Linux_remove(JNIEnv* env, jobject, jstring javaPath) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -1737,7 +1963,7 @@
     throwIfMinusOne(env, "remove", TEMP_FAILURE_RETRY(remove(path.c_str())));
 }
 
-static void Posix_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) {
+static void Linux_removexattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return;
@@ -1753,7 +1979,7 @@
     }
 }
 
-static void Posix_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+static void Linux_rename(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
     ScopedUtfChars oldPath(env, javaOldPath);
     if (oldPath.c_str() == NULL) {
         return;
@@ -1765,7 +1991,7 @@
     throwIfMinusOne(env, "rename", TEMP_FAILURE_RETRY(rename(oldPath.c_str(), newPath.c_str())));
 }
 
-static jlong Posix_sendfile(JNIEnv* env, jobject, jobject javaOutFd, jobject javaInFd, jobject javaOffset, jlong byteCount) {
+static jlong Linux_sendfile(JNIEnv* env, jobject, jobject javaOutFd, jobject javaInFd, jobject javaOffset, jlong byteCount) {
     int outFd = jniGetFDFromFileDescriptor(env, javaOutFd);
     int inFd = jniGetFDFromFileDescriptor(env, javaInFd);
     static jfieldID valueFid = env->GetFieldID(JniConstants::mutableLongClass, "value", "J");
@@ -1783,7 +2009,7 @@
     return result;
 }
 
-static jint Posix_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) {
+static jint Linux_sendtoBytes(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaInetAddress, jint port) {
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -1793,13 +2019,13 @@
                              NULL_ADDR_OK, bytes.get() + byteOffset, byteCount, flags);
 }
 
-static jint Posix_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) {
+static jint Linux_sendtoBytesSocketAddress(JNIEnv* env, jobject, jobject javaFd, jobject javaBytes, jint byteOffset, jint byteCount, jint flags, jobject javaSocketAddress) {
     if (env->IsInstanceOf(javaSocketAddress, JniConstants::inetSocketAddressClass)) {
         // Use the InetAddress version so we get the benefit of NET_IPV4_FALLBACK.
         jobject javaInetAddress;
         jint port;
         javaInetSocketAddressToInetAddressAndPort(env, javaSocketAddress, javaInetAddress, port);
-        return Posix_sendtoBytes(env, NULL, javaFd, javaBytes, byteOffset, byteCount, flags,
+        return Linux_sendtoBytes(env, NULL, javaFd, javaBytes, byteOffset, byteCount, flags,
                                  javaInetAddress, port);
     }
 
@@ -1819,11 +2045,11 @@
     return NET_FAILURE_RETRY(env, ssize_t, sendto, javaFd, bytes.get() + byteOffset, byteCount, flags, sa, sa_len);
 }
 
-static void Posix_setegid(JNIEnv* env, jobject, jint egid) {
+static void Linux_setegid(JNIEnv* env, jobject, jint egid) {
     throwIfMinusOne(env, "setegid", TEMP_FAILURE_RETRY(setegid(egid)));
 }
 
-static void Posix_setenv(JNIEnv* env, jobject, jstring javaName, jstring javaValue, jboolean overwrite) {
+static void Linux_setenv(JNIEnv* env, jobject, jstring javaName, jstring javaValue, jboolean overwrite) {
     ScopedUtfChars name(env, javaName);
     if (name.c_str() == NULL) {
         return;
@@ -1835,37 +2061,37 @@
     throwIfMinusOne(env, "setenv", setenv(name.c_str(), value.c_str(), overwrite));
 }
 
-static void Posix_seteuid(JNIEnv* env, jobject, jint euid) {
+static void Linux_seteuid(JNIEnv* env, jobject, jint euid) {
     throwIfMinusOne(env, "seteuid", TEMP_FAILURE_RETRY(seteuid(euid)));
 }
 
-static void Posix_setgid(JNIEnv* env, jobject, jint gid) {
+static void Linux_setgid(JNIEnv* env, jobject, jint gid) {
     throwIfMinusOne(env, "setgid", TEMP_FAILURE_RETRY(setgid(gid)));
 }
 
-static void Posix_setpgid(JNIEnv* env, jobject, jint pid, int pgid) {
+static void Linux_setpgid(JNIEnv* env, jobject, jint pid, int pgid) {
     throwIfMinusOne(env, "setpgid", TEMP_FAILURE_RETRY(setpgid(pid, pgid)));
 }
 
-static void Posix_setregid(JNIEnv* env, jobject, jint rgid, int egid) {
+static void Linux_setregid(JNIEnv* env, jobject, jint rgid, int egid) {
     throwIfMinusOne(env, "setregid", TEMP_FAILURE_RETRY(setregid(rgid, egid)));
 }
 
-static void Posix_setreuid(JNIEnv* env, jobject, jint ruid, int euid) {
+static void Linux_setreuid(JNIEnv* env, jobject, jint ruid, int euid) {
     throwIfMinusOne(env, "setreuid", TEMP_FAILURE_RETRY(setreuid(ruid, euid)));
 }
 
-static jint Posix_setsid(JNIEnv* env, jobject) {
+static jint Linux_setsid(JNIEnv* env, jobject) {
     return throwIfMinusOne(env, "setsid", TEMP_FAILURE_RETRY(setsid()));
 }
 
-static void Posix_setsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+static void Linux_setsockoptByte(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     u_char byte = value;
     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &byte, sizeof(byte))));
 }
 
-static void Posix_setsockoptIfreq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jstring javaInterfaceName) {
+static void Linux_setsockoptIfreq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jstring javaInterfaceName) {
     struct ifreq req;
     if (!fillIfreq(env, javaInterfaceName, req)) {
         return;
@@ -1874,12 +2100,12 @@
     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
 }
 
-static void Posix_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+static void Linux_setsockoptInt(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
 }
 
-static void Posix_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
+static void Linux_setsockoptIpMreqn(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jint value) {
     ip_mreqn req;
     memset(&req, 0, sizeof(req));
     req.imr_ifindex = value;
@@ -1887,7 +2113,7 @@
     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &req, sizeof(req))));
 }
 
-static void Posix_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupReq) {
+static void Linux_setsockoptGroupReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupReq) {
     struct group_req req;
     memset(&req, 0, sizeof(req));
 
@@ -1920,7 +2146,7 @@
     throwIfMinusOne(env, "setsockopt", rc);
 }
 
-static void Posix_setsockoptGroupSourceReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupSourceReq) {
+static void Linux_setsockoptGroupSourceReq(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaGroupSourceReq) {
     socklen_t sa_len;
     struct group_source_req req;
     memset(&req, 0, sizeof(req));
@@ -1962,7 +2188,7 @@
     throwIfMinusOne(env, "setsockopt", rc);
 }
 
-static void Posix_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
+static void Linux_setsockoptLinger(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaLinger) {
     static jfieldID lOnoffFid = env->GetFieldID(JniConstants::structLingerClass, "l_onoff", "I");
     static jfieldID lLingerFid = env->GetFieldID(JniConstants::structLingerClass, "l_linger", "I");
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -1972,7 +2198,7 @@
     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
 }
 
-static void Posix_setsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaTimeval) {
+static void Linux_setsockoptTimeval(JNIEnv* env, jobject, jobject javaFd, jint level, jint option, jobject javaTimeval) {
     static jfieldID tvSecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_sec", "J");
     static jfieldID tvUsecFid = env->GetFieldID(JniConstants::structTimevalClass, "tv_usec", "J");
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
@@ -1982,11 +2208,11 @@
     throwIfMinusOne(env, "setsockopt", TEMP_FAILURE_RETRY(setsockopt(fd, level, option, &value, sizeof(value))));
 }
 
-static void Posix_setuid(JNIEnv* env, jobject, jint uid) {
+static void Linux_setuid(JNIEnv* env, jobject, jint uid) {
     throwIfMinusOne(env, "setuid", TEMP_FAILURE_RETRY(setuid(uid)));
 }
 
-static void Posix_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName,
+static void Linux_setxattr(JNIEnv* env, jobject, jstring javaPath, jstring javaName,
         jbyteArray javaValue, jint flags) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
@@ -2007,12 +2233,12 @@
     }
 }
 
-static void Posix_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) {
+static void Linux_shutdown(JNIEnv* env, jobject, jobject javaFd, jint how) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "shutdown", TEMP_FAILURE_RETRY(shutdown(fd, how)));
 }
 
-static jobject Posix_socket(JNIEnv* env, jobject, jint domain, jint type, jint protocol) {
+static jobject Linux_socket(JNIEnv* env, jobject, jint domain, jint type, jint protocol) {
     if (domain == AF_PACKET) {
         protocol = htons(protocol);  // Packet sockets specify the protocol in host byte order.
     }
@@ -2020,7 +2246,7 @@
     return fd != -1 ? jniCreateFileDescriptor(env, fd) : NULL;
 }
 
-static void Posix_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
+static void Linux_socketpair(JNIEnv* env, jobject, jint domain, jint type, jint protocol, jobject javaFd1, jobject javaFd2) {
     int fds[2];
     int rc = throwIfMinusOne(env, "socketpair", TEMP_FAILURE_RETRY(socketpair(domain, type, protocol, fds)));
     if (rc != -1) {
@@ -2029,11 +2255,11 @@
     }
 }
 
-static jobject Posix_stat(JNIEnv* env, jobject, jstring javaPath) {
+static jobject Linux_stat(JNIEnv* env, jobject, jstring javaPath) {
     return doStat(env, javaPath, false);
 }
 
-static jobject Posix_statvfs(JNIEnv* env, jobject, jstring javaPath) {
+static jobject Linux_statvfs(JNIEnv* env, jobject, jstring javaPath) {
     ScopedUtfChars path(env, javaPath);
     if (path.c_str() == NULL) {
         return NULL;
@@ -2047,17 +2273,17 @@
     return makeStructStatVfs(env, sb);
 }
 
-static jstring Posix_strerror(JNIEnv* env, jobject, jint errnum) {
+static jstring Linux_strerror(JNIEnv* env, jobject, jint errnum) {
     char buffer[BUFSIZ];
     const char* message = jniStrError(errnum, buffer, sizeof(buffer));
     return env->NewStringUTF(message);
 }
 
-static jstring Posix_strsignal(JNIEnv* env, jobject, jint signal) {
+static jstring Linux_strsignal(JNIEnv* env, jobject, jint signal) {
     return env->NewStringUTF(strsignal(signal));
 }
 
-static void Posix_symlink(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
+static void Linux_symlink(JNIEnv* env, jobject, jstring javaOldPath, jstring javaNewPath) {
     ScopedUtfChars oldPath(env, javaOldPath);
     if (oldPath.c_str() == NULL) {
         return;
@@ -2069,7 +2295,7 @@
     throwIfMinusOne(env, "symlink", TEMP_FAILURE_RETRY(symlink(oldPath.c_str(), newPath.c_str())));
 }
 
-static jlong Posix_sysconf(JNIEnv* env, jobject, jint name) {
+static jlong Linux_sysconf(JNIEnv* env, jobject, jint name) {
     // Since -1 is a valid result from sysconf(3), detecting failure is a little more awkward.
     errno = 0;
     long result = sysconf(name);
@@ -2079,21 +2305,21 @@
     return result;
 }
 
-static void Posix_tcdrain(JNIEnv* env, jobject, jobject javaFd) {
+static void Linux_tcdrain(JNIEnv* env, jobject, jobject javaFd) {
     int fd = jniGetFDFromFileDescriptor(env, javaFd);
     throwIfMinusOne(env, "tcdrain", TEMP_FAILURE_RETRY(tcdrain(fd)));
 }
 
-static void Posix_tcsendbreak(JNIEnv* env, jobject, jobject javaFd, jint duration) {
+static void Linux_tcsendbreak(JNIEnv* env, jobject, jobject javaFd, jint duration) {
   int fd = jniGetFDFromFileDescriptor(env, javaFd);
   throwIfMinusOne(env, "tcsendbreak", TEMP_FAILURE_RETRY(tcsendbreak(fd, duration)));
 }
 
-static jint Posix_umaskImpl(JNIEnv*, jobject, jint mask) {
+static jint Linux_umaskImpl(JNIEnv*, jobject, jint mask) {
     return umask(mask);
 }
 
-static jobject Posix_uname(JNIEnv* env, jobject) {
+static jobject Linux_uname(JNIEnv* env, jobject) {
     struct utsname buf;
     if (TEMP_FAILURE_RETRY(uname(&buf)) == -1) {
         return NULL; // Can't happen.
@@ -2101,7 +2327,7 @@
     return makeStructUtsname(env, buf);
 }
 
-static void Posix_unlink(JNIEnv* env, jobject, jstring javaPathname) {
+static void Linux_unlink(JNIEnv* env, jobject, jstring javaPathname) {
     ScopedUtfChars pathname(env, javaPathname);
     if (pathname.c_str() == NULL) {
         return;
@@ -2109,7 +2335,7 @@
     throwIfMinusOne(env, "unlink", unlink(pathname.c_str()));
 }
 
-static void Posix_unsetenv(JNIEnv* env, jobject, jstring javaName) {
+static void Linux_unsetenv(JNIEnv* env, jobject, jstring javaName) {
     ScopedUtfChars name(env, javaName);
     if (name.c_str() == NULL) {
         return;
@@ -2117,7 +2343,7 @@
     throwIfMinusOne(env, "unsetenv", unsetenv(name.c_str()));
 }
 
-static jint Posix_waitpid(JNIEnv* env, jobject, jint pid, jobject javaStatus, jint options) {
+static jint Linux_waitpid(JNIEnv* env, jobject, jint pid, jobject javaStatus, jint options) {
     int status;
     int rc = throwIfMinusOne(env, "waitpid", TEMP_FAILURE_RETRY(waitpid(pid, &status, options)));
     if (rc != -1) {
@@ -2127,7 +2353,7 @@
     return rc;
 }
 
-static jint Posix_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) {
+static jint Linux_writeBytes(JNIEnv* env, jobject, jobject javaFd, jbyteArray javaBytes, jint byteOffset, jint byteCount) {
     ScopedBytesRO bytes(env, javaBytes);
     if (bytes.get() == NULL) {
         return -1;
@@ -2135,7 +2361,7 @@
     return IO_FAILURE_RETRY(env, ssize_t, write, javaFd, bytes.get() + byteOffset, byteCount);
 }
 
-static jint Posix_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
+static jint Linux_writev(JNIEnv* env, jobject, jobject javaFd, jobjectArray buffers, jintArray offsets, jintArray byteCounts) {
     IoVec<ScopedBytesRO> ioVec(env, env->GetArrayLength(buffers));
     if (!ioVec.init(buffers, offsets, byteCounts)) {
         return -1;
@@ -2147,132 +2373,136 @@
     { #functionName, signature, reinterpret_cast<void*>(className ## _ ## functionName ## variant) }
 
 static JNINativeMethod gMethods[] = {
-    NATIVE_METHOD(Posix, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
-    NATIVE_METHOD(Posix, access, "(Ljava/lang/String;I)Z"),
-    NATIVE_METHOD(Posix, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
-    NATIVE_METHOD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
-    NATIVE_METHOD_OVERLOAD(Posix, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
-    NATIVE_METHOD(Posix, chmod, "(Ljava/lang/String;I)V"),
-    NATIVE_METHOD(Posix, chown, "(Ljava/lang/String;II)V"),
-    NATIVE_METHOD(Posix, close, "(Ljava/io/FileDescriptor;)V"),
-    NATIVE_METHOD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
-    NATIVE_METHOD_OVERLOAD(Posix, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
-    NATIVE_METHOD(Posix, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"),
-    NATIVE_METHOD(Posix, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"),
-    NATIVE_METHOD(Posix, environ, "()[Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, execv, "(Ljava/lang/String;[Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, execve, "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, fchmod, "(Ljava/io/FileDescriptor;I)V"),
-    NATIVE_METHOD(Posix, fchown, "(Ljava/io/FileDescriptor;II)V"),
-    NATIVE_METHOD(Posix, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"),
-    NATIVE_METHOD(Posix, fcntlInt, "(Ljava/io/FileDescriptor;II)I"),
-    NATIVE_METHOD(Posix, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"),
-    NATIVE_METHOD(Posix, fdatasync, "(Ljava/io/FileDescriptor;)V"),
-    NATIVE_METHOD(Posix, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"),
-    NATIVE_METHOD(Posix, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"),
-    NATIVE_METHOD(Posix, fsync, "(Ljava/io/FileDescriptor;)V"),
-    NATIVE_METHOD(Posix, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
-    NATIVE_METHOD(Posix, gai_strerror, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, getegid, "()I"),
-    NATIVE_METHOD(Posix, geteuid, "()I"),
-    NATIVE_METHOD(Posix, getgid, "()I"),
-    NATIVE_METHOD(Posix, getenv, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, getnameinfo, "(Ljava/net/InetAddress;I)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
-    NATIVE_METHOD(Posix, getpgid, "(I)I"),
-    NATIVE_METHOD(Posix, getpid, "()I"),
-    NATIVE_METHOD(Posix, getppid, "()I"),
-    NATIVE_METHOD(Posix, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"),
-    NATIVE_METHOD(Posix, getpwuid, "(I)Landroid/system/StructPasswd;"),
-    NATIVE_METHOD(Posix, getsockname, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
-    NATIVE_METHOD(Posix, getsockoptByte, "(Ljava/io/FileDescriptor;II)I"),
-    NATIVE_METHOD(Posix, getsockoptInAddr, "(Ljava/io/FileDescriptor;II)Ljava/net/InetAddress;"),
-    NATIVE_METHOD(Posix, getsockoptInt, "(Ljava/io/FileDescriptor;II)I"),
-    NATIVE_METHOD(Posix, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Landroid/system/StructLinger;"),
-    NATIVE_METHOD(Posix, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Landroid/system/StructTimeval;"),
-    NATIVE_METHOD(Posix, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
-    NATIVE_METHOD(Posix, gettid, "()I"),
-    NATIVE_METHOD(Posix, getuid, "()I"),
-    NATIVE_METHOD(Posix, getxattr, "(Ljava/lang/String;Ljava/lang/String;)[B"),
-    NATIVE_METHOD(Posix, getifaddrs, "()[Landroid/system/StructIfaddrs;"),
-    NATIVE_METHOD(Posix, if_indextoname, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, if_nametoindex, "(Ljava/lang/String;)I"),
-    NATIVE_METHOD(Posix, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
-    NATIVE_METHOD(Posix, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
-    NATIVE_METHOD(Posix, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
-    NATIVE_METHOD(Posix, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/util/MutableInt;)I"),
-    NATIVE_METHOD(Posix, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
-    NATIVE_METHOD(Posix, isatty, "(Ljava/io/FileDescriptor;)Z"),
-    NATIVE_METHOD(Posix, kill, "(II)V"),
-    NATIVE_METHOD(Posix, lchown, "(Ljava/lang/String;II)V"),
-    NATIVE_METHOD(Posix, link, "(Ljava/lang/String;Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, listen, "(Ljava/io/FileDescriptor;I)V"),
-    NATIVE_METHOD(Posix, listxattr, "(Ljava/lang/String;)[Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, lseek, "(Ljava/io/FileDescriptor;JI)J"),
-    NATIVE_METHOD(Posix, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
-    NATIVE_METHOD(Posix, mincore, "(JJ[B)V"),
-    NATIVE_METHOD(Posix, mkdir, "(Ljava/lang/String;I)V"),
-    NATIVE_METHOD(Posix, mkfifo, "(Ljava/lang/String;I)V"),
-    NATIVE_METHOD(Posix, mlock, "(JJ)V"),
-    NATIVE_METHOD(Posix, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
-    NATIVE_METHOD(Posix, msync, "(JJI)V"),
-    NATIVE_METHOD(Posix, munlock, "(JJ)V"),
-    NATIVE_METHOD(Posix, munmap, "(JJ)V"),
-    NATIVE_METHOD(Posix, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"),
-    NATIVE_METHOD(Posix, pipe2, "(I)[Ljava/io/FileDescriptor;"),
-    NATIVE_METHOD(Posix, poll, "([Landroid/system/StructPollfd;I)I"),
-    NATIVE_METHOD(Posix, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"),
-    NATIVE_METHOD(Posix, prctl, "(IJJJJ)I"),
-    NATIVE_METHOD(Posix, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
-    NATIVE_METHOD(Posix, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
-    NATIVE_METHOD(Posix, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
-    NATIVE_METHOD(Posix, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
-    NATIVE_METHOD(Posix, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
-    NATIVE_METHOD(Posix, remove, "(Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"),
-    NATIVE_METHOD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
-    NATIVE_METHOD_OVERLOAD(Posix, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
-    NATIVE_METHOD(Posix, setegid, "(I)V"),
-    NATIVE_METHOD(Posix, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"),
-    NATIVE_METHOD(Posix, seteuid, "(I)V"),
-    NATIVE_METHOD(Posix, setgid, "(I)V"),
-    NATIVE_METHOD(Posix, setpgid, "(II)V"),
-    NATIVE_METHOD(Posix, setregid, "(II)V"),
-    NATIVE_METHOD(Posix, setreuid, "(II)V"),
-    NATIVE_METHOD(Posix, setsid, "()I"),
-    NATIVE_METHOD(Posix, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"),
-    NATIVE_METHOD(Posix, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
-    NATIVE_METHOD(Posix, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
-    NATIVE_METHOD(Posix, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
-    NATIVE_METHOD(Posix, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V"),
-    NATIVE_METHOD(Posix, setsockoptGroupSourceReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupSourceReq;)V"),
-    NATIVE_METHOD(Posix, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
-    NATIVE_METHOD(Posix, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
-    NATIVE_METHOD(Posix, setuid, "(I)V"),
-    NATIVE_METHOD(Posix, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"),
-    NATIVE_METHOD(Posix, shutdown, "(Ljava/io/FileDescriptor;I)V"),
-    NATIVE_METHOD(Posix, socket, "(III)Ljava/io/FileDescriptor;"),
-    NATIVE_METHOD(Posix, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
-    NATIVE_METHOD(Posix, stat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
-    NATIVE_METHOD(Posix, statvfs, "(Ljava/lang/String;)Landroid/system/StructStatVfs;"),
-    NATIVE_METHOD(Posix, strerror, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, strsignal, "(I)Ljava/lang/String;"),
-    NATIVE_METHOD(Posix, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, sysconf, "(I)J"),
-    NATIVE_METHOD(Posix, tcdrain, "(Ljava/io/FileDescriptor;)V"),
-    NATIVE_METHOD(Posix, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
-    NATIVE_METHOD(Posix, umaskImpl, "(I)I"),
-    NATIVE_METHOD(Posix, uname, "()Landroid/system/StructUtsname;"),
-    NATIVE_METHOD(Posix, unlink, "(Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, unsetenv, "(Ljava/lang/String;)V"),
-    NATIVE_METHOD(Posix, waitpid, "(ILandroid/util/MutableInt;I)I"),
-    NATIVE_METHOD(Posix, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
-    NATIVE_METHOD(Posix, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
+    NATIVE_METHOD(Linux, accept, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)Ljava/io/FileDescriptor;"),
+    NATIVE_METHOD(Linux, access, "(Ljava/lang/String;I)Z"),
+    NATIVE_METHOD(Linux, android_getaddrinfo, "(Ljava/lang/String;Landroid/system/StructAddrinfo;I)[Ljava/net/InetAddress;"),
+    NATIVE_METHOD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
+    NATIVE_METHOD_OVERLOAD(Linux, bind, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
+    NATIVE_METHOD(Linux, capget,
+                  "(Landroid/system/StructCapUserHeader;)[Landroid/system/StructCapUserData;"),
+    NATIVE_METHOD(Linux, capset,
+                  "(Landroid/system/StructCapUserHeader;[Landroid/system/StructCapUserData;)V"),
+    NATIVE_METHOD(Linux, chmod, "(Ljava/lang/String;I)V"),
+    NATIVE_METHOD(Linux, chown, "(Ljava/lang/String;II)V"),
+    NATIVE_METHOD(Linux, close, "(Ljava/io/FileDescriptor;)V"),
+    NATIVE_METHOD(Linux, connect, "(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V"),
+    NATIVE_METHOD_OVERLOAD(Linux, connect, "(Ljava/io/FileDescriptor;Ljava/net/SocketAddress;)V", SocketAddress),
+    NATIVE_METHOD(Linux, dup, "(Ljava/io/FileDescriptor;)Ljava/io/FileDescriptor;"),
+    NATIVE_METHOD(Linux, dup2, "(Ljava/io/FileDescriptor;I)Ljava/io/FileDescriptor;"),
+    NATIVE_METHOD(Linux, environ, "()[Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, execv, "(Ljava/lang/String;[Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, execve, "(Ljava/lang/String;[Ljava/lang/String;[Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, fchmod, "(Ljava/io/FileDescriptor;I)V"),
+    NATIVE_METHOD(Linux, fchown, "(Ljava/io/FileDescriptor;II)V"),
+    NATIVE_METHOD(Linux, fcntlFlock, "(Ljava/io/FileDescriptor;ILandroid/system/StructFlock;)I"),
+    NATIVE_METHOD(Linux, fcntlInt, "(Ljava/io/FileDescriptor;II)I"),
+    NATIVE_METHOD(Linux, fcntlVoid, "(Ljava/io/FileDescriptor;I)I"),
+    NATIVE_METHOD(Linux, fdatasync, "(Ljava/io/FileDescriptor;)V"),
+    NATIVE_METHOD(Linux, fstat, "(Ljava/io/FileDescriptor;)Landroid/system/StructStat;"),
+    NATIVE_METHOD(Linux, fstatvfs, "(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;"),
+    NATIVE_METHOD(Linux, fsync, "(Ljava/io/FileDescriptor;)V"),
+    NATIVE_METHOD(Linux, ftruncate, "(Ljava/io/FileDescriptor;J)V"),
+    NATIVE_METHOD(Linux, gai_strerror, "(I)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, getegid, "()I"),
+    NATIVE_METHOD(Linux, geteuid, "()I"),
+    NATIVE_METHOD(Linux, getgid, "()I"),
+    NATIVE_METHOD(Linux, getenv, "(Ljava/lang/String;)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, getnameinfo, "(Ljava/net/InetAddress;I)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, getpeername, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
+    NATIVE_METHOD(Linux, getpgid, "(I)I"),
+    NATIVE_METHOD(Linux, getpid, "()I"),
+    NATIVE_METHOD(Linux, getppid, "()I"),
+    NATIVE_METHOD(Linux, getpwnam, "(Ljava/lang/String;)Landroid/system/StructPasswd;"),
+    NATIVE_METHOD(Linux, getpwuid, "(I)Landroid/system/StructPasswd;"),
+    NATIVE_METHOD(Linux, getsockname, "(Ljava/io/FileDescriptor;)Ljava/net/SocketAddress;"),
+    NATIVE_METHOD(Linux, getsockoptByte, "(Ljava/io/FileDescriptor;II)I"),
+    NATIVE_METHOD(Linux, getsockoptInAddr, "(Ljava/io/FileDescriptor;II)Ljava/net/InetAddress;"),
+    NATIVE_METHOD(Linux, getsockoptInt, "(Ljava/io/FileDescriptor;II)I"),
+    NATIVE_METHOD(Linux, getsockoptLinger, "(Ljava/io/FileDescriptor;II)Landroid/system/StructLinger;"),
+    NATIVE_METHOD(Linux, getsockoptTimeval, "(Ljava/io/FileDescriptor;II)Landroid/system/StructTimeval;"),
+    NATIVE_METHOD(Linux, getsockoptUcred, "(Ljava/io/FileDescriptor;II)Landroid/system/StructUcred;"),
+    NATIVE_METHOD(Linux, gettid, "()I"),
+    NATIVE_METHOD(Linux, getuid, "()I"),
+    NATIVE_METHOD(Linux, getxattr, "(Ljava/lang/String;Ljava/lang/String;)[B"),
+    NATIVE_METHOD(Linux, getifaddrs, "()[Landroid/system/StructIfaddrs;"),
+    NATIVE_METHOD(Linux, if_indextoname, "(I)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, if_nametoindex, "(Ljava/lang/String;)I"),
+    NATIVE_METHOD(Linux, inet_pton, "(ILjava/lang/String;)Ljava/net/InetAddress;"),
+    NATIVE_METHOD(Linux, ioctlFlags, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
+    NATIVE_METHOD(Linux, ioctlInetAddress, "(Ljava/io/FileDescriptor;ILjava/lang/String;)Ljava/net/InetAddress;"),
+    NATIVE_METHOD(Linux, ioctlInt, "(Ljava/io/FileDescriptor;ILandroid/util/MutableInt;)I"),
+    NATIVE_METHOD(Linux, ioctlMTU, "(Ljava/io/FileDescriptor;Ljava/lang/String;)I"),
+    NATIVE_METHOD(Linux, isatty, "(Ljava/io/FileDescriptor;)Z"),
+    NATIVE_METHOD(Linux, kill, "(II)V"),
+    NATIVE_METHOD(Linux, lchown, "(Ljava/lang/String;II)V"),
+    NATIVE_METHOD(Linux, link, "(Ljava/lang/String;Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, listen, "(Ljava/io/FileDescriptor;I)V"),
+    NATIVE_METHOD(Linux, listxattr, "(Ljava/lang/String;)[Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, lseek, "(Ljava/io/FileDescriptor;JI)J"),
+    NATIVE_METHOD(Linux, lstat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
+    NATIVE_METHOD(Linux, mincore, "(JJ[B)V"),
+    NATIVE_METHOD(Linux, mkdir, "(Ljava/lang/String;I)V"),
+    NATIVE_METHOD(Linux, mkfifo, "(Ljava/lang/String;I)V"),
+    NATIVE_METHOD(Linux, mlock, "(JJ)V"),
+    NATIVE_METHOD(Linux, mmap, "(JJIILjava/io/FileDescriptor;J)J"),
+    NATIVE_METHOD(Linux, msync, "(JJI)V"),
+    NATIVE_METHOD(Linux, munlock, "(JJ)V"),
+    NATIVE_METHOD(Linux, munmap, "(JJ)V"),
+    NATIVE_METHOD(Linux, open, "(Ljava/lang/String;II)Ljava/io/FileDescriptor;"),
+    NATIVE_METHOD(Linux, pipe2, "(I)[Ljava/io/FileDescriptor;"),
+    NATIVE_METHOD(Linux, poll, "([Landroid/system/StructPollfd;I)I"),
+    NATIVE_METHOD(Linux, posix_fallocate, "(Ljava/io/FileDescriptor;JJ)V"),
+    NATIVE_METHOD(Linux, prctl, "(IJJJJ)I"),
+    NATIVE_METHOD(Linux, preadBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
+    NATIVE_METHOD(Linux, pwriteBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIJ)I"),
+    NATIVE_METHOD(Linux, readBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
+    NATIVE_METHOD(Linux, readlink, "(Ljava/lang/String;)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, realpath, "(Ljava/lang/String;)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, readv, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
+    NATIVE_METHOD(Linux, recvfromBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetSocketAddress;)I"),
+    NATIVE_METHOD(Linux, remove, "(Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, removexattr, "(Ljava/lang/String;Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, rename, "(Ljava/lang/String;Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, sendfile, "(Ljava/io/FileDescriptor;Ljava/io/FileDescriptor;Landroid/util/MutableLong;J)J"),
+    NATIVE_METHOD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/InetAddress;I)I"),
+    NATIVE_METHOD_OVERLOAD(Linux, sendtoBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;IIILjava/net/SocketAddress;)I", SocketAddress),
+    NATIVE_METHOD(Linux, setegid, "(I)V"),
+    NATIVE_METHOD(Linux, setenv, "(Ljava/lang/String;Ljava/lang/String;Z)V"),
+    NATIVE_METHOD(Linux, seteuid, "(I)V"),
+    NATIVE_METHOD(Linux, setgid, "(I)V"),
+    NATIVE_METHOD(Linux, setpgid, "(II)V"),
+    NATIVE_METHOD(Linux, setregid, "(II)V"),
+    NATIVE_METHOD(Linux, setreuid, "(II)V"),
+    NATIVE_METHOD(Linux, setsid, "()I"),
+    NATIVE_METHOD(Linux, setsockoptByte, "(Ljava/io/FileDescriptor;III)V"),
+    NATIVE_METHOD(Linux, setsockoptIfreq, "(Ljava/io/FileDescriptor;IILjava/lang/String;)V"),
+    NATIVE_METHOD(Linux, setsockoptInt, "(Ljava/io/FileDescriptor;III)V"),
+    NATIVE_METHOD(Linux, setsockoptIpMreqn, "(Ljava/io/FileDescriptor;III)V"),
+    NATIVE_METHOD(Linux, setsockoptGroupReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupReq;)V"),
+    NATIVE_METHOD(Linux, setsockoptGroupSourceReq, "(Ljava/io/FileDescriptor;IILandroid/system/StructGroupSourceReq;)V"),
+    NATIVE_METHOD(Linux, setsockoptLinger, "(Ljava/io/FileDescriptor;IILandroid/system/StructLinger;)V"),
+    NATIVE_METHOD(Linux, setsockoptTimeval, "(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V"),
+    NATIVE_METHOD(Linux, setuid, "(I)V"),
+    NATIVE_METHOD(Linux, setxattr, "(Ljava/lang/String;Ljava/lang/String;[BI)V"),
+    NATIVE_METHOD(Linux, shutdown, "(Ljava/io/FileDescriptor;I)V"),
+    NATIVE_METHOD(Linux, socket, "(III)Ljava/io/FileDescriptor;"),
+    NATIVE_METHOD(Linux, socketpair, "(IIILjava/io/FileDescriptor;Ljava/io/FileDescriptor;)V"),
+    NATIVE_METHOD(Linux, stat, "(Ljava/lang/String;)Landroid/system/StructStat;"),
+    NATIVE_METHOD(Linux, statvfs, "(Ljava/lang/String;)Landroid/system/StructStatVfs;"),
+    NATIVE_METHOD(Linux, strerror, "(I)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, strsignal, "(I)Ljava/lang/String;"),
+    NATIVE_METHOD(Linux, symlink, "(Ljava/lang/String;Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, sysconf, "(I)J"),
+    NATIVE_METHOD(Linux, tcdrain, "(Ljava/io/FileDescriptor;)V"),
+    NATIVE_METHOD(Linux, tcsendbreak, "(Ljava/io/FileDescriptor;I)V"),
+    NATIVE_METHOD(Linux, umaskImpl, "(I)I"),
+    NATIVE_METHOD(Linux, uname, "()Landroid/system/StructUtsname;"),
+    NATIVE_METHOD(Linux, unlink, "(Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, unsetenv, "(Ljava/lang/String;)V"),
+    NATIVE_METHOD(Linux, waitpid, "(ILandroid/util/MutableInt;I)I"),
+    NATIVE_METHOD(Linux, writeBytes, "(Ljava/io/FileDescriptor;Ljava/lang/Object;II)I"),
+    NATIVE_METHOD(Linux, writev, "(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I"),
 };
-void register_libcore_io_Posix(JNIEnv* env) {
-    jniRegisterNativeMethods(env, "libcore/io/Posix", gMethods, NELEM(gMethods));
+void register_libcore_io_Linux(JNIEnv* env) {
+    jniRegisterNativeMethods(env, "libcore/io/Linux", gMethods, NELEM(gMethods));
 }
diff --git a/luni/src/main/native/sub.mk b/luni/src/main/native/sub.mk
index 803d818..0706ce8 100644
--- a/luni/src/main/native/sub.mk
+++ b/luni/src/main/native/sub.mk
@@ -21,8 +21,8 @@
     libcore_icu_NativeConverter.cpp \
     libcore_icu_TimeZoneNames.cpp \
     libcore_io_AsynchronousCloseMonitor.cpp \
+    libcore_io_Linux.cpp \
     libcore_io_Memory.cpp \
-    libcore_io_Posix.cpp \
     libcore_util_NativeAllocationRegistry.cpp \
     org_apache_harmony_xml_ExpatParser.cpp \
     sun_misc_Unsafe.cpp \
diff --git a/luni/src/test/java/libcore/io/BlockGuardOsTest.java b/luni/src/test/java/libcore/io/BlockGuardOsTest.java
index 33eb411..567cf2d 100644
--- a/luni/src/test/java/libcore/io/BlockGuardOsTest.java
+++ b/luni/src/test/java/libcore/io/BlockGuardOsTest.java
@@ -49,6 +49,8 @@
                 "android_getaddrinfo(java.lang.String,android.system.StructAddrinfo,int)",
                 "bind(java.io.FileDescriptor,java.net.InetAddress,int)",
                 "bind(java.io.FileDescriptor,java.net.SocketAddress)",
+                "capget(android.system.StructCapUserHeader)",
+                "capset(android.system.StructCapUserHeader,android.system.StructCapUserData[])",
                 "dup(java.io.FileDescriptor)",
                 "dup2(java.io.FileDescriptor,int)",
                 "environ()",
diff --git a/luni/src/test/java/libcore/java/lang/SystemTest.java b/luni/src/test/java/libcore/java/lang/SystemTest.java
index 2de659d..48f4591 100644
--- a/luni/src/test/java/libcore/java/lang/SystemTest.java
+++ b/luni/src/test/java/libcore/java/lang/SystemTest.java
@@ -16,17 +16,16 @@
 
 package libcore.java.lang;
 
+import junit.framework.TestCase;
+
 import java.io.BufferedWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.PrintStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
-import java.lang.SecurityException;
-import java.lang.SecurityManager;
 import java.util.Formatter;
 import java.util.Properties;
 import java.util.concurrent.atomic.AtomicBoolean;
-import junit.framework.TestCase;
 
 public class SystemTest extends TestCase {
 
@@ -250,14 +249,4 @@
         } catch (SecurityException expected) {
         }
     }
-
-    // http://b/34867424
-    public void testIcuPathIncludesTimeZoneOverride() {
-        String icuDataPath = System.getProperty("android.icu.impl.ICUBinary.dataPath");
-        String[] paths = icuDataPath.split(":");
-        assertEquals(2, paths.length);
-
-        assertTrue(paths[0].contains("/misc/zoneinfo/current/icu"));
-        assertTrue(paths[1].contains("/usr/icu"));
-    }
 }
diff --git a/luni/src/test/java/libcore/java/net/URLTest.java b/luni/src/test/java/libcore/java/net/URLTest.java
index 566c314..3a14063 100644
--- a/luni/src/test/java/libcore/java/net/URLTest.java
+++ b/luni/src/test/java/libcore/java/net/URLTest.java
@@ -194,14 +194,6 @@
         assertEquals(null, url.getRef());
     }
 
-    public void testAtSignInUserInfo() throws Exception {
-        try {
-            new URL("http://user@userhost.com:password@host");
-            fail();
-        } catch (MalformedURLException expected) {
-        }
-    }
-
     public void testUserNoPassword() throws Exception {
         URL url = new URL("http://user@host");
         assertEquals("user@host", url.getAuthority());
@@ -762,4 +754,12 @@
         assertEquals("/some/path", new URL("http://foobar.com/some/path#").getFile());
         assertEquals("/some/path", new URL("http://foobar.com/some/path?#").getFile());
     }
+
+    // http://b/33351987
+    public void testMultipleUserField() throws Exception {
+        final String host = "http://multiple@users@url.com";
+        URL url = new URL(host);
+        assertNull(url.getUserInfo());
+        assertTrue(url.getHost().isEmpty());
+    }
 }
diff --git a/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java b/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java
index 564f7c9..dbbfeae 100644
--- a/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java
+++ b/luni/src/test/java/libcore/java/nio/file/DefaultFileSystemProvider2Test.java
@@ -22,6 +22,7 @@
 import org.junit.runner.RunWith;
 
 import java.io.IOException;
+import java.net.URI;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.NonReadableChannelException;
@@ -47,6 +48,7 @@
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
@@ -69,6 +71,7 @@
 import static libcore.java.nio.file.FilesSetup.TEST_FILE_DATA_2;
 import static libcore.java.nio.file.FilesSetup.readFromFile;
 import static libcore.java.nio.file.FilesSetup.writeToFile;
+import static libcore.java.nio.file.LinuxFileSystemTestData.getPath_URI_InputOutputTestData;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.fail;
@@ -591,6 +594,55 @@
         } catch (NullPointerException expected) {}
     }
 
+    @Test
+    public void test_getPath() throws Exception {
+        List<LinuxFileSystemTestData.TestData> inputOutputTestCases = getPath_URI_InputOutputTestData();
+        for (LinuxFileSystemTestData.TestData inputOutputTestCase : inputOutputTestCases) {
+            assertEquals(inputOutputTestCase.output,
+                    provider.getPath(new URI(inputOutputTestCase.input)).toString());
+        }
+
+        // When URI is null.
+        try {
+            provider.getPath(null);
+            fail();
+        } catch (NullPointerException expected) {}
+
+        // When Schema is not supported.
+        try {
+            provider.getPath(new URI("scheme://d"));
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
+    @Test
+    public void test_getScheme() {
+        assertEquals("file", provider.getScheme());
+    }
+
+    @Test
+    public void test_installedProviders() {
+        assertNotNull(provider.installedProviders());
+    }
+
+    @Test
+    public void test_newFileSystem$URI$Map() throws Exception {
+        Path testPath = Paths.get("/");
+        assertNotNull(provider.getFileSystem(testPath.toUri()));
+
+        try {
+            provider.getFileSystem(null);
+            fail();
+        } catch (NullPointerException expected) {}
+
+        // Test the case when URI has illegal scheme.
+        URI stubURI = new URI("scheme://path");
+        try {
+            provider.getFileSystem(stubURI);
+            fail();
+        } catch (IllegalArgumentException expected) {}
+    }
+
     String readFromFileChannel(FileChannel fc) throws IOException {
         ByteBuffer bb = ByteBuffer.allocate(20);
         fc.read(bb);
diff --git a/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java b/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java
new file mode 100644
index 0000000..bf6c6b7
--- /dev/null
+++ b/luni/src/test/java/libcore/java/nio/file/spi/FileTypeDetectorTest.java
@@ -0,0 +1,22 @@
+package libcore.java.nio.file.spi;
+
+import org.junit.Test;
+
+import java.nio.file.Paths;
+import java.nio.file.spi.FileTypeDetector;
+
+import static org.junit.Assert.assertEquals;
+
+public class FileTypeDetectorTest {
+
+    @Test
+    public void test_probeFileType() throws Exception {
+        FileTypeDetector defaultFileTypeDetector = sun.nio.fs.DefaultFileTypeDetector.create();
+        // The method uses file extensions to deduce mime type, therefore, it doesn't check for
+        // file existence.
+        assertEquals("text/plain",
+                defaultFileTypeDetector.probeContentType(Paths.get("file.txt")));
+        assertEquals("text/x-java",
+                defaultFileTypeDetector.probeContentType(Paths.get("file.java")));
+    }
+}
diff --git a/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java b/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
index 4a5658c..cbaadd4 100644
--- a/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
+++ b/luni/src/test/java/libcore/java/security/cert/X509CertSelectorTest.java
@@ -67,13 +67,21 @@
         X509CertSelector certSelector = new X509CertSelector();
         certSelector.addPathToName(GeneralName.iPAddress, "127.0.0.1");
 
+        // This constraint matches 127.0.0.1/255.255.255.255 aka 127.0.0.1
         byte[] directMatch = { 127, 0, 0, 1, -1, -1, -1, -1 };
         assertTrue(certSelector.match(newCertWithNameConstraint(directMatch, excluded)));
 
-        byte[] noMatch = { 127, 0, 0, 2, -1, -1, -1, 127 };
+        // This constraint matches 127.0.0.2/255.255.255.255 aka 127.0.0.2
+        byte[] noMatch = { 127, 0, 0, 2, -1, -1, -1, -1 };
         assertFalse(certSelector.match(newCertWithNameConstraint(noMatch, excluded)));
 
-        // TODO: test that requires mask to match
+        // This constraint matches 127.0.0.0/255.255.255.255 aka 127.0.0.0
+        byte[] subnetWithNoMask = { 127, 0, 0, 0, -1, -1, -1, -1 };
+        assertFalse(certSelector.match(newCertWithNameConstraint(subnetWithNoMask, excluded)));
+
+        // This constraint matches 127.0.0.0/255.255.255.0 aka 127.0.0.0/24
+        byte[] maskedMatch = { 127, 0, 0, 0, -1, -1, -1, 0 };
+        assertTrue(certSelector.match(newCertWithNameConstraint(maskedMatch, excluded)));
     }
 
     public void testMatchMaskedIpv6NameConstraint() throws Exception {
@@ -84,19 +92,33 @@
         X509CertSelector certSelector = new X509CertSelector();
         certSelector.addPathToName(GeneralName.iPAddress, "1::1");
 
+        // This constraint matches 1::1/128 aka 1::1
         byte[] directMatch = {
                 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
-                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
+                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
         };
         assertTrue(certSelector.match(newCertWithNameConstraint(directMatch, excluded)));
 
+        // This constraint matches 1::2/128 aka 1::2
         byte[] noMatch = {
                 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
-                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 127
+                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
         };
         assertFalse(certSelector.match(newCertWithNameConstraint(noMatch, excluded)));
 
-        // TODO: test that requires mask to match
+        // This constraint matches 1::/128 aka 1::
+        byte[] subnetWithNoMask = {
+                0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+        };
+        assertFalse(certSelector.match(newCertWithNameConstraint(subnetWithNoMask, excluded)));
+
+        // This constraint matches 1::/120
+        byte[] maskedMatch = {
+                0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0
+        };
+        assertTrue(certSelector.match(newCertWithNameConstraint(maskedMatch, excluded)));
     }
 
     public void testMatchMalformedSubjectAlternativeName() throws Exception {
diff --git a/luni/src/test/java/libcore/java/util/LocaleTest.java b/luni/src/test/java/libcore/java/util/LocaleTest.java
index 1414c05..969402b 100644
--- a/luni/src/test/java/libcore/java/util/LocaleTest.java
+++ b/luni/src/test/java/libcore/java/util/LocaleTest.java
@@ -136,8 +136,6 @@
         assertEquals("Palestine", new Locale("", "PS").getDisplayCountry(Locale.US));
 
         assertEquals("Cocos (Keeling) Islands", new Locale("", "CC").getDisplayCountry(Locale.US));
-        assertEquals("Congo (DRC)", new Locale("", "CD").getDisplayCountry(Locale.US));
-        assertEquals("Congo (Republic)", new Locale("", "CG").getDisplayCountry(Locale.US));
         assertEquals("Falkland Islands (Islas Malvinas)", new Locale("", "FK").getDisplayCountry(Locale.US));
         assertEquals("Macedonia (FYROM)", new Locale("", "MK").getDisplayCountry(Locale.US));
         assertEquals("Myanmar (Burma)", new Locale("", "MM").getDisplayCountry(Locale.US));
diff --git a/luni/src/test/java/libcore/java/util/TimeZoneTest.java b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
index 6b692cf..375eb36 100644
--- a/luni/src/test/java/libcore/java/util/TimeZoneTest.java
+++ b/luni/src/test/java/libcore/java/util/TimeZoneTest.java
@@ -216,15 +216,26 @@
 
     // http://b/7955614 and http://b/8026776.
     public void testDisplayNames() throws Exception {
+        checkDisplayNames(Locale.US);
+    }
+
+    public void testDisplayNames_nonUS() throws Exception {
+        // run checkDisplayNames with an arbitrary set of Locales.
+        checkDisplayNames(Locale.CHINESE);
+        checkDisplayNames(Locale.FRENCH);
+        checkDisplayNames(Locale.forLanguageTag("bn-BD"));
+    }
+
+    public void checkDisplayNames(Locale locale) throws Exception {
         // Check that there are no time zones that use DST but have the same display name for
         // both standard and daylight time.
         StringBuilder failures = new StringBuilder();
         for (String id : TimeZone.getAvailableIDs()) {
             TimeZone tz = TimeZone.getTimeZone(id);
-            String longDst = tz.getDisplayName(true, TimeZone.LONG, Locale.US);
-            String longStd = tz.getDisplayName(false, TimeZone.LONG, Locale.US);
-            String shortDst = tz.getDisplayName(true, TimeZone.SHORT, Locale.US);
-            String shortStd = tz.getDisplayName(false, TimeZone.SHORT, Locale.US);
+            String longDst = tz.getDisplayName(true, TimeZone.LONG, locale);
+            String longStd = tz.getDisplayName(false, TimeZone.LONG, locale);
+            String shortDst = tz.getDisplayName(true, TimeZone.SHORT, locale);
+            String shortStd = tz.getDisplayName(false, TimeZone.SHORT, locale);
 
             if (tz.useDaylightTime()) {
                 // The long std and dst strings must differ!
@@ -329,15 +340,6 @@
         return String.format("GMT%c%02d:%02d", sign, offset / 60, offset % 60);
     }
 
-    public void testAllDisplayNames() throws Exception {
-      for (Locale locale : Locale.getAvailableLocales()) {
-        for (String id : TimeZone.getAvailableIDs()) {
-          TimeZone tz = TimeZone.getTimeZone(id);
-          assertNotNull(tz.getDisplayName(false, TimeZone.LONG, locale));
-        }
-      }
-    }
-
     // http://b/18839557
     public void testOverflowing32BitUnixDates() {
         final TimeZone tz = TimeZone.getTimeZone("America/New_York");
diff --git a/luni/src/test/java/libcore/javax/crypto/CipherOutputStreamTest.java b/luni/src/test/java/libcore/javax/crypto/CipherOutputStreamTest.java
new file mode 100644
index 0000000..dd9a9a0
--- /dev/null
+++ b/luni/src/test/java/libcore/javax/crypto/CipherOutputStreamTest.java
@@ -0,0 +1,105 @@
+/*
+ * 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.javax.crypto;
+
+import junit.framework.TestCase;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+import java.security.spec.AlgorithmParameterSpec;
+import javax.crypto.AEADBadTagException;
+import javax.crypto.Cipher;
+import javax.crypto.CipherOutputStream;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.GCMParameterSpec;
+
+public final class CipherOutputStreamTest extends TestCase {
+
+    // From b/36636576. CipherOutputStream had a bug where it would ignore exceptions
+    // thrown during close().
+    public void testDecryptCorruptGCM() throws Exception {
+        for (Provider provider : Security.getProviders()) {
+            Cipher cipher;
+            try {
+                cipher = Cipher.getInstance("AES/GCM/NoPadding", provider);
+            } catch (NoSuchAlgorithmException e) {
+                continue;
+            }
+            SecretKey key;
+            if (provider.getName().equals("AndroidKeyStoreBCWorkaround")) {
+                key = getAndroidKeyStoreSecretKey();
+            } else {
+                KeyGenerator keygen = KeyGenerator.getInstance("AES");
+                keygen.init(256);
+                key = keygen.generateKey();
+            }
+            GCMParameterSpec params = new GCMParameterSpec(128, new byte[12]);
+            byte[] unencrypted = new byte[200];
+
+            // Normal providers require specifying the IV, but KeyStore prohibits it, so
+            // we have to special-case it
+            if (provider.getName().equals("AndroidKeyStoreBCWorkaround")) {
+                cipher.init(Cipher.ENCRYPT_MODE, key);
+            } else {
+                cipher.init(Cipher.ENCRYPT_MODE, key, params);
+            }
+            byte[] encrypted = cipher.doFinal(unencrypted);
+
+            // Corrupt the final byte, which will corrupt the authentication tag
+            encrypted[encrypted.length - 1] ^= 1;
+
+            cipher.init(Cipher.DECRYPT_MODE, key, params);
+            CipherOutputStream cos = new CipherOutputStream(new ByteArrayOutputStream(), cipher);
+            try {
+                cos.write(encrypted);
+                cos.close();
+                fail("Writing a corrupted stream should throw an exception."
+                        + "  Provider: " + provider);
+            } catch (IOException expected) {
+                assertTrue(expected.getCause() instanceof AEADBadTagException);
+            }
+        }
+
+    }
+
+    // The AndroidKeyStoreBCWorkaround provider can't use keys created by anything
+    // but Android KeyStore, which requires using its own parameters class to create
+    // keys.  Since we're in javax, we can't link against the frameworks classes, so
+    // we have to use reflection to make a suitable key.  This will always be safe
+    // because if we're making a key for AndroidKeyStoreBCWorkaround, the KeyStore
+    // classes must be present.
+    private static SecretKey getAndroidKeyStoreSecretKey() throws Exception {
+        KeyGenerator keygen = KeyGenerator.getInstance("AES", "AndroidKeyStore");
+        Class<?> keyParamsBuilderClass = keygen.getClass().getClassLoader().loadClass(
+                "android.security.keystore.KeyGenParameterSpec$Builder");
+        Object keyParamsBuilder = keyParamsBuilderClass.getConstructor(String.class, Integer.TYPE)
+                // 3 is PURPOSE_ENCRYPT | PURPOSE_DECRYPT
+                .newInstance("testDecryptCorruptGCM", 3);
+        keyParamsBuilderClass.getMethod("setBlockModes", new Class[]{String[].class})
+                .invoke(keyParamsBuilder, new Object[]{new String[]{"GCM"}});
+        keyParamsBuilderClass.getMethod("setEncryptionPaddings", new Class[]{String[].class})
+                .invoke(keyParamsBuilder, new Object[]{new String[]{"NoPadding"}});
+        AlgorithmParameterSpec spec = (AlgorithmParameterSpec)
+                keyParamsBuilderClass.getMethod("build", new Class[]{}).invoke(keyParamsBuilder);
+        keygen.init(spec);
+        return keygen.generateKey();
+    }
+}
diff --git a/luni/src/test/java/libcore/util/TimeZoneDataFilesTest.java b/luni/src/test/java/libcore/util/TimeZoneDataFilesTest.java
new file mode 100644
index 0000000..efba900
--- /dev/null
+++ b/luni/src/test/java/libcore/util/TimeZoneDataFilesTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.util;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+public class TimeZoneDataFilesTest {
+
+    @Test
+    public void getTimeZoneFilePaths() {
+        String[] paths = TimeZoneDataFiles.getTimeZoneFilePaths("foo");
+        assertEquals(2, paths.length);
+
+        assertTrue(paths[0].contains("/misc/zoneinfo/current/"));
+        assertTrue(paths[0].endsWith("foo"));
+
+        assertTrue(paths[1].contains("/usr/share/zoneinfo/"));
+        assertTrue(paths[1].endsWith("foo"));
+    }
+
+    // http://b/34867424
+    @Test
+    public void generateIcuDataPath_includesTimeZoneOverride() {
+        String icuDataPath = System.getProperty("android.icu.impl.ICUBinary.dataPath");
+        assertEquals(icuDataPath, TimeZoneDataFiles.generateIcuDataPath());
+
+        String[] paths = icuDataPath.split(":");
+        assertEquals(2, paths.length);
+
+        assertTrue(paths[0].contains("/misc/zoneinfo/current/icu"));
+        assertTrue(paths[1].contains("/usr/icu"));
+    }
+}
diff --git a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
index 901519e..e6ec4df 100644
--- a/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
+++ b/luni/src/test/java/libcore/util/ZoneInfoDBTest.java
@@ -28,27 +28,27 @@
 public class ZoneInfoDBTest extends junit.framework.TestCase {
 
   // The base tzdata file, always present on a device.
-  private static final String TZDATA_IN_ROOT =
-      System.getenv("ANDROID_ROOT") + "/usr/share/zoneinfo/tzdata";
+  private static final String SYSTEM_TZDATA_FILE =
+      TimeZoneDataFiles.getSystemTimeZoneFile(ZoneInfoDB.TZDATA_FILE);
 
   // An empty override file should fall back to the default file.
   public void testLoadTzDataWithFallback_emptyOverrideFile() throws Exception {
-    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
     String emptyFilePath = makeEmptyFile().getPath();
 
     ZoneInfoDB.TzData dataWithEmptyOverride =
-        ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, TZDATA_IN_ROOT);
+        ZoneInfoDB.TzData.loadTzDataWithFallback(emptyFilePath, SYSTEM_TZDATA_FILE);
     assertEquals(data.getVersion(), dataWithEmptyOverride.getVersion());
     assertEquals(data.getAvailableIDs().length, dataWithEmptyOverride.getAvailableIDs().length);
   }
 
   // A corrupt override file should fall back to the default file.
   public void testLoadTzDataWithFallback_corruptOverrideFile() throws Exception {
-    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
     String corruptFilePath = makeCorruptFile().getPath();
 
     ZoneInfoDB.TzData dataWithCorruptOverride =
-        ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, TZDATA_IN_ROOT);
+        ZoneInfoDB.TzData.loadTzDataWithFallback(corruptFilePath, SYSTEM_TZDATA_FILE);
     assertEquals(data.getVersion(), dataWithCorruptOverride.getVersion());
     assertEquals(data.getAvailableIDs().length, dataWithCorruptOverride.getAvailableIDs().length);
   }
@@ -64,7 +64,7 @@
 
   // Given a valid override file, we should find ourselves using that.
   public void testLoadTzDataWithFallback_goodOverrideFile() throws Exception {
-    RandomAccessFile in = new RandomAccessFile(TZDATA_IN_ROOT, "r");
+    RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
     byte[] content = new byte[(int) in.length()];
     in.readFully(content);
     in.close();
@@ -79,9 +79,9 @@
     File goodFile = makeTemporaryFile(content);
     try {
       ZoneInfoDB.TzData dataWithOverride =
-              ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), TZDATA_IN_ROOT);
+              ZoneInfoDB.TzData.loadTzDataWithFallback(goodFile.getPath(), SYSTEM_TZDATA_FILE);
       assertEquals("9999z", dataWithOverride.getVersion());
-      ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+      ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
       assertEquals(data.getAvailableIDs().length, dataWithOverride.getAvailableIDs().length);
     } finally {
       goodFile.delete();
@@ -89,7 +89,7 @@
   }
 
   public void testLoadTzData_badHeader() throws Exception {
-    RandomAccessFile in = new RandomAccessFile(TZDATA_IN_ROOT, "r");
+    RandomAccessFile in = new RandomAccessFile(SYSTEM_TZDATA_FILE, "r");
     byte[] content = new byte[(int) in.length()];
     in.readFully(content);
     in.close();
@@ -212,7 +212,7 @@
 
   // Confirms any caching that exists correctly handles TimeZone mutability.
   public void testMakeTimeZone_timeZoneMutability() throws Exception {
-    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
     String tzId = "Europe/London";
     ZoneInfo first = data.makeTimeZone(tzId);
     ZoneInfo second = data.makeTimeZone(tzId);
@@ -229,21 +229,21 @@
   }
 
   public void testMakeTimeZone_notFound() throws Exception {
-    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
     assertNull(data.makeTimeZone("THIS_TZ_DOES_NOT_EXIST"));
     assertFalse(data.hasTimeZone("THIS_TZ_DOES_NOT_EXIST"));
   }
 
   public void testMakeTimeZone_found() throws Exception {
-    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
     assertNotNull(data.makeTimeZone("Europe/London"));
     assertTrue(data.hasTimeZone("Europe/London"));
   }
 
   public void testGetRulesVersion() throws Exception {
-    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(TZDATA_IN_ROOT);
+    ZoneInfoDB.TzData data = ZoneInfoDB.TzData.loadTzData(SYSTEM_TZDATA_FILE);
 
-    String rulesVersion = ZoneInfoDB.TzData.getRulesVersion(new File(TZDATA_IN_ROOT));
+    String rulesVersion = ZoneInfoDB.TzData.getRulesVersion(new File(SYSTEM_TZDATA_FILE));
     assertEquals(data.getVersion(), rulesVersion);
   }
 
diff --git a/non_openjdk_java_files.mk b/non_openjdk_java_files.mk
index 9d59a4a..31ee139 100644
--- a/non_openjdk_java_files.mk
+++ b/non_openjdk_java_files.mk
@@ -6,6 +6,8 @@
   luni/src/main/java/android/system/OsConstants.java \
   luni/src/main/java/android/system/PacketSocketAddress.java \
   luni/src/main/java/android/system/StructAddrinfo.java \
+  luni/src/main/java/android/system/StructCapUserData.java \
+  luni/src/main/java/android/system/StructCapUserHeader.java \
   luni/src/main/java/android/system/StructFlock.java \
   luni/src/main/java/android/system/StructGroupReq.java \
   luni/src/main/java/android/system/StructGroupSourceReq.java \
@@ -235,31 +237,6 @@
   xml/src/main/java/org/xmlpull/v1/sax2/Driver.java \
 
 non_openjdk_java_files := \
-  dex/src/main/java/com/android/dex/Annotation.java \
-  dex/src/main/java/com/android/dex/ClassData.java \
-  dex/src/main/java/com/android/dex/ClassDef.java \
-  dex/src/main/java/com/android/dex/Code.java \
-  dex/src/main/java/com/android/dex/Dex.java \
-  dex/src/main/java/com/android/dex/DexException.java \
-  dex/src/main/java/com/android/dex/DexFormat.java \
-  dex/src/main/java/com/android/dex/DexIndexOverflowException.java \
-  dex/src/main/java/com/android/dex/EncodedValue.java \
-  dex/src/main/java/com/android/dex/EncodedValueCodec.java \
-  dex/src/main/java/com/android/dex/EncodedValueReader.java \
-  dex/src/main/java/com/android/dex/FieldId.java \
-  dex/src/main/java/com/android/dex/Leb128.java \
-  dex/src/main/java/com/android/dex/MethodId.java \
-  dex/src/main/java/com/android/dex/Mutf8.java \
-  dex/src/main/java/com/android/dex/ProtoId.java \
-  dex/src/main/java/com/android/dex/SizeOf.java \
-  dex/src/main/java/com/android/dex/TableOfContents.java \
-  dex/src/main/java/com/android/dex/TypeList.java \
-  dex/src/main/java/com/android/dex/util/ByteArrayByteInput.java \
-  dex/src/main/java/com/android/dex/util/ByteInput.java \
-  dex/src/main/java/com/android/dex/util/ByteOutput.java \
-  dex/src/main/java/com/android/dex/util/ExceptionWithContext.java \
-  dex/src/main/java/com/android/dex/util/FileUtils.java \
-  dex/src/main/java/com/android/dex/util/Unsigned.java \
   dalvik/src/main/java/dalvik/system/profiler/AsciiHprofWriter.java \
   dalvik/src/main/java/dalvik/system/profiler/BinaryHprof.java \
   dalvik/src/main/java/dalvik/system/profiler/BinaryHprofReader.java \
@@ -294,11 +271,11 @@
   luni/src/main/java/libcore/io/IoTracker.java \
   luni/src/main/java/libcore/io/IoUtils.java \
   luni/src/main/java/libcore/io/Libcore.java \
+  luni/src/main/java/libcore/io/Linux.java \
   luni/src/main/java/libcore/io/Memory.java \
   luni/src/main/java/libcore/io/MemoryMappedFile.java \
   luni/src/main/java/libcore/io/NioBufferIterator.java \
   luni/src/main/java/libcore/io/Os.java \
-  luni/src/main/java/libcore/io/Posix.java \
   luni/src/main/java/libcore/io/SizeOf.java \
   luni/src/main/java/libcore/io/Streams.java \
   luni/src/main/java/libcore/math/MathUtils.java \
@@ -330,6 +307,7 @@
   luni/src/main/java/libcore/util/Objects.java \
   luni/src/main/java/libcore/util/RecoverySystem.java \
   luni/src/main/java/libcore/util/SneakyThrow.java \
+  luni/src/main/java/libcore/util/TimeZoneDataFiles.java \
   luni/src/main/java/libcore/util/ZoneInfo.java \
   luni/src/main/java/libcore/util/ZoneInfoDB.java \
   luni/src/main/java/libcore/util/HexEncoding.java \
diff --git a/ojluni/src/main/java/java/awt/font/NumericShaper.java b/ojluni/src/main/java/java/awt/font/NumericShaper.java
index c8100bf..7e1980e 100644
--- a/ojluni/src/main/java/java/awt/font/NumericShaper.java
+++ b/ojluni/src/main/java/java/awt/font/NumericShaper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -633,7 +633,6 @@
         0x06d6, 0x06e5,
         0x06e7, 0x06ee,
         0x06f0, 0x06fa,
-        0x070f, 0x0710,
         0x0711, 0x0712,
         0x0730, 0x074d,
         0x07a6, 0x07b1,
@@ -644,7 +643,7 @@
         0x0825, 0x0828,
         0x0829, 0x0830,
         0x0859, 0x085e,
-        0x0900, 0x0903,
+        0x08e4, 0x0903,
         0x093a, 0x093b,
         0x093c, 0x093d,
         0x0941, 0x0949,
@@ -723,6 +722,7 @@
         0x1732, 0x1735,
         0x1752, 0x1760,
         0x1772, 0x1780,
+        0x17b4, 0x17b6,
         0x17b7, 0x17be,
         0x17c6, 0x17c7,
         0x17c9, 0x17d4,
@@ -750,6 +750,7 @@
         0x1b80, 0x1b82,
         0x1ba2, 0x1ba6,
         0x1ba8, 0x1baa,
+        0x1bab, 0x1bac,
         0x1be6, 0x1be7,
         0x1be8, 0x1bea,
         0x1bed, 0x1bee,
@@ -760,6 +761,7 @@
         0x1cd4, 0x1ce1,
         0x1ce2, 0x1ce9,
         0x1ced, 0x1cee,
+        0x1cf4, 0x1cf5,
         0x1dc0, 0x1e00,
         0x1fbd, 0x1fbe,
         0x1fbf, 0x1fc2,
@@ -791,7 +793,8 @@
         0x26ad, 0x2800,
         0x2900, 0x2c00,
         0x2ce5, 0x2ceb,
-        0x2cef, 0x2d00,
+        0x2cef, 0x2cf2,
+        0x2cf9, 0x2d00,
         0x2d7f, 0x2d80,
         0x2de0, 0x3005,
         0x3008, 0x3021,
@@ -814,6 +817,7 @@
         0xa490, 0xa4d0,
         0xa60d, 0xa610,
         0xa66f, 0xa680,
+        0xa69f, 0xa6a0,
         0xa6f0, 0xa6f2,
         0xa700, 0xa722,
         0xa788, 0xa789,
@@ -842,6 +846,8 @@
         0xaab7, 0xaab9,
         0xaabe, 0xaac0,
         0xaac1, 0xaac2,
+        0xaaec, 0xaaee,
+        0xaaf6, 0xab01,
         0xabe5, 0xabe6,
         0xabe8, 0xabe9,
         0xabed, 0xabf0,
@@ -867,6 +873,16 @@
         0x11080, 0x11082,
         0x110b3, 0x110b7,
         0x110b9, 0x110bb,
+        0x11100, 0x11103,
+        0x11127, 0x1112c,
+        0x1112d, 0x11136,
+        0x11180, 0x11182,
+        0x111b6, 0x111bf,
+        0x116ab, 0x116ac,
+        0x116ad, 0x116ae,
+        0x116b0, 0x116b6,
+        0x116b7, 0x116c0,
+        0x16f8f, 0x16f93,
         0x1d167, 0x1d16a,
         0x1d173, 0x1d183,
         0x1d185, 0x1d18c,
@@ -877,7 +893,9 @@
         0x1d74f, 0x1d750,
         0x1d789, 0x1d78a,
         0x1d7c3, 0x1d7c4,
-        0x1d7ce, 0x1f110,
+        0x1d7ce, 0x1ee00,
+        0x1eef0, 0x1f110,
+        0x1f16a, 0x1f170,
         0x1f300, 0x1f48c,
         0x1f48d, 0x1f524,
         0x1f525, 0x20000,
@@ -1194,7 +1212,7 @@
      * For example, to check if a shaper shapes to Arabic, you would use the
      * following:
      * <blockquote>
-     *   <code>if ((shaper.getRanges() & shaper.ARABIC) != 0) { ... </code>
+     *   {@code if ((shaper.getRanges() & shaper.ARABIC) != 0) &#123; ... }
      * </blockquote>
      *
      * <p>Note that this method supports only the bit mask-based
diff --git a/ojluni/src/main/java/java/beans/ChangeListenerMap.java b/ojluni/src/main/java/java/beans/ChangeListenerMap.java
index fead0a4..fa8be47 100644
--- a/ojluni/src/main/java/java/beans/ChangeListenerMap.java
+++ b/ojluni/src/main/java/java/beans/ChangeListenerMap.java
@@ -76,7 +76,7 @@
      */
     public final synchronized void add(String name, L listener) {
         if (this.map == null) {
-            this.map = new HashMap<String, L[]>();
+            this.map = new HashMap<>();
         }
         L[] array = this.map.get(name);
         int size = (array != null)
@@ -146,7 +146,7 @@
     public final void set(String name, L[] listeners) {
         if (listeners != null) {
             if (this.map == null) {
-                this.map = new HashMap<String, L[]>();
+                this.map = new HashMap<>();
             }
             this.map.put(name, listeners);
         }
@@ -167,7 +167,7 @@
         if (this.map == null) {
             return newArray(0);
         }
-        List<L> list = new ArrayList<L>();
+        List<L> list = new ArrayList<>();
 
         L[] listeners = this.map.get(null);
         if (listeners != null) {
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeEvent.java b/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
index 55397ef..eeaa651 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2010, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -25,6 +25,8 @@
 
 package java.beans;
 
+import java.util.EventObject;
+
 /**
  * A "PropertyChange" event gets delivered whenever a bean changes a "bound"
  * or "constrained" property.  A PropertyChangeEvent object is sent as an
@@ -42,21 +44,21 @@
  * arbitrary set of if its properties have changed.  In this case the
  * old and new values should also be null.
  */
-
-public class PropertyChangeEvent extends java.util.EventObject {
+public class PropertyChangeEvent extends EventObject {
     private static final long serialVersionUID = 7042693688939648123L;
 
     /**
-     * Constructs a new <code>PropertyChangeEvent</code>.
+     * Constructs a new {@code PropertyChangeEvent}.
      *
-     * @param source  The bean that fired the event.
-     * @param propertyName  The programmatic name of the property
-     *          that was changed.
-     * @param oldValue  The old value of the property.
-     * @param newValue  The new value of the property.
+     * @param source        the bean that fired the event
+     * @param propertyName  the programmatic name of the property that was changed
+     * @param oldValue      the old value of the property
+     * @param newValue      the new value of the property
+     *
+     * @throws IllegalArgumentException if {@code source} is {@code null}
      */
     public PropertyChangeEvent(Object source, String propertyName,
-                                     Object oldValue, Object newValue) {
+                               Object oldValue, Object newValue) {
         super(source);
         this.propertyName = propertyName;
         this.newValue = newValue;
diff --git a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
index 270912c..d55ae76 100644
--- a/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
+++ b/ojluni/src/main/java/java/beans/PropertyChangeSupport.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,7 @@
      * <code>PropertyChangeListenerProxy</code>, perform the cast, and examine
      * the parameter.
      *
-     * <pre>
+     * <pre>{@code
      * PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
      * for (int i = 0; i < listeners.length; i++) {
      *   if (listeners[i] instanceof PropertyChangeListenerProxy) {
@@ -168,7 +168,7 @@
      *     }
      *   }
      * }
-     *</pre>
+     * }</pre>
      *
      * @see PropertyChangeListenerProxy
      * @return all of the <code>PropertyChangeListeners</code> added or an
@@ -431,7 +431,7 @@
                     listeners = entry.getValue();
                 } else {
                     if (children == null) {
-                        children = new Hashtable<String, PropertyChangeSupport>();
+                        children = new Hashtable<>();
                     }
                     PropertyChangeSupport pcs = new PropertyChangeSupport(this.source);
                     pcs.map.set(null, entry.getValue());
@@ -460,6 +460,7 @@
 
         ObjectInputStream.GetField fields = s.readFields();
 
+        @SuppressWarnings("unchecked")
         Hashtable<String, PropertyChangeSupport> children = (Hashtable<String, PropertyChangeSupport>) fields.get("children", null);
         this.source = fields.get("source", null);
         fields.get("propertyChangeSupportSerializedDataVersion", 2);
diff --git a/ojluni/src/main/java/java/lang/Class.java b/ojluni/src/main/java/java/lang/Class.java
index 8591bfe..3717cd7 100644
--- a/ojluni/src/main/java/java/lang/Class.java
+++ b/ojluni/src/main/java/java/lang/Class.java
@@ -27,7 +27,6 @@
 package java.lang;
 
 import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
 
 import java.io.InputStream;
 import java.io.Serializable;
@@ -128,7 +127,7 @@
      * DexCache of resolved constant pool entries. Will be null for certain runtime-generated classes
      * e.g. arrays and primitive classes.
      */
-    private transient DexCache dexCache;
+    private transient Object dexCache;
 
     /**
      * Extra data that only some classes possess. This is allocated lazily as needed.
@@ -960,24 +959,19 @@
     public Class<?>[] getInterfaces() {
         if (isArray()) {
             return new Class<?>[] { Cloneable.class, Serializable.class };
-        } else if (isProxy()) {
-            return getProxyInterfaces();
         }
-        Dex dex = getDex();
-        if (dex == null) {
+
+        final Class<?>[] ifaces = getInterfacesInternal();
+        if (ifaces == null) {
             return EmptyArray.CLASS;
         }
-        short[] interfaces = dex.interfaceTypeIndicesFromClassDefIndex(dexClassDefIndex);
-        Class<?>[] result = new Class<?>[interfaces.length];
-        for (int i = 0; i < interfaces.length; i++) {
-            result[i] = getDexCacheType(dex, interfaces[i]);
-        }
-        return result;
+
+        return ifaces;
     }
 
-    // Returns the interfaces that this proxy class directly implements.
     @FastNative
-    private native Class<?>[] getProxyInterfaces();
+    private native Class<?>[] getInterfacesInternal();
+
 
     /**
      * Returns the {@code Type}s representing the interfaces
@@ -2637,70 +2631,6 @@
     }
 
     /**
-     * Returns the dex file from which this class was loaded.
-     *
-     * @hide
-     */
-    public Dex getDex() {
-        if (dexCache == null) {
-            return null;
-        }
-        return dexCache.getDex();
-    }
-    /**
-     * Returns a string from the dex cache, computing the string from the dex file if necessary.
-     *
-     * @hide
-     */
-    public String getDexCacheString(Dex dex, int dexStringIndex) {
-        String s = dexCache.getResolvedString(dexStringIndex);
-        if (s == null) {
-            s = dex.strings().get(dexStringIndex).intern();
-            dexCache.setResolvedString(dexStringIndex, s);
-        }
-        return s;
-    }
-
-    /**
-     * Returns a resolved type from the dex cache, computing the type from the dex file if
-     * necessary.
-     *
-     * @hide
-     */
-    public Class<?> getDexCacheType(Dex dex, int dexTypeIndex) {
-        Class<?> resolvedType = dexCache.getResolvedType(dexTypeIndex);
-        if (resolvedType == null) {
-
-            // Temporary debugging code for issue b/35970927. In the absence of reproducibility,
-            // we want more information on :
-            //
-            // (a) This class: a proxy for the dex file whose cache is being queried.
-            // (b) The dex type index & descriptor index.
-            // (c) The resolved descriptor.
-            // (d) The wrapper message : this is the name of the class used by InternalNames
-            // for its loadClass call.
-            //
-            // (c) & (d) should help us rule out string compression issues.
-            // (a) & (b) should help us rule out some classes of heap corruption issues.
-            int descriptorIndex = 0;
-            String descriptor = "";
-            try {
-                descriptorIndex = dex.typeIds().get(dexTypeIndex);
-                descriptor = getDexCacheString(dex, descriptorIndex);
-                resolvedType = InternalNames.getClass(getClassLoader(), descriptor);
-            } catch (NoClassDefFoundError error) {
-                throw new NoClassDefFoundError("class: " + getName()
-                        + ", dexTypeIndex=" + dexTypeIndex
-                        + ", descriptorIndex=" + descriptorIndex + ", desc=" + descriptor
-                        + ", wrapped Msg= " + error.getMessage());
-            }
-
-            dexCache.setResolvedType(dexTypeIndex, resolvedType);
-        }
-        return resolvedType;
-    }
-
-    /**
      * @hide
      */
     public int getAccessFlags() {
diff --git a/ojluni/src/main/java/java/lang/ClassLoader.java b/ojluni/src/main/java/java/lang/ClassLoader.java
index 9a34a34..8b9d27d 100644
--- a/ojluni/src/main/java/java/lang/ClassLoader.java
+++ b/ojluni/src/main/java/java/lang/ClassLoader.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -160,7 +160,7 @@
  *     }
  * </pre></blockquote>
  *
- * <h4> <a name="name">Binary names</a> </h4>
+ * <h3> <a name="name">Binary names</a> </h3>
  *
  * <p> Any class name provided as a {@link String} parameter to methods in
  * <tt>ClassLoader</tt> must be a binary name as defined by
@@ -298,7 +298,7 @@
      * #loadClass(String, boolean)} method.  It is invoked by the Java virtual
      * machine to resolve class references.  Invoking this method is equivalent
      * to invoking {@link #loadClass(String, boolean) <tt>loadClass(name,
-     * false)</tt>}.  </p>
+     * false)</tt>}.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
@@ -317,7 +317,7 @@
      * default implementation of this method searches for classes in the
      * following order:
      *
-     * <p><ol>
+     * <ol>
      *
      *   <li><p> Invoke {@link #findLoadedClass(String)} to check if the class
      *   has already been loaded.  </p></li>
@@ -360,7 +360,7 @@
         throws ClassNotFoundException
     {
             // First, check if the class has already been loaded
-            Class c = findLoadedClass(name);
+            Class<?> c = findLoadedClass(name);
             if (c == null) {
                 try {
                     if (parent != null) {
@@ -389,7 +389,7 @@
      * follow the delegation model for loading classes, and will be invoked by
      * the {@link #loadClass <tt>loadClass</tt>} method after checking the
      * parent class loader for the requested class.  The default implementation
-     * throws a <tt>ClassNotFoundException</tt>.  </p>
+     * throws a <tt>ClassNotFoundException</tt>.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
@@ -542,7 +542,7 @@
      * bootstrap class loader.  If <tt>name</tt> is not <tt>null</tt>, it
      * must be equal to the <a href="#name">binary name</a> of the class
      * specified by the byte array "<tt>b</tt>", otherwise a {@link
-     * NoClassDefFoundError} will be thrown.  </p>
+     * NoClassDefFoundError <tt>NoClassDefFoundError</tt>} will be thrown. </p>
      *
      * @param  name
      *         The expected <a href="#name">binary name</a> of the class, or
@@ -609,16 +609,16 @@
      * <i>bBuffer</i><tt>,</tt> <i>pd</i><tt>)</tt> yields exactly the same
      * result as the statements
      *
-     * <blockquote><tt>
+     *<p> <tt>
      * ...<br>
-     * byte[] temp = new byte[</tt><i>bBuffer</i><tt>.{@link
+     * byte[] temp = new byte[bBuffer.{@link
      * java.nio.ByteBuffer#remaining remaining}()];<br>
-     *     </tt><i>bBuffer</i><tt>.{@link java.nio.ByteBuffer#get(byte[])
+     *     bBuffer.{@link java.nio.ByteBuffer#get(byte[])
      * get}(temp);<br>
      *     return {@link #defineClass(String, byte[], int, int, ProtectionDomain)
-     * </tt><i>cl</i><tt>.defineClass}(</tt><i>name</i><tt>, temp, 0,
-     * temp.length, </tt><i>pd</i><tt>);<br>
-     * </tt></blockquote>
+     * cl.defineClass}(name, temp, 0,
+     * temp.length, pd);<br>
+     * </tt></p>
      *
      * @param  name
      *         The expected <a href="#name">binary name</a>. of the class, or
@@ -666,7 +666,6 @@
      * already been linked, then this method simply returns. Otherwise, the
      * class is linked as described in the "Execution" chapter of
      * <cite>The Java&trade; Language Specification</cite>.
-     * </p>
      *
      * @param  c
      *         The class to link
@@ -711,7 +710,7 @@
      * Returns a class loaded by the bootstrap class loader;
      * or return null if not found.
      */
-    private Class findBootstrapClassOrNull(String name)
+    private Class<?> findBootstrapClassOrNull(String name)
     {
         return null;
     }
@@ -720,7 +719,7 @@
      * Returns the class with the given <a href="#name">binary name</a> if this
      * loader has been recorded by the Java virtual machine as an initiating
      * loader of a class with that <a href="#name">binary name</a>.  Otherwise
-     * <tt>null</tt> is returned.  </p>
+     * <tt>null</tt> is returned.
      *
      * @param  name
      *         The <a href="#name">binary name</a> of the class
@@ -741,7 +740,7 @@
 
     /**
      * Sets the signers of a class.  This should be invoked after defining a
-     * class.  </p>
+     * class.
      *
      * @param  c
      *         The <tt>Class</tt> object
@@ -770,6 +769,10 @@
      * built-in to the virtual machine is searched.  That failing, this method
      * will invoke {@link #findResource(String)} to find the resource.  </p>
      *
+     * @apiNote When overriding this method it is recommended that an
+     * implementation ensures that any delegation is consistent with the {@link
+     * #getResources(java.lang.String) getResources(String)} method.
+     *
      * @param  name
      *         The resource name
      *
@@ -803,6 +806,13 @@
      * <p> The search order is described in the documentation for {@link
      * #getResource(String)}.  </p>
      *
+     * @apiNote When overriding this method it is recommended that an
+     * implementation ensures that any delegation is consistent with the {@link
+     * #getResource(java.lang.String) getResource(String)} method. This should
+     * ensure that the first element returned by the Enumeration's
+     * {@code nextElement} method is the same resource that the
+     * {@code getResource(String)} method would return.
+     *
      * @param  name
      *         The resource name
      *
@@ -819,7 +829,8 @@
      * @since  1.2
      */
     public Enumeration<URL> getResources(String name) throws IOException {
-        Enumeration[] tmp = new Enumeration[2];
+        @SuppressWarnings("unchecked")
+        Enumeration<URL>[] tmp = (Enumeration<URL>[]) new Enumeration<?>[2];
         if (parent != null) {
             tmp[0] = parent.getResources(name);
         } else {
@@ -832,7 +843,7 @@
 
     /**
      * Finds the resource with the given name. Class loader implementations
-     * should override this method to specify where to find resources.  </p>
+     * should override this method to specify where to find resources.
      *
      * @param  name
      *         The resource name
@@ -850,7 +861,7 @@
      * Returns an enumeration of {@link java.net.URL <tt>URL</tt>} objects
      * representing all the resources with the given name. Class loader
      * implementations should override this method to specify where to load
-     * resources from.  </p>
+     * resources from.
      *
      * @param  name
      *         The resource name
@@ -868,14 +879,16 @@
     }
 
     /**
-     * Registers the caller as parallel capable.</p>
+     * Registers the caller as parallel capable.
      * The registration succeeds if and only if all of the following
-     * conditions are met: <br>
-     * 1. no instance of the caller has been created</p>
-     * 2. all of the super classes (except class Object) of the caller are
-     * registered as parallel capable</p>
-     * Note that once a class loader is registered as parallel capable, there
-     * is no way to change it back. </p>
+     * conditions are met:
+     * <ol>
+     * <li> no instance of the caller has been created</li>
+     * <li> all of the super classes (except class Object) of the caller are
+     * registered as parallel capable</li>
+     * </ol>
+     * <p>Note that once a class loader is registered as parallel capable, there
+     * is no way to change it back.</p>
      *
      * @return  true if the caller is successfully registered as
      *          parallel capable and false if otherwise.
@@ -890,7 +903,7 @@
     /**
      * Find a resource of the specified name from the search path used to load
      * classes.  This method locates the resource through the system class
-     * loader (see {@link #getSystemClassLoader()}).  </p>
+     * loader (see {@link #getSystemClassLoader()}).
      *
      * @param  name
      *         The resource name
@@ -982,7 +995,7 @@
     /**
      * Open for reading, a resource of the specified name from the search path
      * used to load classes.  This method locates the resource through the
-     * system class loader (see {@link #getSystemClassLoader()}).  </p>
+     * system class loader (see {@link #getSystemClassLoader()}).
      *
      * @param  name
      *         The resource name
@@ -1101,7 +1114,7 @@
      * class loaders to define the packages for their classes. Packages must
      * be created before the class is defined, and package names must be
      * unique within a class loader and cannot be redefined or changed once
-     * created.  </p>
+     * created.
      *
      * @param  name
      *         The package name
@@ -1158,7 +1171,7 @@
 
     /**
      * Returns a <tt>Package</tt> that has been defined by this class loader
-     * or any of its ancestors.  </p>
+     * or any of its ancestors.
      *
      * @param  name
      *         The package name
@@ -1178,7 +1191,7 @@
 
     /**
      * Returns all of the <tt>Packages</tt> defined by this class loader and
-     * its ancestors.  </p>
+     * its ancestors.
      *
      * @return  The array of <tt>Package</tt> objects defined by this
      *          <tt>ClassLoader</tt>
@@ -1202,7 +1215,7 @@
      * method to locate the native libraries that belong to classes loaded with
      * this class loader. If this method returns <tt>null</tt>, the VM
      * searches the library along the path specified as the
-     * "<tt>java.library.path</tt>" property.  </p>
+     * "<tt>java.library.path</tt>" property.
      *
      * @param  libname
      *         The library name
@@ -1224,7 +1237,7 @@
      * in the future will have assertions enabled or disabled by default.
      * This setting may be overridden on a per-package or per-class basis by
      * invoking {@link #setPackageAssertionStatus(String, boolean)} or {@link
-     * #setClassAssertionStatus(String, boolean)}.  </p>
+     * #setClassAssertionStatus(String, boolean)}.
      *
      * @param  enabled
      *         <tt>true</tt> if classes loaded by this class loader will
@@ -1308,7 +1321,6 @@
      * status settings associated with the class loader.  This method is
      * provided so that class loaders can be made to ignore any command line or
      * persistent assertion status settings and "start with a clean slate."
-     * </p>
      *
      * @since  1.4
      */
diff --git a/ojluni/src/main/java/java/lang/Override.java b/ojluni/src/main/java/java/lang/Override.java
index f708105..bf77344 100644
--- a/ojluni/src/main/java/java/lang/Override.java
+++ b/ojluni/src/main/java/java/lang/Override.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@
  *
  * @author  Peter von der Ah&eacute;
  * @author  Joshua Bloch
- * @jls 9.6.1.4 Override
+ * @jls 9.6.1.4 @Override
  * @since 1.5
  */
 @Target(ElementType.METHOD)
diff --git a/ojluni/src/main/java/java/lang/System.java b/ojluni/src/main/java/java/lang/System.java
index 4797c1b..6e8f74f 100644
--- a/ojluni/src/main/java/java/lang/System.java
+++ b/ojluni/src/main/java/java/lang/System.java
@@ -41,6 +41,8 @@
 import java.util.PropertyPermission;
 import libcore.icu.ICU;
 import libcore.io.Libcore;
+import libcore.util.TimeZoneDataFiles;
+
 import sun.reflect.CallerSensitive;
 import sun.security.util.SecurityConstants;
 /**
@@ -996,7 +998,7 @@
         // is prioritized over the properties in ICUConfig.properties. The issue with using
         // that is that it doesn't play well with jarjar and it needs complicated build rules
         // to change its default value.
-        String icuDataPath = generateIcuDataPath();
+        String icuDataPath = TimeZoneDataFiles.generateIcuDataPath();
         p.put("android.icu.impl.ICUBinary.dataPath", icuDataPath);
 
         parsePropertyAssignments(p, specialProperties());
@@ -1023,37 +1025,6 @@
         return p;
     }
 
-    private static String generateIcuDataPath() {
-        StringBuilder icuDataPathBuilder = new StringBuilder();
-        // ICU should first look in ANDROID_DATA. This is used for (optional) timezone data.
-        String dataIcuDataPath = getEnvironmentPath("ANDROID_DATA", "/misc/zoneinfo/current/icu");
-        if (dataIcuDataPath != null) {
-            icuDataPathBuilder.append(dataIcuDataPath);
-        }
-
-        // ICU should always look in ANDROID_ROOT.
-        String systemIcuDataPath = getEnvironmentPath("ANDROID_ROOT", "/usr/icu");
-        if (systemIcuDataPath != null) {
-            if (icuDataPathBuilder.length() > 0) {
-                icuDataPathBuilder.append(":");
-            }
-            icuDataPathBuilder.append(systemIcuDataPath);
-        }
-        return icuDataPathBuilder.toString();
-    }
-
-    /**
-     * Creates a path by combining the value of an environment variable with a relative path.
-     * Returns {@code null} if the environment variable is not set.
-     */
-    private static String getEnvironmentPath(String environmentVariable, String path) {
-        String variable = getenv(environmentVariable);
-        if (variable == null) {
-            return null;
-        }
-        return variable + path;
-    }
-
     private static Properties initProperties() {
         Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableProps);
         setDefaultChangeableProperties(p);
diff --git a/ojluni/src/main/java/java/lang/annotation/ElementType.java b/ojluni/src/main/java/java/lang/annotation/ElementType.java
index 13b48f6..4590f39 100644
--- a/ojluni/src/main/java/java/lang/annotation/ElementType.java
+++ b/ojluni/src/main/java/java/lang/annotation/ElementType.java
@@ -26,15 +26,49 @@
 package java.lang.annotation;
 
 /**
- * A program element type.  The constants of this enumerated type
- * provide a simple classification of the declared elements in a
- * Java program.
+ * The constants of this enumerated type provide a simple classification of the
+ * syntactic locations where annotations may appear in a Java program. These
+ * constants are used in {@link Target java.lang.annotation.Target}
+ * meta-annotations to specify where it is legal to write annotations of a
+ * given type.
  *
- * <p>These constants are used with the {@link Target} meta-annotation type
- * to specify where it is legal to use an annotation type.
+ * <p>The syntactic locations where annotations may appear are split into
+ * <em>declaration contexts</em> , where annotations apply to declarations, and
+ * <em>type contexts</em> , where annotations apply to types used in
+ * declarations and expressions.
+ *
+ * <p>The constants {@link #ANNOTATION_TYPE} , {@link #CONSTRUCTOR} , {@link
+ * #FIELD} , {@link #LOCAL_VARIABLE} , {@link #METHOD} , {@link #PACKAGE} ,
+ * {@link #PARAMETER} , {@link #TYPE} , and {@link #TYPE_PARAMETER} correspond
+ * to the declaration contexts in JLS 9.6.4.1.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.FIELD)} may only be written as a modifier for a
+ * field declaration.
+ *
+ * <p>The constant {@link #TYPE_USE} corresponds to the 15 type contexts in JLS
+ * 4.11, as well as to two declaration contexts: type declarations (including
+ * annotation type declarations) and type parameter declarations.
+ *
+ * <p>For example, an annotation whose type is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)} may be written on the type of a field
+ * (or within the type of the field, if it is a nested, parameterized, or array
+ * type), and may also appear as a modifier for, say, a class declaration.
+ *
+ * <p>The {@code TYPE_USE} constant includes type declarations and type
+ * parameter declarations as a convenience for designers of type checkers which
+ * give semantics to annotation types. For example, if the annotation type
+ * {@code NonNull} is meta-annotated with
+ * {@code @Target(ElementType.TYPE_USE)}, then {@code @NonNull}
+ * {@code class C {...}} could be treated by a type checker as indicating that
+ * all variables of class {@code C} are non-null, while still allowing
+ * variables of other classes to be non-null or not non-null based on whether
+ * {@code @NonNull} appears at the variable's declaration.
  *
  * @author  Joshua Bloch
  * @since 1.5
+ * @jls 9.6.4.1 @Target
+ * @jls 4.1 The Kinds of Types and Values
  */
 public enum ElementType {
     /** Class, interface (including annotation type), or enum declaration */
diff --git a/ojluni/src/main/java/java/lang/invoke/CallSite.java b/ojluni/src/main/java/java/lang/invoke/CallSite.java
index f9338e6..b2226bf 100644
--- a/ojluni/src/main/java/java/lang/invoke/CallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/CallSite.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -61,7 +61,7 @@
  * <p>
  * Here is a sample use of call sites and bootstrap methods which links every
  * dynamic call site to print its arguments:
-<blockquote><pre><!-- see indy-demo/src/PrintArgsDemo.java -->
+<blockquote><pre>{@code
 static void test() throws Throwable {
     // THE FOLLOWING LINE IS PSEUDOCODE FOR A JVM INSTRUCTION
     InvokeDynamic[#bootstrapDynamic].baz("baz arg", 2, 3.14);
@@ -80,7 +80,7 @@
   // ignore caller and name, but match the type:
   return new ConstantCallSite(printArgs.asType(type));
 }
-</pre></blockquote>
+}</pre></blockquote>
  * @author John Rose, JSR 292 EG
  */
 abstract
@@ -102,13 +102,12 @@
      * via a call to {@link CallSite#setTarget(MethodHandle) setTarget}.
      * @throws NullPointerException if the proposed type is null
      */
-
     /*package-private*/
     CallSite(MethodType type) {
         // Android-changed: No cache for these so create uninitializedCallSite target here using
         // method handle transformations to create a method handle that has the expected method
         // type but throws an IllegalStateException.
-        // target = type.invokers().uninitializedCallSite();
+        // target = makeUninitializedCallSite(type);
         this.target = MethodHandles.throwException(type.returnType(), IllegalStateException.class);
         this.target = MethodHandles.insertArguments(
             this.target, 0, new IllegalStateException("uninitialized call site"));
@@ -144,7 +143,7 @@
      *         or if the target returned by the hook is not of the given {@code targetType}
      * @throws NullPointerException if the hook returns a null value
      * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
-     * @throws Throwable anything else thrown by the the hook function
+     * @throws Throwable anything else thrown by the hook function
      */
     /*package-private*/
     CallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
@@ -223,19 +222,19 @@
      * which has been linked to this call site.
      * <p>
      * This method is equivalent to the following code:
-     * <blockquote><pre>
+     * <blockquote><pre>{@code
      * MethodHandle getTarget, invoker, result;
      * getTarget = MethodHandles.publicLookup().bind(this, "getTarget", MethodType.methodType(MethodHandle.class));
      * invoker = MethodHandles.exactInvoker(this.type());
      * result = MethodHandles.foldArguments(invoker, getTarget)
-     * </pre></blockquote>
+     * }</pre></blockquote>
      *
      * @return a method handle which always invokes this call site's current target
      */
     public abstract MethodHandle dynamicInvoker();
 
     /*non-public*/ MethodHandle makeDynamicInvoker() {
-        // Android-changed: Use bindTo() rather than bindReceiver() (not implemented).
+        // Android-changed: Use bindTo() rather than bindArgumentL() (not implemented).
         MethodHandle getTarget = GET_TARGET.bindTo(this);
         MethodHandle invoker = MethodHandles.exactInvoker(this.type());
         return MethodHandles.foldArguments(invoker, getTarget);
@@ -302,7 +301,7 @@
     //                          Object info,
     //                          // Caller information:
     //                          Class<?> callerClass) {
-    //     Object caller = IMPL_LOOKUP.in(callerClass);
+    //     MethodHandles.Lookup caller = IMPL_LOOKUP.in(callerClass);
     //     CallSite site;
     //     try {
     //         Object binding;
@@ -314,14 +313,44 @@
     //         } else {
     //             Object[] argv = (Object[]) info;
     //             maybeReBoxElements(argv);
-    //             if (3 + argv.length > 255)
-    //                 throw new BootstrapMethodError("too many bootstrap method arguments");
-    //             MethodType bsmType = bootstrapMethod.type();
-    //             if (bsmType.parameterCount() == 4 && bsmType.parameterType(3) == Object[].class)
-    //                 binding = bootstrapMethod.invoke(caller, name, type, argv);
-    //             else
-    //                 binding = MethodHandles.spreadInvoker(bsmType, 3)
-    //                     .invoke(bootstrapMethod, caller, name, type, argv);
+    //             switch (argv.length) {
+    //             case 0:
+    //                 binding = bootstrapMethod.invoke(caller, name, type);
+    //                 break;
+    //             case 1:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0]);
+    //                 break;
+    //             case 2:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1]);
+    //                 break;
+    //             case 3:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2]);
+    //                 break;
+    //             case 4:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2], argv[3]);
+    //                 break;
+    //             case 5:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2], argv[3], argv[4]);
+    //                 break;
+    //             case 6:
+    //                 binding = bootstrapMethod.invoke(caller, name, type,
+    //                                                  argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+    //                 break;
+    //             default:
+    //                 final int NON_SPREAD_ARG_COUNT = 3;  // (caller, name, type)
+    //                 if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
+    //                     throw new BootstrapMethodError("too many bootstrap method arguments");
+    //                 MethodType bsmType = bootstrapMethod.type();
+    //                 MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+    //                 MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+    //                 MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+    //                 binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv);
+    //             }
     //         }
     //         //System.out.println("BSM for "+name+type+" => "+binding);
     //         if (binding instanceof CallSite) {
@@ -330,7 +359,7 @@
     //             throw new ClassCastException("bootstrap method failed to produce a CallSite");
     //         }
     //         if (!site.getTarget().type().equals(type))
-    //             throw new WrongMethodTypeException("wrong type: "+site.getTarget());
+    //             throw wrongTargetType(site.getTarget(), type);
     //     } catch (Throwable ex) {
     //         BootstrapMethodError bex;
     //         if (ex instanceof BootstrapMethodError)
@@ -341,6 +370,7 @@
     //     }
     //     return site;
     // }
+
     // private static Object maybeReBox(Object x) {
     //     if (x instanceof Integer) {
     //         int xi = (int) x;
diff --git a/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java b/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java
index 2d9fede..f27d0e7b 100644
--- a/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/ConstantCallSite.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -75,7 +75,7 @@
      *         or if the target returned by the hook is not of the given {@code targetType}
      * @throws NullPointerException if the hook returns a null value
      * @throws ClassCastException if the hook returns something other than a {@code MethodHandle}
-     * @throws Throwable anything else thrown by the the hook function
+     * @throws Throwable anything else thrown by the hook function
      */
     protected ConstantCallSite(MethodType targetType, MethodHandle createTargetHook) throws Throwable {
         super(targetType, createTargetHook);
@@ -85,7 +85,7 @@
     /**
      * Returns the target method of the call site, which behaves
      * like a {@code final} field of the {@code ConstantCallSite}.
-     * That is, the the target is always the original value passed
+     * That is, the target is always the original value passed
      * to the constructor call which created this instance.
      *
      * @return the immutable linkage state of this call site, a constant method handle
diff --git a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
index 37ca324..bb01d4c 100644
--- a/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
+++ b/ojluni/src/main/java/java/lang/invoke/MutableCallSite.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -40,7 +40,7 @@
  * Here is an example of a mutable call site which introduces a
  * state variable into a method handle chain.
  * <!-- JavaDocExamplesTest.testMutableCallSite -->
- * <blockquote><pre>
+ * <blockquote><pre>{@code
 MutableCallSite name = new MutableCallSite(MethodType.methodType(String.class));
 MethodHandle MH_name = name.dynamicInvoker();
 MethodType MT_str1 = MethodType.methodType(String.class);
@@ -52,10 +52,10 @@
 name.setTarget(MethodHandles.constant(String.class, "Fred"));
 assertEquals("FRED", (String) worker1.invokeExact());
 // (mutation can be continued indefinitely)
- * </pre></blockquote>
+ * }</pre></blockquote>
  * <p>
  * The same call site may be used in several places at once.
- * <blockquote><pre>
+ * <blockquote><pre>{@code
 MethodType MT_str2 = MethodType.methodType(String.class, String.class);
 MethodHandle MH_cat = lookup().findVirtual(String.class,
   "concat", methodType(String.class, String.class));
@@ -65,7 +65,7 @@
 name.setTarget(MethodHandles.constant(String.class, "Wilma"));
 assertEquals("WILMA", (String) worker1.invokeExact());
 assertEquals("Wilma, dear?", (String) worker2.invokeExact());
- * </pre></blockquote>
+ * }</pre></blockquote>
  * <p>
  * <em>Non-synchronization of target values:</em>
  * A write to a mutable call site's target does not force other threads
diff --git a/ojluni/src/main/java/java/lang/reflect/Array.java b/ojluni/src/main/java/java/lang/reflect/Array.java
index 8285be7..790a930 100644
--- a/ojluni/src/main/java/java/lang/reflect/Array.java
+++ b/ojluni/src/main/java/java/lang/reflect/Array.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -57,6 +57,8 @@
      * Array.newInstance(componentType, x);
      * </pre>
      * </blockquote>
+     * <p>The number of dimensions of the new array must not
+     * exceed 255.
      *
      * @param componentType the {@code Class} object representing the
      * component type of the new array
@@ -64,7 +66,9 @@
      * @return the new array
      * @exception NullPointerException if the specified
      * {@code componentType} parameter is null
-     * @exception IllegalArgumentException if componentType is {@link Void#TYPE}
+     * @exception IllegalArgumentException if componentType is {@link
+     * Void#TYPE} or if the number of dimensions of the requested array
+     * instance exceed 255.
      * @exception NegativeArraySizeException if the specified {@code length}
      * is negative
      */
@@ -88,8 +92,7 @@
      * {@code componentType}.
      *
      * <p>The number of dimensions of the new array must not
-     * exceed the number of array dimensions supported by the
-     * implementation (typically 255).
+     * exceed 255.
      *
      * @param componentType the {@code Class} object representing the component
      * type of the new array
@@ -99,10 +102,9 @@
      * @exception NullPointerException if the specified
      * {@code componentType} argument is null
      * @exception IllegalArgumentException if the specified {@code dimensions}
-     * argument is a zero-dimensional array, or if the number of
-     * requested dimensions exceeds the limit on the number of array dimensions
-     * supported by the implementation (typically 255), or if componentType
-     * is {@link Void#TYPE}.
+     * argument is a zero-dimensional array, if componentType is {@link
+     * Void#TYPE}, or if the number of dimensions of the requested array
+     * instance exceed 255.
      * @exception NegativeArraySizeException if any of the components in
      * the specified {@code dimensions} argument is negative.
      */
diff --git a/ojluni/src/main/java/java/lang/reflect/Constructor.java b/ojluni/src/main/java/java/lang/reflect/Constructor.java
index dbbb6b2..de7176b 100644
--- a/ojluni/src/main/java/java/lang/reflect/Constructor.java
+++ b/ojluni/src/main/java/java/lang/reflect/Constructor.java
@@ -27,6 +27,8 @@
 package java.lang.reflect;
 
 import dalvik.annotation.optimization.FastNative;
+import libcore.util.EmptyArray;
+
 import java.lang.annotation.Annotation;
 import java.util.Comparator;
 
@@ -127,11 +129,17 @@
     @Override
     public Class<?>[] getParameterTypes() {
         // Android-changed: This is handled by Executable.
-        return super.getParameterTypesInternal();
+        Class<?>[] paramTypes = super.getParameterTypesInternal();
+        if (paramTypes == null) {
+            return EmptyArray.CLASS;
+        }
+
+        return paramTypes;
     }
 
     /**
      * {@inheritDoc}
+     * @since 1.8
      */
     public int getParameterCount() {
         // Android-changed: This is handled by Executable.
diff --git a/ojluni/src/main/java/java/lang/reflect/Executable.java b/ojluni/src/main/java/java/lang/reflect/Executable.java
index 59f50e1..7945ad6 100644
--- a/ojluni/src/main/java/java/lang/reflect/Executable.java
+++ b/ojluni/src/main/java/java/lang/reflect/Executable.java
@@ -26,7 +26,6 @@
 package java.lang.reflect;
 
 import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
 
 import java.lang.annotation.Annotation;
 import java.util.Objects;
@@ -621,30 +620,16 @@
 
     /**
      * Returns an array of {@code Class} objects associated with the parameter types of this
-     * Executable. If the Executable was declared with no parameters, an empty array will be
+     * Executable. If the Executable was declared with no parameters, {@code null} will be
      * returned.
      *
-     * @return the parameter types
+     * @return the parameter types, or {@code null} if no parameters were declared.
      */
-    final Class<?>[] getParameterTypesInternal() {
-        Dex dex = declaringClassOfOverriddenMethod.getDex();
-        short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
-        if (types.length == 0) {
-            return EmptyArray.CLASS;
-        }
-        Class<?>[] parametersArray = new Class[types.length];
-        for (int i = 0; i < types.length; i++) {
-            // Note, in the case of a Proxy the dex cache types are equal.
-            parametersArray[i] = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
-        }
-        return parametersArray;
-    }
+    @FastNative
+    final native Class<?>[] getParameterTypesInternal();
 
-    final int getParameterCountInternal() {
-        Dex dex = declaringClassOfOverriddenMethod.getDex();
-        short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
-        return types.length;
-    }
+    @FastNative
+    final native int getParameterCountInternal();
 
     // Android provides a more efficient implementation of this method for Executable than the one
     // implemented in AnnotatedElement.
@@ -731,52 +716,17 @@
     private native String[] getSignatureAnnotation();
 
     final boolean equalNameAndParametersInternal(Method m) {
-        return getName().equals(m.getName()) && equalMethodParameters(m.getParameterTypes());
+        return getName().equals(m.getName()) && (compareMethodParametersInternal(m) == 0);
     }
 
-    private boolean equalMethodParameters(Class<?>[] params) {
-        Dex dex = declaringClassOfOverriddenMethod.getDex();
-        short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
-        if (types.length != params.length) {
-            return false;
-        }
-        for (int i = 0; i < types.length; i++) {
-            if (declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]) != params[i]) {
-                return false;
-            }
-        }
-        return true;
-    }
+    @FastNative
+    native int compareMethodParametersInternal(Method meth);
 
-    final int compareMethodParametersInternal(Class<?>[] params) {
-        Dex dex = declaringClassOfOverriddenMethod.getDex();
-        short[] types = dex.parameterTypeIndicesFromMethodIndex(dexMethodIndex);
-        int length = Math.min(types.length, params.length);
-        for (int i = 0; i < length; i++) {
-            Class<?> aType = declaringClassOfOverriddenMethod.getDexCacheType(dex, types[i]);
-            Class<?> bType = params[i];
-            if (aType != bType) {
-                int comparison = aType.getName().compareTo(bType.getName());
-                if (comparison != 0) {
-                    return comparison;
-                }
-            }
-        }
-        return types.length - params.length;
-    }
+    @FastNative
+    final native String getMethodNameInternal();
 
-    final String getMethodNameInternal() {
-        Dex dex = declaringClassOfOverriddenMethod.getDex();
-        int nameIndex = dex.nameIndexFromMethodIndex(dexMethodIndex);
-        return declaringClassOfOverriddenMethod.getDexCacheString(dex, nameIndex);
-    }
-
-    final Class<?> getMethodReturnTypeInternal() {
-        Dex dex = declaringClassOfOverriddenMethod.getDex();
-        int returnTypeIndex = dex.returnTypeIndexFromMethodIndex(dexMethodIndex);
-        // Note, in the case of a Proxy the dex cache types are equal.
-        return declaringClassOfOverriddenMethod.getDexCacheType(dex, returnTypeIndex);
-    }
+    @FastNative
+    final native Class<?> getMethodReturnTypeInternal();
 
     /** A cheap implementation for {@link Method#isDefault()}. */
     final boolean isDefaultMethodInternal() {
diff --git a/ojluni/src/main/java/java/lang/reflect/Field.java b/ojluni/src/main/java/java/lang/reflect/Field.java
index 2f1bc31..a691766 100644
--- a/ojluni/src/main/java/java/lang/reflect/Field.java
+++ b/ojluni/src/main/java/java/lang/reflect/Field.java
@@ -27,7 +27,6 @@
 package java.lang.reflect;
 
 import dalvik.annotation.optimization.FastNative;
-import com.android.dex.Dex;
 
 import java.lang.annotation.Annotation;
 import java.util.Objects;
@@ -85,11 +84,13 @@
             }
             return "throws";
         }
-        Dex dex = declaringClass.getDex();
-        int nameIndex = dex.nameIndexFromFieldIndex(dexFieldIndex);
-        return declaringClass.getDexCacheString(dex, nameIndex);
+
+        return getNameInternal();
     }
 
+    @FastNative
+    private native String getNameInternal();
+
     /**
      * Returns the Java language modifiers for the field represented
      * by this {@code Field} object, as an integer. The {@code Modifier} class should
diff --git a/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java b/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
index 1650803..3fd70d3 100644
--- a/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
+++ b/ojluni/src/main/java/java/lang/reflect/GenericSignatureFormatError.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -35,4 +35,22 @@
  */
 public class GenericSignatureFormatError extends ClassFormatError {
     private static final long serialVersionUID = 6709919147137911034L;
+
+    /**
+     * Constructs a new {@code GenericSignatureFormatError}.
+     *
+     */
+    public GenericSignatureFormatError() {
+        super();
+    }
+
+    /**
+     * Constructs a new {@code GenericSignatureFormatError} with the
+     * specified message.
+     *
+     * @param message the detail message, may be {@code null}
+     */
+    public GenericSignatureFormatError(String message) {
+        super(message);
+    }
 }
diff --git a/ojluni/src/main/java/java/lang/reflect/Member.java b/ojluni/src/main/java/java/lang/reflect/Member.java
index 7d51c18..2241d45 100644
--- a/ojluni/src/main/java/java/lang/reflect/Member.java
+++ b/ojluni/src/main/java/java/lang/reflect/Member.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,14 +42,12 @@
     /**
      * Identifies the set of all public members of a class or interface,
      * including inherited members.
-     * @see java.lang.SecurityManager#checkMemberAccess
      */
     public static final int PUBLIC = 0;
 
     /**
      * Identifies the set of declared members of a class or interface.
      * Inherited members are not included.
-     * @see java.lang.SecurityManager#checkMemberAccess
      */
     public static final int DECLARED = 1;
 
@@ -87,6 +85,7 @@
      *
      * @return true if and only if this member was introduced by
      * the compiler.
+     * @jls 13.1 The Form of a Binary
      * @since 1.5
      */
     public boolean isSynthetic();
diff --git a/ojluni/src/main/java/java/lang/reflect/Method.java b/ojluni/src/main/java/java/lang/reflect/Method.java
index 3636a1b..ddda93d 100644
--- a/ojluni/src/main/java/java/lang/reflect/Method.java
+++ b/ojluni/src/main/java/java/lang/reflect/Method.java
@@ -30,6 +30,7 @@
 import java.lang.annotation.Annotation;
 import java.util.Comparator;
 import libcore.reflect.Types;
+import libcore.util.EmptyArray;
 
 /**
  * A {@code Method} provides information about, and access to, a single method
@@ -64,7 +65,7 @@
             }
             int comparison = a.getName().compareTo(b.getName());
             if (comparison == 0) {
-                comparison = a.compareMethodParametersInternal(b.getParameterTypes());
+                comparison = a.compareMethodParametersInternal(b);
                 if (comparison == 0) {
                     // This is necessary for methods that have covariant return types.
                     Class<?> aReturnType = a.getReturnType();
@@ -137,7 +138,6 @@
      * @return the return type for the method this object represents
      */
     public Class<?> getReturnType() {
-        // Android-changed: This is handled by Executable.
         return getMethodReturnTypeInternal();
     }
 
@@ -176,11 +176,17 @@
     @Override
     public Class<?>[] getParameterTypes() {
         // Android-changed: This is handled by Executable.
-        return super.getParameterTypesInternal();
+        Class<?>[] paramTypes = super.getParameterTypesInternal();
+        if (paramTypes == null) {
+            return EmptyArray.CLASS;
+        }
+
+        return paramTypes;
     }
 
     /**
      * {@inheritDoc}
+     * @since 1.8
      */
     public int getParameterCount() {
         // Android-changed: This is handled by Executable.
diff --git a/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java b/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java
index b8e8e63..96a2d21 100644
--- a/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java
+++ b/ojluni/src/main/java/java/lang/reflect/ReflectPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
index 4c5d3de..20372a4 100644
--- a/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
+++ b/ojluni/src/main/java/java/lang/reflect/TypeVariable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,6 +48,8 @@
  *
  * @since 1.5
  */
+// Android-changed: Removed AnnotatedElement super-class due to excluded support
+// for runtime type annotations
 public interface TypeVariable<D extends GenericDeclaration> extends Type {
     /**
      * Returns an array of {@code Type} objects representing the
@@ -86,4 +88,18 @@
      * @return the name of this type variable, as it appears in the source code
      */
     String getName();
+
+    /**
+     * Returns an array of AnnotatedType objects that represent the use of
+     * types to denote the upper bounds of the type parameter represented by
+     * this TypeVariable. The order of the objects in the array corresponds to
+     * the order of the bounds in the declaration of the type parameter.
+     *
+     * Returns an array of length 0 if the type parameter declares no bounds.
+     *
+     * @return an array of objects representing the upper bounds of the type variable
+     * @since 1.8
+     */
+    // Android-changed: Excluded support for runtime type annotations
+    // AnnotatedType[] getAnnotatedBounds();
 }
diff --git a/ojluni/src/main/java/java/net/DatagramSocket.java b/ojluni/src/main/java/java/net/DatagramSocket.java
index cdb8ef7..34f3a2d 100755
--- a/ojluni/src/main/java/java/net/DatagramSocket.java
+++ b/ojluni/src/main/java/java/net/DatagramSocket.java
@@ -1347,12 +1347,17 @@
         factory = fac;
     }
 
-    /** @hide */
+    /**
+     * Android-added: for testing and internal use.
+     *
+     * @hide internal use only
+     */
     public FileDescriptor getFileDescriptor$() {
         return impl.fd;
     }
 
     /**
+     * Android-added:
      * Sets the network interface used by this socket.  Any packets sent
      * via this socket are transmitted via the specified interface.  Any
      * packets received by this socket will come from the specified
diff --git a/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java b/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java
index 18465ba..ad62c58 100644
--- a/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java
+++ b/ojluni/src/main/java/java/net/DefaultDatagramSocketImplFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007,2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,7 +35,7 @@
  */
 
 class DefaultDatagramSocketImplFactory {
-    static Class prefixImplClass = null;
+    static Class<?> prefixImplClass = null;
 
     static {
         String prefix = null;
@@ -53,10 +53,10 @@
     }
 
     /**
-     * Creates a new {@code DatagramSocketImpl} instance.
+     * Creates a new <code>DatagramSocketImpl</code> instance.
      *
      * @param   isMulticast     true if this impl if for a MutlicastSocket
-     * @return  a new instance of a {@code DatagramSocketImpl}.
+     * @return  a new instance of a <code>DatagramSocketImpl</code>.
      */
     static DatagramSocketImpl createDatagramSocketImpl(boolean isMulticast /*unused on unix*/)
         throws SocketException {
diff --git a/ojluni/src/main/java/java/net/DefaultInterface.java b/ojluni/src/main/java/java/net/DefaultInterface.java
index 9f4dfe1..0c31cb6 100644
--- a/ojluni/src/main/java/java/net/DefaultInterface.java
+++ b/ojluni/src/main/java/java/net/DefaultInterface.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 package java.net;
 
 /**
- * Choose a network inteface to be the default for
+ * Choose a network interface to be the default for
  * outgoing IPv6 traffic that does not specify a scope_id (and which needs one).
  *
  * Platforms that do not require a default interface may return null
diff --git a/ojluni/src/main/java/java/net/PlainSocketImpl.java b/ojluni/src/main/java/java/net/PlainSocketImpl.java
index 7177098..f02006d 100644
--- a/ojluni/src/main/java/java/net/PlainSocketImpl.java
+++ b/ojluni/src/main/java/java/net/PlainSocketImpl.java
@@ -25,15 +25,34 @@
  */
 package java.net;
 
+import android.system.ErrnoException;
+
 import java.io.IOException;
 import java.io.FileDescriptor;
 import java.util.Set;
 import java.util.HashSet;
 import java.util.Collections;
+import libcore.io.AsynchronousCloseMonitor;
+import libcore.io.IoBridge;
+import libcore.io.IoUtils;
+import libcore.io.Libcore;
+
 import jdk.net.*;
 
+import static android.system.OsConstants.AF_INET6;
+import static android.system.OsConstants.AF_UNIX;
+import static android.system.OsConstants.EAGAIN;
+import static android.system.OsConstants.EBADF;
+import static android.system.OsConstants.EINVAL;
+import static android.system.OsConstants.MSG_OOB;
+import static android.system.OsConstants.POLLERR;
+import static android.system.OsConstants.POLLIN;
+import static android.system.OsConstants.SOCK_DGRAM;
+import static android.system.OsConstants.SOCK_STREAM;
+import static android.system.OsConstants.SHUT_RDWR;
 import static sun.net.ExtendedOptionsImpl.*;
 
+// Android-changed: Rewritten to use android.system POSIX calls and assume AF_INET6.
 /*
  * On Unix systems we simply delegate to native methods.
  *
@@ -91,29 +110,180 @@
         }
     }
 
-    native void socketCreate(boolean isServer) throws IOException;
+    void socketCreate(boolean isStream) throws IOException {
+        // The fd object must not change after calling bind, because we rely on this undocumented
+        // behaviour. See libcore.java.net.SocketTest#testFileDescriptorStaysSame.
+        fd.setInt$(IoBridge.socket(AF_INET6, isStream ? SOCK_STREAM : SOCK_DGRAM, 0).getInt$());
 
-    native void socketConnect(InetAddress address, int port, int timeout)
-        throws IOException;
+        if (serverSocket != null) {
+            IoUtils.setBlocking(fd, false);
+            IoBridge.setSocketOption(fd, SO_REUSEADDR, true);
+        }
+    }
 
-    native void socketBind(InetAddress address, int port)
-        throws IOException;
+    void socketConnect(InetAddress address, int port, int timeout) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
 
-    native void socketListen(int count) throws IOException;
+        IoBridge.connect(fd, address, port, timeout);
 
-    native void socketAccept(SocketImpl s) throws IOException;
+        this.address = address;
+        this.port = port;
 
-    native int socketAvailable() throws IOException;
+        if (localport == 0) {
+            // If socket is pending close, fd becomes an AF_UNIX socket and calling
+            // getLocalInetSocketAddress will fail.
+            // http://b/34645743
+            if (!isClosedOrPending()) {
+                localport = IoBridge.getLocalInetSocketAddress(fd).getPort();
+            }
+        }
+    }
 
-    native void socketClose0(boolean useDeferredClose) throws IOException;
+    void socketBind(InetAddress address, int port) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
 
-    native void socketShutdown(int howto) throws IOException;
+        IoBridge.bind(fd, address, port);
+
+        this.address = address;
+        if (port == 0) {
+            // Now that we're a connected socket, let's extract the port number that the system
+            // chose for us and store it in the Socket object.
+            localport = IoBridge.getLocalInetSocketAddress(fd).getPort();
+        } else {
+            localport = port;
+        }
+    }
+
+    void socketListen(int count) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        try {
+            Libcore.os.listen(fd, count);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsSocketException();
+        }
+    }
+
+    void socketAccept(SocketImpl s) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        // poll() with a timeout of 0 means "poll for zero millis", but a Socket timeout == 0 means
+        // "wait forever". When timeout == 0 we pass -1 to poll.
+        if (timeout <= 0) {
+            IoBridge.poll(fd, POLLIN | POLLERR, -1);
+        } else {
+            IoBridge.poll(fd, POLLIN | POLLERR, timeout);
+        }
+
+        InetSocketAddress peerAddress = new InetSocketAddress();
+        try {
+            FileDescriptor newfd = Libcore.os.accept(fd, peerAddress);
+
+            s.fd.setInt$(newfd.getInt$());
+            s.address = peerAddress.getAddress();
+            s.port = peerAddress.getPort();
+        } catch (ErrnoException errnoException) {
+            if (errnoException.errno == EAGAIN) {
+                throw new SocketTimeoutException(errnoException);
+            } else if (errnoException.errno == EINVAL || errnoException.errno == EBADF) {
+                throw new SocketException("Socket closed");
+            }
+            errnoException.rethrowAsSocketException();
+        }
+
+        s.localport = IoBridge.getLocalInetSocketAddress(s.fd).getPort();
+    }
+
+    int socketAvailable() throws IOException {
+        return IoBridge.available(fd);
+    }
+
+    void socketClose0(boolean useDeferredClose) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("socket already closed");
+        }
+
+        FileDescriptor markerFD = null;
+        if (useDeferredClose) {
+            markerFD = getMarkerFD();
+        }
+
+        if (useDeferredClose && markerFD != null) {
+            try {
+                Libcore.os.dup2(markerFD, fd.getInt$());
+                Libcore.os.close(markerFD);
+
+                // This effectively closes the socket, needs to signal threads that blocks on this
+                // file descriptor.
+                AsynchronousCloseMonitor.signalBlockedThreads(fd);
+            } catch (ErrnoException errnoException) {
+                // close should not throw
+            }
+        } else {
+            // If requested or a markerFD cannot be created, a non-deferred close is performed
+            // instead.
+            IoBridge.closeAndSignalBlockedThreads(fd);
+        }
+    }
+
+    /*
+     * Create the marker file descriptor by establishing a loopback connection which we shutdown but
+     * do not close the fd. The result is an fd that can be used for read/write.
+     *
+     * The purpose is to keep hold of the raw fd handle until we are sure it is not used in any
+     * thread. Otherwise if we close the file descriptor directly, the system might reuse the raw fd
+     * number and threads holding old fd value might behave incorrectly.
+     */
+    private FileDescriptor getMarkerFD() throws SocketException {
+        FileDescriptor fd1 = new FileDescriptor();
+        FileDescriptor fd2 = new FileDescriptor();
+        try {
+            Libcore.os.socketpair(AF_UNIX, SOCK_STREAM, 0, fd1, fd2);
+
+            // Shutdown fd1, any reads to this fd will get EOF; any writes will get an error.
+            Libcore.os.shutdown(fd1, SHUT_RDWR);
+            Libcore.os.close(fd2);
+        } catch (ErrnoException errnoException) {
+            // We might have reached the maximum file descriptor number and socketpair(2) would
+            // fail. In this case, return null and let caller to fall back to an alternative method
+            // that does not allocate more file descriptors.
+            return null;
+        }
+        return fd1;
+    }
+
+    void socketShutdown(int howto) throws IOException {
+        try {
+            Libcore.os.shutdown(fd, howto);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsIOException();
+        }
+    }
 
     native void socketSetOption0(int cmd, boolean on, Object value)
         throws SocketException;
 
     native int socketGetOption(int opt, Object iaContainerObj) throws SocketException;
 
-    native void socketSendUrgentData(int data) throws IOException;
+    void socketSendUrgentData(int data) throws IOException {
+        if (fd == null || !fd.valid()) {
+            throw new SocketException("Socket closed");
+        }
+
+        try {
+            byte[] buffer = new byte[] { (byte) data };
+            Libcore.os.sendto(fd, buffer, 0, 1, MSG_OOB, null, 0);
+        } catch (ErrnoException errnoException) {
+            throw errnoException.rethrowAsSocketException();
+        }
+    }
 
 }
diff --git a/ojluni/src/main/java/java/net/ServerSocket.java b/ojluni/src/main/java/java/net/ServerSocket.java
index ccf88f8..670acf2 100644
--- a/ojluni/src/main/java/java/net/ServerSocket.java
+++ b/ojluni/src/main/java/java/net/ServerSocket.java
@@ -922,4 +922,12 @@
         /* Not implemented yet */
     }
 
+    /**
+     * Android-added: for testing and internal use.
+     *
+     * @hide internal use only
+     */
+    public FileDescriptor getFileDescriptor$() {
+        return impl.getFileDescriptor();
+    }
 }
diff --git a/ojluni/src/main/java/java/net/Socket.java b/ojluni/src/main/java/java/net/Socket.java
index ed18b48..9d566b1 100644
--- a/ojluni/src/main/java/java/net/Socket.java
+++ b/ojluni/src/main/java/java/net/Socket.java
@@ -1769,6 +1769,8 @@
     }
 
     /**
+     * Android-added: for testing and internal use.
+     *
      * @hide internal use only
      */
     public FileDescriptor getFileDescriptor$() {
diff --git a/ojluni/src/main/java/java/net/SocketInputStream.java b/ojluni/src/main/java/java/net/SocketInputStream.java
index 2757412..f5c4c8f 100644
--- a/ojluni/src/main/java/java/net/SocketInputStream.java
+++ b/ojluni/src/main/java/java/net/SocketInputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -153,11 +153,12 @@
         }
 
         // bounds check
-        if (length <= 0 || off < 0 || off + length > b.length) {
+        if (length <= 0 || off < 0 || length > b.length - off) {
             if (length == 0) {
                 return 0;
             }
-            throw new ArrayIndexOutOfBoundsException();
+            throw new ArrayIndexOutOfBoundsException("length == " + length
+                    + " off == " + off + " buffer length == " + b.length);
         }
 
         boolean gotReset = false;
diff --git a/ojluni/src/main/java/java/net/SocketOutputStream.java b/ojluni/src/main/java/java/net/SocketOutputStream.java
index d37a7d7..c0173f0 100644
--- a/ojluni/src/main/java/java/net/SocketOutputStream.java
+++ b/ojluni/src/main/java/java/net/SocketOutputStream.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,12 +95,12 @@
      * @exception IOException If an I/O error has occurred.
      */
     private void socketWrite(byte b[], int off, int len) throws IOException {
-
-        if (len <= 0 || off < 0 || off + len > b.length) {
+        if (len <= 0 || off < 0 || len > b.length - off) {
             if (len == 0) {
                 return;
             }
-            throw new ArrayIndexOutOfBoundsException();
+            throw new ArrayIndexOutOfBoundsException("len == " + len
+                    + " off == " + off + " buffer length == " + b.length);
         }
 
         FileDescriptor fd = impl.acquireFD();
diff --git a/ojluni/src/main/java/java/security/AccessControlContext.java b/ojluni/src/main/java/java/security/AccessControlContext.java
index 86a88f0..e95cff2 100644
--- a/ojluni/src/main/java/java/security/AccessControlContext.java
+++ b/ojluni/src/main/java/java/security/AccessControlContext.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/AccessController.java b/ojluni/src/main/java/java/security/AccessController.java
index 1f7bdc5..b4d544c 100644
--- a/ojluni/src/main/java/java/security/AccessController.java
+++ b/ojluni/src/main/java/java/security/AccessController.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java b/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
index 5224158..7355405 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameterGenerator.java
@@ -68,34 +68,34 @@
  *
  * <p> Android provides the following <code>AlgorithmParameterGenerator</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>AES</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DES</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DESede</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DH</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DSA</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr class="deprecated">
+ *       <td>AES</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DES</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESede</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/AlgorithmParameters.java b/ojluni/src/main/java/java/security/AlgorithmParameters.java
index af5ed7e..36bb3ee 100644
--- a/ojluni/src/main/java/java/security/AlgorithmParameters.java
+++ b/ojluni/src/main/java/java/security/AlgorithmParameters.java
@@ -48,58 +48,102 @@
  *
  * <p> Android provides the following <code>AlgorithmParameters</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>AES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>Blowfish</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>DES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DH</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>GCM</td>
- *             <td>22+</td>
- *         </tr>
- *         <tr>
- *             <td>IES</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>OAEP</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PKCS12PBE</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PSS</td>
- *             <td>1&ndash;8, 24+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>AES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BLOWFISH</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DESede</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>EC</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>GCM</td>
+ *       <td>22+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>IES</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>OAEP</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PKCS12PBE</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PSS</td>
+ *       <td>1-8,24+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/AuthProvider.java b/ojluni/src/main/java/java/security/AuthProvider.java
index 0308291..23ddb0a 100644
--- a/ojluni/src/main/java/java/security/AuthProvider.java
+++ b/ojluni/src/main/java/java/security/AuthProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/CodeSource.java b/ojluni/src/main/java/java/security/CodeSource.java
index d678011..7396d91 100644
--- a/ojluni/src/main/java/java/security/CodeSource.java
+++ b/ojluni/src/main/java/java/security/CodeSource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/DomainCombiner.java b/ojluni/src/main/java/java/security/DomainCombiner.java
index 7dc0849..5426bf6 100644
--- a/ojluni/src/main/java/java/security/DomainCombiner.java
+++ b/ojluni/src/main/java/java/security/DomainCombiner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/KeyFactory.java b/ojluni/src/main/java/java/security/KeyFactory.java
index 92149ae..a6b912c 100644
--- a/ojluni/src/main/java/java/security/KeyFactory.java
+++ b/ojluni/src/main/java/java/security/KeyFactory.java
@@ -69,34 +69,34 @@
  *
  * <p> Android provides the following <code>KeyFactory</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>DH</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>EC</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>X.509</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>EC</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>RSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>X.509</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/KeyPairGenerator.java b/ojluni/src/main/java/java/security/KeyPairGenerator.java
index c9fa996..1e46cee 100644
--- a/ojluni/src/main/java/java/security/KeyPairGenerator.java
+++ b/ojluni/src/main/java/java/security/KeyPairGenerator.java
@@ -111,30 +111,30 @@
  *
  * <p> Android provides the following <code>KeyPairGenerator</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>DH</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>EC</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>EC</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>RSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/KeyStore.java b/ojluni/src/main/java/java/security/KeyStore.java
index 43ecd6d..d091781 100644
--- a/ojluni/src/main/java/java/security/KeyStore.java
+++ b/ojluni/src/main/java/java/security/KeyStore.java
@@ -156,42 +156,42 @@
  *
  * <p> Android provides the following <code>KeyStore</code> types:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>AndroidCAStore</td>
- *             <td>14+</td>
- *         </tr>
- *         <tr>
- *             <td>AndroidKeyStore</td>
- *             <td>18+</td>
- *         </tr>
- *         <tr>
- *             <td>BCPKCS12</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>BKS</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>BouncyCastle</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PKCS12</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PKCS12-DEF</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>AndroidCAStore</td>
+ *       <td>14+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>AndroidKeyStore</td>
+ *       <td>18+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>BCPKCS12</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BKS</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BouncyCastle</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PKCS12</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>PKCS12-DEF</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These types are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/MessageDigest.java b/ojluni/src/main/java/java/security/MessageDigest.java
index d173048..df6c456 100644
--- a/ojluni/src/main/java/java/security/MessageDigest.java
+++ b/ojluni/src/main/java/java/security/MessageDigest.java
@@ -87,38 +87,38 @@
  *
  * <p> Android provides the following <code>MessageDigest</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>MD5</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA-1</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA-224</td>
- *             <td>1&ndash;8,22+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA-256</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA-384</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA-512</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>MD5</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-224</td>
+ *       <td>1-8,22+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-256</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-384</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA-512</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java b/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java
index fb34981..951e44e 100644
--- a/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java
+++ b/ojluni/src/main/java/java/security/NoSuchAlgorithmException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,13 +58,13 @@
     }
 
     /**
-     * Creates a <code>NoSuchAlgorithmException</code> with the specified
+     * Creates a {@code NoSuchAlgorithmException} with the specified
      * detail message and cause.
      *
      * @param message the detail message (which is saved for later retrieval
      *        by the {@link #getMessage()} method).
      * @param cause the cause (which is saved for later retrieval by the
-     *        {@link #getCause()} method).  (A <tt>null</tt> value is permitted,
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
      *        and indicates that the cause is nonexistent or unknown.)
      * @since 1.5
      */
@@ -73,13 +73,13 @@
     }
 
     /**
-     * Creates a <code>NoSuchAlgorithmException</code> with the specified cause
-     * and a detail message of <tt>(cause==null ? null : cause.toString())</tt>
+     * Creates a {@code NoSuchAlgorithmException} with the specified cause
+     * and a detail message of {@code (cause==null ? null : cause.toString())}
      * (which typically contains the class and detail message of
-     * <tt>cause</tt>).
+     * {@code cause}).
      *
      * @param cause the cause (which is saved for later retrieval by the
-     *        {@link #getCause()} method).  (A <tt>null</tt> value is permitted,
+     *        {@link #getCause()} method).  (A {@code null} value is permitted,
      *        and indicates that the cause is nonexistent or unknown.)
      * @since 1.5
      */
diff --git a/ojluni/src/main/java/java/security/Permission.java b/ojluni/src/main/java/java/security/Permission.java
index 9f04ac4..8d170c0 100644
--- a/ojluni/src/main/java/java/security/Permission.java
+++ b/ojluni/src/main/java/java/security/Permission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/Permissions.java b/ojluni/src/main/java/java/security/Permissions.java
index de5d451..7411e06 100644
--- a/ojluni/src/main/java/java/security/Permissions.java
+++ b/ojluni/src/main/java/java/security/Permissions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/PrivilegedAction.java b/ojluni/src/main/java/java/security/PrivilegedAction.java
index ab39f98..bef7e44 100644
--- a/ojluni/src/main/java/java/security/PrivilegedAction.java
+++ b/ojluni/src/main/java/java/security/PrivilegedAction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java b/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java
index 87e4209..bae883e 100644
--- a/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java
+++ b/ojluni/src/main/java/java/security/PrivilegedExceptionAction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/SecurityPermission.java b/ojluni/src/main/java/java/security/SecurityPermission.java
index 432ee4b..7d2ec47 100644
--- a/ojluni/src/main/java/java/security/SecurityPermission.java
+++ b/ojluni/src/main/java/java/security/SecurityPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/Signature.java b/ojluni/src/main/java/java/security/Signature.java
index 730803f..7e9f5a8 100644
--- a/ojluni/src/main/java/java/security/Signature.java
+++ b/ojluni/src/main/java/java/security/Signature.java
@@ -99,106 +99,142 @@
  *
  * <p> Android provides the following {@code Signature} algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>DSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DSAwithSHA1</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DSS</td>
- *             <td>1&ndash;19</td>
- *         </tr>
- *         <tr>
- *             <td>ECDSA</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>ECDSAwithSHA1</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>MD2withRSA</td>
- *             <td>1&ndash;3</td>
- *         </tr>
- *         <tr>
- *             <td>MD4withRSA</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>MD5withRSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>MD5withRSA/ISO9796-2</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>NONEwithDSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>NONEwithECDSA</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>NONEwithRSA</td>
- *             <td>17+</td>
- *         </tr>
- *         <tr>
- *             <td>RSASSA-PSS</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>SHA1withDSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA1withECDSA</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA1withRSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA1withRSA/ISO9796-2</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>SHA256withECDSA</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA256withRSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA384withECDSA</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA384withRSA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA512withECDSA</td>
- *             <td>11+</td>
- *         </tr>
- *         <tr>
- *             <td>SHA512withRSA</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DSAwithSHA1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DSS</td>
+ *       <td>1-19</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ECDSAwithSHA1</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>MD2withRSA</td>
+ *       <td>1-3</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>MD4withRSA</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>MD5withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>MD5withRSA/ISO9796-2</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>NONEwithDSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>NONEwithECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>NONEwithRSA</td>
+ *       <td>17+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>RSASSA-PSS</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withDSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SHA1withRSA/ISO9796-2</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA1withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withDSA</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withECDSA</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withRSA</td>
+ *       <td>20+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA224withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withDSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA256withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA384withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA384withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA384withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA512withECDSA</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA512withRSA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SHA512withRSA/PSS</td>
+ *       <td>23+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/java/security/UnresolvedPermission.java b/ojluni/src/main/java/java/security/UnresolvedPermission.java
index dec952b..6d97fbe 100644
--- a/ojluni/src/main/java/java/security/UnresolvedPermission.java
+++ b/ojluni/src/main/java/java/security/UnresolvedPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/java/security/cert/CertPathBuilder.java b/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
index da5e322..fd6cdc8 100644
--- a/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
+++ b/ojluni/src/main/java/java/security/cert/CertPathBuilder.java
@@ -68,18 +68,18 @@
  *
  * <p> Android provides the following {@code CertPathBuilder} algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>PKIX</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>PKIX</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * This algorithm is described in the <a href=
diff --git a/ojluni/src/main/java/java/security/cert/CertPathValidator.java b/ojluni/src/main/java/java/security/cert/CertPathValidator.java
index 40adafe..3a4b053 100644
--- a/ojluni/src/main/java/java/security/cert/CertPathValidator.java
+++ b/ojluni/src/main/java/java/security/cert/CertPathValidator.java
@@ -70,18 +70,18 @@
  *
  * <p> Android provides the following {@code CertPathValidator} algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>PKIX</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>PKIX</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * This algorithm is described in the <a href=
diff --git a/ojluni/src/main/java/java/security/cert/CertStore.java b/ojluni/src/main/java/java/security/cert/CertStore.java
index add36cd..047af77 100644
--- a/ojluni/src/main/java/java/security/cert/CertStore.java
+++ b/ojluni/src/main/java/java/security/cert/CertStore.java
@@ -62,18 +62,18 @@
  *
  * <p> Android provides the following <code>CertStore</code> types:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>Collection</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>Collection</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * This type is described in the <a href=
diff --git a/ojluni/src/main/java/java/security/cert/CertificateFactory.java b/ojluni/src/main/java/java/security/cert/CertificateFactory.java
index e82a579..e74ff0a 100644
--- a/ojluni/src/main/java/java/security/cert/CertificateFactory.java
+++ b/ojluni/src/main/java/java/security/cert/CertificateFactory.java
@@ -93,18 +93,18 @@
  *
  * <p> Android provides the following <code>CertificateFactory</code> types:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>X.509</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>X.509</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  * and the following <code>CertPath</code> encodings:
  * <table>
diff --git a/ojluni/src/main/java/java/util/regex/MatchResult.java b/ojluni/src/main/java/java/util/regex/MatchResult.java
index 9b52331..4f42eae 100644
--- a/ojluni/src/main/java/java/util/regex/MatchResult.java
+++ b/ojluni/src/main/java/java/util/regex/MatchResult.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -77,9 +77,9 @@
     public int start(int group);
 
     /**
-     * Returns the offset after the last character matched.  </p>
+     * Returns the offset after the last character matched.
      *
-     * @return  @return  The offset after the last character matched
+     * @return  The offset after the last character matched
      *
      * @throws  IllegalStateException
      *          If no match has yet been attempted,
diff --git a/ojluni/src/main/java/java/util/regex/Matcher.java b/ojluni/src/main/java/java/util/regex/Matcher.java
index 3d79ba7..9805dde 100644
--- a/ojluni/src/main/java/java/util/regex/Matcher.java
+++ b/ojluni/src/main/java/java/util/regex/Matcher.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1999, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/crypto/Cipher.java b/ojluni/src/main/java/javax/crypto/Cipher.java
index ea88f04..c2a2183 100644
--- a/ojluni/src/main/java/javax/crypto/Cipher.java
+++ b/ojluni/src/main/java/javax/crypto/Cipher.java
@@ -134,494 +134,87 @@
  * </pre>
  * <p> Android provides the following <code>Cipher</code> transformations:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *         <tr>
- *             <td>AES/CBC/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CBC/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CBC/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CTR/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CTR/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CTR/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CTS/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CTS/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/CTS/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/ECB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/ECB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/ECB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/OFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/OFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AES/OFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>ARCFOUR/ECB/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CBC/ISO10126Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CBC/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CBC/PKCS5Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CFB/ISO10126Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CFB/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CFB/PKCS5Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CTR/ISO10126Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CTR/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CTR/PKCS5Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CTS/ISO10126Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CTS/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/CTS/PKCS5Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/ECB/ISO10126Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/ECB/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/ECB/PKCS5Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/OFB/ISO10126Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/OFB/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>BLOWFISH/OFB/PKCS5Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CBC/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CBC/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CBC/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CTR/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CTR/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CTR/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CTS/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CTS/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/CTS/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/ECB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/ECB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/ECB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/OFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/OFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DES/OFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CBC/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CBC/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CBC/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CTR/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CTR/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CTR/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CTS/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CTS/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/CTS/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/ECB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/ECB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/ECB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/OFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/OFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede/OFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CBC/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CBC/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CBC/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CTR/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CTR/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CTR/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CTS/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CTS/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/CTS/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/ECB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/ECB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/ECB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/OFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/OFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES/OFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CBC/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CBC/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CBC/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CTR/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CTR/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CTR/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CTS/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CTS/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/CTS/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/ECB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/ECB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/ECB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/OFB/ISO10126Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/OFB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDESede/OFB/PKCS5Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RC4/ECB/NoPadding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/ECB/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/ECB/OAEPPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/ECB/OAEPwithSHA-1andMGF1Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/ECB/OAEPwithSHA-256andMGF1Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/ECB/PKCS1Padding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/NONE/NoPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/NONE/OAEPPadding</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/NONE/OAEPwithSHA-1andMGF1Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/NONE/OAEPwithSHA-256andMGF1Padding</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>RSA/NONE/PKCS1Padding</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Modes</th>
+ *       <th>Paddings</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td rowspan="2">AES</td>
+ *       <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ *       <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>GCM</td>
+ *       <td>NOPADDING</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td rowspan="2">AES_128</td>
+ *       <td>CBC<br>ECB</td>
+ *       <td>NoPadding<br>PKCS5Padding</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>GCM</td>
+ *       <td>NoPadding</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td rowspan="2">AES_256</td>
+ *       <td>CBC<br>ECB</td>
+ *       <td>NoPadding<br>PKCS5Padding</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>GCM</td>
+ *       <td>NoPadding</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ARC4</td>
+ *       <td>ECB</td>
+ *       <td>NoPadding</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BLOWFISH</td>
+ *       <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ *       <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DES</td>
+ *       <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ *       <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DESede</td>
+ *       <td>CBC<br>CFB<br>CTR<br>CTS<br>ECB<br>OFB</td>
+ *       <td>ISO10126Padding<br>NoPadding<br>PKCS5Padding</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td rowspan="3">RSA</td>
+ *       <td rowspan="3">ECB<br>NONE</td>
+ *       <td>NoPadding<br>OAEPPadding<br>PKCS1Padding</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>OAEPwithSHA-1andMGF1Padding<br>OAEPwithSHA-256andMGF1Padding</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>OAEPwithSHA-224andMGF1Padding<br>OAEPwithSHA-384andMGF1Padding<br>OAEPwithSHA-512andMGF1Padding</td>
+ *       <td>23+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These transformations are described in the
diff --git a/ojluni/src/main/java/javax/crypto/CipherOutputStream.java b/ojluni/src/main/java/javax/crypto/CipherOutputStream.java
index 6b8d273..370f7af 100644
--- a/ojluni/src/main/java/javax/crypto/CipherOutputStream.java
+++ b/ojluni/src/main/java/javax/crypto/CipherOutputStream.java
@@ -210,6 +210,8 @@
             obuffer = cipher.doFinal();
         } catch (IllegalBlockSizeException | BadPaddingException e) {
             obuffer = null;
+            // Android-added: Throw an exception when the underlying cipher does.  http://b/36636576
+            throw new IOException(e);
         }
         try {
             flush();
diff --git a/ojluni/src/main/java/javax/crypto/JceSecurity.java b/ojluni/src/main/java/javax/crypto/JceSecurity.java
index 72a6c31..073d827 100644
--- a/ojluni/src/main/java/javax/crypto/JceSecurity.java
+++ b/ojluni/src/main/java/javax/crypto/JceSecurity.java
@@ -73,7 +73,8 @@
     private JceSecurity() {
     }
 
-    /* BEGIN Android-changed
+    // BEGIN Android-changed
+    /*
     static {
         try {
             AccessController.doPrivileged(
@@ -91,7 +92,8 @@
                     "Can not initialize cryptographic mechanism", e);
         }
     }
-    END Android-changed */
+    */
+    // END Android-changed
 
     static Instance getInstance(String type, Class<?> clazz, String algorithm,
             String provider) throws NoSuchAlgorithmException,
@@ -199,9 +201,8 @@
 
     // return whether this provider is properly signed and can be used by JCE
     static boolean canUseProvider(Provider p) {
-        /* BEGIN Android-changed
-        return getVerificationResult(p) == null;
-        */
+        // BEGIN Android-changed
+        // return getVerificationResult(p) == null;
         return true;
         // END Android-changed
     }
diff --git a/ojluni/src/main/java/javax/crypto/KeyAgreement.java b/ojluni/src/main/java/javax/crypto/KeyAgreement.java
index dab71f5..8a0b1c1 100644
--- a/ojluni/src/main/java/javax/crypto/KeyAgreement.java
+++ b/ojluni/src/main/java/javax/crypto/KeyAgreement.java
@@ -59,22 +59,22 @@
  *
  * <p> Android provides the following <code>KeyAgreement</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>DH</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>ECDH</td>
- *             <td>11+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>DH</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ECDH</td>
+ *       <td>11+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * This algorithm is described in the <a href=
diff --git a/ojluni/src/main/java/javax/crypto/KeyGenerator.java b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
index cb3ad69..8a54e5c 100644
--- a/ojluni/src/main/java/javax/crypto/KeyGenerator.java
+++ b/ojluni/src/main/java/javax/crypto/KeyGenerator.java
@@ -88,70 +88,70 @@
  *
  * <p> Android provides the following <code>KeyGenerator</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>AES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>AESWRAP</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>ARC4</td>
- *             <td>14+</td>
- *         </tr>
- *         <tr>
- *             <td>Blowfish</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>DES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESedeWRAP</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>HmacMD5</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA1</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA224</td>
- *             <td>1&ndash;8,22+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA256</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA384</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA512</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>RC4</td>
- *             <td>10&ndash;13</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>AES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>AESWRAP</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>ARC4</td>
+ *       <td>14+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>BLOWFISH</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DESede</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESedeWRAP</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacMD5</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA1</td>
+ *       <td>11+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA224</td>
+ *       <td>1-8,22+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA256</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA384</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA512</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>RC4</td>
+ *       <td>10-13</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/javax/crypto/Mac.java b/ojluni/src/main/java/javax/crypto/Mac.java
index bee46cd..2315db7 100644
--- a/ojluni/src/main/java/javax/crypto/Mac.java
+++ b/ojluni/src/main/java/javax/crypto/Mac.java
@@ -56,76 +56,92 @@
  * e.g., MD5 or SHA-1, in combination with a secret shared key. HMAC is
  * specified in RFC 2104.
  *
- * <p> Android provides the following <code>Mac</code> algorithms
+ * <p> Android provides the following <code>Mac</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>DESedeMAC</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DESedeMAC/CFB8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DESedeMAC64</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DESMAC</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DESMAC/CFB8</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>DESwithISO9797</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>HmacMD5</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA1</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA224</td>
- *             <td>1&ndash;8, 22+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA256</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA384</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA512</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>ISO9797ALG3MAC</td>
- *             <td>1&ndash;8</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithHmacSHA</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithHmacSHA1</td>
- *             <td>1+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr class="deprecated">
+ *       <td>DESMAC</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESMAC/CFB8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESedeMAC</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESedeMAC/CFB8</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESedeMAC64</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>DESwithISO9797</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacMD5</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA224</td>
+ *       <td>1-8,22+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA256</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA384</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA512</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>ISO9797ALG3MAC</td>
+ *       <td>1-8</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512</td>
+ *       <td>26+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the
diff --git a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
index 0c323dd..c1358c2 100644
--- a/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
+++ b/ojluni/src/main/java/javax/crypto/SecretKeyFactory.java
@@ -60,138 +60,194 @@
  *
  * <p> Android provides the following <code>SecretKeyFactory</code> algorithms:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>AES</td>
- *             <td>23+</td>
- *         </tr>
- *         <tr>
- *             <td>DES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>DESede</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA1</td>
- *             <td>23+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA224</td>
- *             <td>23+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA256</td>
- *             <td>23+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA384</td>
- *             <td>23+</td>
- *         </tr>
- *         <tr>
- *             <td>HmacSHA512</td>
- *             <td>23+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithHmacSHA1</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5and128BITAES-CBC-OPENSSL</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5and192BITAES-CBC-OPENSSL</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5and256BITAES-CBC-OPENSSL</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andDES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithMD5andRC2</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andDES</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA1andRC2</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA256and128BITAES-CBC-BC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA256and192BITAES-CBC-BC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHA256and256BITAES-CBC-BC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand128BITAES-CBC-BC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand128BITRC2-CBC</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand128BITRC4</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand192BITAES-CBC-BC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand2-KEYTRIPLEDES-CBC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand256BITAES-CBC-BC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand3-KEYTRIPLEDES-CBC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand40BITRC2-CBC</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAand40BITRC4</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>PBEwithSHAandTWOFISH-CBC</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>PBKDF2withHmacSHA1</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>PBKDF2withHmacSHA1and8BIT</td>
- *             <td>19+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>AES</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>DESede</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA1</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA224</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA256</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA384</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>HmacSHA512</td>
+ *       <td>23+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA1AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA224AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA256AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA384AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512AndAES_128</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithHmacSHA512AndAES_256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithMD5AND128BITAES-CBC-OPENSSL</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithMD5AND192BITAES-CBC-OPENSSL</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithMD5AND256BITAES-CBC-OPENSSL</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithMD5ANDDES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithMD5ANDRC2</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHA1ANDDES</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHA1ANDRC2</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHA256AND128BITAES-CBC-BC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHA256AND192BITAES-CBC-BC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHA256AND256BITAES-CBC-BC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND128BITAES-CBC-BC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND128BITRC2-CBC</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND128BITRC4</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND192BITAES-CBC-BC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND2-KEYTRIPLEDES-CBC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND256BITAES-CBC-BC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND3-KEYTRIPLEDES-CBC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND40BITRC2-CBC</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAAND40BITRC4</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBEwithSHAANDTWOFISH-CBC</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBKDF2withHmacSHA1</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBKDF2withHmacSHA1And8BIT</td>
+ *       <td>19+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBKDF2withHmacSHA224</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBKDF2withHmacSHA256</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBKDF2withHmacSHA384</td>
+ *       <td>26+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>PBKDF2withHmacSHA512</td>
+ *       <td>26+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * These algorithms are described in the <a href=
diff --git a/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java b/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
index b9fe920..f6abafa 100644
--- a/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
+++ b/ojluni/src/main/java/javax/net/ssl/HandshakeCompletedEvent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 import java.security.cert.Certificate;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
-import javax.security.auth.x500.X500Principal;
 
 /**
  * This event indicates that an SSL handshake completed on a given
@@ -186,8 +185,7 @@
             // if the provider does not support it, fallback to peer certs.
             // return the X500Principal of the end-entity cert.
             Certificate[] certs = getPeerCertificates();
-            principal = (X500Principal)
-                ((X509Certificate)certs[0]).getSubjectX500Principal();
+            principal = ((X509Certificate)certs[0]).getSubjectX500Principal();
         }
         return principal;
     }
@@ -216,7 +214,7 @@
             // return the X500Principal of the end-entity cert.
             Certificate[] certs = getLocalCertificates();
             if (certs != null) {
-                principal = (X500Principal)
+                principal =
                         ((X509Certificate)certs[0]).getSubjectX500Principal();
             }
         }
diff --git a/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java b/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
index d2f504f..49b3163 100644
--- a/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
+++ b/ojluni/src/main/java/javax/net/ssl/HostnameVerifier.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
index de1c89d..9660643 100644
--- a/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
+++ b/ojluni/src/main/java/javax/net/ssl/HttpsURLConnection.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
 import java.net.HttpURLConnection;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
-import javax.security.auth.x500.X500Principal;
 
 /**
  * <code>HttpsURLConnection</code> extends <code>HttpURLConnection</code>
@@ -145,8 +144,7 @@
             throws SSLPeerUnverifiedException {
 
         java.security.cert.Certificate[] certs = getServerCertificates();
-        return ((X500Principal)
-                ((X509Certificate)certs[0]).getSubjectX500Principal());
+        return ((X509Certificate)certs[0]).getSubjectX500Principal();
     }
 
     /**
@@ -174,8 +172,7 @@
 
         java.security.cert.Certificate[] certs = getLocalCertificates();
         if (certs != null) {
-            return ((X500Principal)
-                ((X509Certificate)certs[0]).getSubjectX500Principal());
+            return ((X509Certificate)certs[0]).getSubjectX500Principal();
         } else {
             return null;
         }
diff --git a/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java b/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
index 70ea99f..2199c9f 100644
--- a/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/KeyManagerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,22 @@
  * type of key material for use by secure sockets. The key
  * material is based on a KeyStore and/or provider specific sources.
  *
+ * <p> Android provides the following <code>KeyManagerFactory</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>PKIX</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
  * @since 1.4
  * @see KeyManager
  */
@@ -53,21 +69,18 @@
      * Obtains the default KeyManagerFactory algorithm name.
      *
      * <p>The default algorithm can be changed at runtime by setting
-     * the value of the "ssl.KeyManagerFactory.algorithm" security
-     * property (set in the Java security properties file or by calling
-     * {@link java.security.Security#setProperty(java.lang.String,
-     * java.lang.String)})
-     * to the desired algorithm name.
+     * the value of the {@code ssl.KeyManagerFactory.algorithm}
+     * security property to the desired algorithm name.
      *
-     * @see java.security.Security#setProperty(java.lang.String,
-     *          java.lang.String)
-     * @return the default algorithm name as specified in the
-     *          Java security properties, or an implementation-specific
-     *          default if no such property exists.
+     * @see java.security.Security security properties
+     * @return the default algorithm name as specified by the
+     *          {@code ssl.KeyManagerFactory.algorithm} security property, or an
+     *          implementation-specific default if no such property exists.
      */
     public final static String getDefaultAlgorithm() {
         String type;
         type = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override
             public String run() {
                 return Security.getProperty(
                     "ssl.KeyManagerFactory.algorithm");
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLContext.java b/ojluni/src/main/java/javax/net/ssl/SSLContext.java
index fa8a3af..71cfc23 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLContext.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,42 +39,42 @@
  *
  * <p> Android provides the following <code>SSLContext</code> protocols:
  * <table>
- *     <thead>
- *         <tr>
- *             <th>Name</th>
- *             <th>Supported (API Levels)</th>
- *         </tr>
- *     </thead>
- *     <tbody>
- *         <tr>
- *             <td>Default</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSL</td>
- *             <td>10&ndash;TBD</td>
- *         </tr>
- *         <tr class="deprecated">
- *             <td>SSLv3</td>
- *             <td>10&ndash;TBD</td>
- *         </tr>
- *         <tr>
- *             <td>TLS</td>
- *             <td>1+</td>
- *         </tr>
- *         <tr>
- *             <td>TLSv1</td>
- *             <td>10+</td>
- *         </tr>
- *         <tr>
- *             <td>TLSv1.1</td>
- *             <td>16+</td>
- *         </tr>
- *         <tr>
- *             <td>TLSv1.2</td>
- *             <td>16+</td>
- *         </tr>
- *     </tbody>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>Default</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>SSL</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr class="deprecated">
+ *       <td>SSLv3</td>
+ *       <td>10-25</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLS</td>
+ *       <td>1+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLSv1</td>
+ *       <td>10+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLSv1.1</td>
+ *       <td>16+</td>
+ *     </tr>
+ *     <tr>
+ *       <td>TLSv1.2</td>
+ *       <td>16+</td>
+ *     </tr>
+ *   </tbody>
  * </table>
  *
  * This protocol is described in the <a href=
@@ -255,11 +255,11 @@
      *
      * @return the new <code>SSLContext</code> object.
      *
-     * @throws NoSuchAlgorithmException if a KeyManagerFactorySpi
+     * @throws NoSuchAlgorithmException if a SSLContextSpi
      *          implementation for the specified protocol is not available
      *          from the specified Provider object.
      *
-     * @throws IllegalArgumentException if the provider name is null.
+     * @throws IllegalArgumentException if the provider is null.
      * @throws NullPointerException if protocol is null.
      *
      * @see java.security.Provider
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java b/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java
index e4def55..269ed85 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLContextSpi.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package javax.net.ssl;
 
-import java.util.*;
 import java.security.*;
 
 /**
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
index 2bf28b1..26dc64c 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLEngine.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -211,7 +211,7 @@
  * that the source buffer has enough room to hold a record (enlarging if
  * necessary), and then obtain more inbound data.
  *
- * <pre>
+ * <pre>{@code
  *   SSLEngineResult r = engine.unwrap(src, dst);
  *   switch (r.getStatus()) {
  *   BUFFER_OVERFLOW:
@@ -238,7 +238,7 @@
  *       break;
  *   // other cases: CLOSED, OK.
  *   }
- * </pre>
+ * }</pre>
  *
  * <P>
  * Unlike <code>SSLSocket</code>, all methods of SSLEngine are
@@ -329,7 +329,6 @@
  * is saved.  All future delegated tasks will be processed using this
  * context:  that is, all access control decisions will be made using the
  * context captured at engine creation.
- * <P>
  * <HR>
  *
  * <B>Concurrency Notes</B>:
@@ -345,7 +344,7 @@
  *      out-of-order, unexpected or fatal results may occur.
  * <P>
  *      For example:
- * <P>
+ *
  *      <pre>
  *              synchronized (outboundLock) {
  *                  sslEngine.wrap(src, dst);
@@ -1088,7 +1087,7 @@
      * <blockquote><pre>
      * {@link #wrap(ByteBuffer [], int, int, ByteBuffer)
      *     engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);}
-     * </pre</blockquote>
+     * </pre></blockquote>
      *
      * @param   src
      *          a <code>ByteBuffer</code> containing outbound application data
@@ -1124,7 +1123,7 @@
      * <blockquote><pre>
      * {@link #wrap(ByteBuffer [], int, int, ByteBuffer)
      *     engine.wrap(srcs, 0, srcs.length, dst);}
-     * </pre</blockquote>
+     * </pre></blockquote>
      *
      * @param   srcs
      *          an array of <code>ByteBuffers</code> containing the
@@ -1243,7 +1242,7 @@
      * <blockquote><pre>
      * {@link #unwrap(ByteBuffer, ByteBuffer [], int, int)
      *     engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);}
-     * </pre</blockquote>
+     * </pre></blockquote>
      *
      * @param   src
      *          a <code>ByteBuffer</code> containing inbound network data.
@@ -1279,7 +1278,7 @@
      * <blockquote><pre>
      * {@link #unwrap(ByteBuffer, ByteBuffer [], int, int)
      *     engine.unwrap(src, dsts, 0, dsts.length);}
-     * </pre</blockquote>
+     * </pre></blockquote>
      *
      * @param   src
      *          a <code>ByteBuffer</code> containing inbound network data.
@@ -1860,15 +1859,19 @@
      *
      * <p>This means:
      * <ul>
-     * <li>if <code>params.getCipherSuites()</code> is non-null,
-     *   <code>setEnabledCipherSuites()</code> is called with that value
-     * <li>if <code>params.getProtocols()</code> is non-null,
-     *   <code>setEnabledProtocols()</code> is called with that value
-     * <li>if <code>params.getNeedClientAuth()</code> or
-     *   <code>params.getWantClientAuth()</code> return <code>true</code>,
-     *   <code>setNeedClientAuth(true)</code> and
-     *   <code>setWantClientAuth(true)</code> are called, respectively;
-     *   otherwise <code>setWantClientAuth(false)</code> is called.
+     * <li>If {@code params.getCipherSuites()} is non-null,
+     *   {@code setEnabledCipherSuites()} is called with that value.</li>
+     * <li>If {@code params.getProtocols()} is non-null,
+     *   {@code setEnabledProtocols()} is called with that value.</li>
+     * <li>If {@code params.getNeedClientAuth()} or
+     *   {@code params.getWantClientAuth()} return {@code true},
+     *   {@code setNeedClientAuth(true)} and
+     *   {@code setWantClientAuth(true)} are called, respectively;
+     *   otherwise {@code setWantClientAuth(false)} is called.</li>
+     * <li>If {@code params.getServerNames()} is non-null, the engine will
+     *   configure its server names with that value.</li>
+     * <li>If {@code params.getSNIMatchers()} is non-null, the engine will
+     *   configure its SNI matchers with that value.</li>
      * </ul>
      *
      * @param params the parameters
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java b/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java
index dd63ea4..af42f2b 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLEngineResult.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -173,7 +173,7 @@
      *
      * @throws  IllegalArgumentException
      *          if the <code>status</code> or <code>handshakeStatus</code>
-     *          arguments are null, or if <<code>bytesConsumed</code> or
+     *          arguments are null, or if <code>bytesConsumed</code> or
      *          <code>bytesProduced</code> is negative.
      */
     public SSLEngineResult(Status status, HandshakeStatus handshakeStatus,
@@ -230,6 +230,7 @@
     /**
      * Returns a String representation of this object.
      */
+    @Override
     public String toString() {
         return ("Status = " + status +
             " HandshakeStatus = " + handshakeStatus +
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java b/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java
index b6b4087..e613e0f 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLPeerUnverifiedException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
 
     /**
      * Constructs an exception reporting that the SSL peer's
-     * identity has not been verifiied.
+     * identity has not been verified.
      *
      * @param reason describes the problem.
      */
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
index b7a6c3d..50efe8d 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLServerSocket.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -484,15 +484,19 @@
      *
      * <p>This means:
      * <ul>
-     * <li>if <code>params.getCipherSuites()</code> is non-null,
-     *   <code>setEnabledCipherSuites()</code> is called with that value
-     * <li>if <code>params.getProtocols()</code> is non-null,
-     *   <code>setEnabledProtocols()</code> is called with that value
-     * <li>if <code>params.getNeedClientAuth()</code> or
-     *   <code>params.getWantClientAuth()</code> return <code>true</code>,
-     *   <code>setNeedClientAuth(true)</code> and
-     *   <code>setWantClientAuth(true)</code> are called, respectively;
-     *   otherwise <code>setWantClientAuth(false)</code> is called.
+     * <li>If {@code params.getCipherSuites()} is non-null,
+     *   {@code setEnabledCipherSuites()} is called with that value.</li>
+     * <li>If {@code params.getProtocols()} is non-null,
+     *   {@code setEnabledProtocols()} is called with that value.</li>
+     * <li>If {@code params.getNeedClientAuth()} or
+     *   {@code params.getWantClientAuth()} return {@code true},
+     *   {@code setNeedClientAuth(true)} and
+     *   {@code setWantClientAuth(true)} are called, respectively;
+     *   otherwise {@code setWantClientAuth(false)} is called.</li>
+     * <li>If {@code params.getServerNames()} is non-null, the socket will
+     *   configure its server names with that value.</li>
+     * <li>If {@code params.getSNIMatchers()} is non-null, the socket will
+     *   configure its SNI matchers with that value.</li>
      * </ul>
      *
      * @param params the parameters
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java b/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
index 7809c93..a480c60 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLServerSocketFactory.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -192,23 +192,27 @@
             new SocketException(reason.toString()).initCause(reason);
     }
 
+    @Override
     public ServerSocket createServerSocket() throws IOException {
         return throwException();
     }
 
 
+    @Override
     public ServerSocket createServerSocket(int port)
     throws IOException
     {
         return throwException();
     }
 
+    @Override
     public ServerSocket createServerSocket(int port, int backlog)
     throws IOException
     {
         return throwException();
     }
 
+    @Override
     public ServerSocket
     createServerSocket(int port, int backlog, InetAddress ifAddress)
     throws IOException
@@ -216,10 +220,12 @@
         return throwException();
     }
 
+    @Override
     public String [] getDefaultCipherSuites() {
         return new String[0];
     }
 
+    @Override
     public String [] getSupportedCipherSuites() {
         return new String[0];
     }
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSession.java b/ojluni/src/main/java/javax/net/ssl/SSLSession.java
index 93f0667..d98edf0 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSession.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSession.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package javax.net.ssl;
 
-import java.net.InetAddress;
 import java.security.Principal;
 
 /**
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java b/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java
index 61f1ddc..b6f6fb6 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSessionContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -90,7 +90,7 @@
      * @param seconds the new session timeout limit in seconds; zero means
      *          there is no limit.
      *
-     * @exception IllegalArgumentException if the timeout specified is < 0.
+     * @exception IllegalArgumentException if the timeout specified is {@code < 0}.
      * @see #getSessionTimeout
      */
     public void setSessionTimeout(int seconds)
@@ -122,7 +122,7 @@
      *
      * @param size the new session cache size limit; zero means there is no
      * limit.
-     * @exception IllegalArgumentException if the specified size is < 0.
+     * @exception IllegalArgumentException if the specified size is {@code < 0}.
      * @see #getSessionCacheSize
      */
     public void setSessionCacheSize(int size)
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
index 1b6a69c..f2037b4 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocket.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,8 +28,6 @@
 
 import java.io.IOException;
 import java.net.*;
-import java.util.Enumeration;
-import java.util.Vector;
 
 
 /**
@@ -81,7 +79,7 @@
  * </UL>
  *
  * <P>If handshaking fails for any reason, the <code>SSLSocket</code>
- * is closed, and no futher communications can be done.
+ * is closed, and no further communications can be done.
  *
  * <P>There are two groups of cipher suites which you will need to know
  * about when managing cipher suites: <UL>
@@ -1358,15 +1356,19 @@
      *
      * <p>This means:
      * <ul>
-     * <li>if <code>params.getCipherSuites()</code> is non-null,
-     *   <code>setEnabledCipherSuites()</code> is called with that value
-     * <li>if <code>params.getProtocols()</code> is non-null,
-     *   <code>setEnabledProtocols()</code> is called with that value
-     * <li>if <code>params.getNeedClientAuth()</code> or
-     *   <code>params.getWantClientAuth()</code> return <code>true</code>,
-     *   <code>setNeedClientAuth(true)</code> and
-     *   <code>setWantClientAuth(true)</code> are called, respectively;
-     *   otherwise <code>setWantClientAuth(false)</code> is called.
+     * <li>If {@code params.getCipherSuites()} is non-null,
+     *   {@code setEnabledCipherSuites()} is called with that value.</li>
+     * <li>If {@code params.getProtocols()} is non-null,
+     *   {@code setEnabledProtocols()} is called with that value.</li>
+     * <li>If {@code params.getNeedClientAuth()} or
+     *   {@code params.getWantClientAuth()} return {@code true},
+     *   {@code setNeedClientAuth(true)} and
+     *   {@code setWantClientAuth(true)} are called, respectively;
+     *   otherwise {@code setWantClientAuth(false)} is called.</li>
+     * <li>If {@code params.getServerNames()} is non-null, the socket will
+     *   configure its server names with that value.</li>
+     * <li>If {@code params.getSNIMatchers()} is non-null, the socket will
+     *   configure its SNI matchers with that value.</li>
      * </ul>
      *
      * @param params the parameters
diff --git a/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java b/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
index 6b257f5..f1d7057 100644
--- a/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/SSLSocketFactory.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -206,8 +206,7 @@
      * @throws NullPointerException if the parameter s is null
      */
     public abstract Socket createSocket(Socket s, String host,
-                                        int port, boolean autoClose)
-    throws IOException;
+            int port, boolean autoClose) throws IOException;
 }
 
 
@@ -225,18 +224,21 @@
             new SocketException(reason.toString()).initCause(reason);
     }
 
+    @Override
     public Socket createSocket()
     throws IOException
     {
         return throwException();
     }
 
+    @Override
     public Socket createSocket(String host, int port)
     throws IOException
     {
         return throwException();
     }
 
+    @Override
     public Socket createSocket(Socket s, String host,
                                 int port, boolean autoClose)
     throws IOException
@@ -244,12 +246,14 @@
         return throwException();
     }
 
+    @Override
     public Socket createSocket(InetAddress address, int port)
     throws IOException
     {
         return throwException();
     }
 
+    @Override
     public Socket createSocket(String host, int port,
         InetAddress clientAddress, int clientPort)
     throws IOException
@@ -257,6 +261,7 @@
         return throwException();
     }
 
+    @Override
     public Socket createSocket(InetAddress address, int port,
         InetAddress clientAddress, int clientPort)
     throws IOException
@@ -264,10 +269,12 @@
         return throwException();
     }
 
+    @Override
     public String [] getDefaultCipherSuites() {
         return new String[0];
     }
 
+    @Override
     public String [] getSupportedCipherSuites() {
         return new String[0];
     }
diff --git a/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java b/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
index aa5baa7..2a223b0 100644
--- a/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
+++ b/ojluni/src/main/java/javax/net/ssl/TrustManagerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,22 @@
  * type of trust material for use by secure sockets. The trust
  * material is based on a KeyStore and/or provider specific sources.
  *
+ * <p> Android provides the following <code>TrustManagerFactory</code> algorithms:
+ * <table>
+ *   <thead>
+ *     <tr>
+ *       <th>Algorithm</th>
+ *       <th>Supported API Levels</th>
+ *     </tr>
+ *   </thead>
+ *   <tbody>
+ *     <tr>
+ *       <td>PKIX</td>
+ *       <td>1+</td>
+ *     </tr>
+ *   </tbody>
+ * </table>
+ *
  * @since 1.4
  * @see TrustManager
  */
@@ -53,18 +69,18 @@
      * Obtains the default TrustManagerFactory algorithm name.
      *
      * <p>The default TrustManager can be changed at runtime by setting
-     * the value of the "ssl.TrustManagerFactory.algorithm" security
-     * property (set in the Java security properties file or by calling
-     * {@link java.security.Security#setProperty(String, String) })
-     * to the desired algorithm name.
+     * the value of the {@code ssl.TrustManagerFactory.algorithm}
+     * security property to the desired algorithm name.
      *
-     * @return the default algorithm name as specified in the
-     * Java security properties, or an implementation-specific default
-     * if no such property exists.
+     * @see java.security.Security security properties
+     * @return the default algorithm name as specified by the
+     * {@code ssl.TrustManagerFactory.algorithm} security property, or an
+     * implementation-specific default if no such property exists.
      */
     public final static String getDefaultAlgorithm() {
         String type;
         type = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override
             public String run() {
                 return Security.getProperty(
                     "ssl.TrustManagerFactory.algorithm");
diff --git a/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java b/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java
index 3fcf222..69ab91a 100644
--- a/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java
+++ b/ojluni/src/main/java/javax/net/ssl/X509KeyManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,6 @@
 
 package javax.net.ssl;
 
-import java.security.KeyManagementException;
 import java.security.PrivateKey;
 import java.security.Principal;
 import java.security.cert.X509Certificate;
@@ -41,7 +40,7 @@
  * <UL>
  * <LI> determine the set of aliases that are available for negotiations
  *      based on the criteria presented,
- * <LI> select the <ITALIC> best alias </ITALIC> based on
+ * <LI> select the <i> best alias</i> based on
  *      the criteria presented, and
  * <LI> obtain the corresponding key material for given aliases.
  * </UL>
diff --git a/ojluni/src/main/java/javax/security/auth/AuthPermission.java b/ojluni/src/main/java/javax/security/auth/AuthPermission.java
index 82a7eb3..651e9a3 100644
--- a/ojluni/src/main/java/javax/security/auth/AuthPermission.java
+++ b/ojluni/src/main/java/javax/security/auth/AuthPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java b/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
index a49032d..ca52a1b2 100644
--- a/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
+++ b/ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java b/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
index 6352927..8e07d4b 100644
--- a/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
+++ b/ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
diff --git a/ojluni/src/main/java/sun/net/util/IPAddressUtil.java b/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
index e43e386..7ca0f12 100644
--- a/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
+++ b/ojluni/src/main/java/sun/net/util/IPAddressUtil.java
@@ -48,7 +48,8 @@
         long val;
         try {
             switch(s.length) {
-            /* BEGIN Android-changed
+            // BEGIN Android-removed
+            /*
             case 1:
                 // When only one part is given, the value is stored directly in
                 // the network address without any byte rearrangement.
@@ -97,7 +98,9 @@
                     return null;
                 res[2] = (byte) ((val >> 8) & 0xff);
                 res[3] = (byte) (val & 0xff);
-                break; */
+                break;
+            */
+            // END Android-removed
             case 4:
                 /*
                  * When four parts are specified, each is interpreted as a
diff --git a/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java
index 3158215..762df01 100644
--- a/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/DatagramSocketAdaptor.java
@@ -361,7 +361,9 @@
         return dc;
     }
 
-    /** @hide */
+    /*
+     * Android-added: for testing and internal use.
+     */
     @Override
     public final FileDescriptor getFileDescriptor$() {
         return dc.fd;
diff --git a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
index 2b5615d..de78c68 100644
--- a/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
+++ b/ojluni/src/main/java/sun/nio/ch/FileChannelImpl.java
@@ -929,12 +929,14 @@
                 return null;
 
             if (filesize < position + size) { // Extend file size
-                /* BEGIN Android-changed
+                // BEGIN Android-changed
+                /*
                 if (!writable) {
                     throw new IOException("Channel not open for writing " +
                         "- cannot extend file to required size");
                 }
-                END Android-changed */
+                */
+                // END Android-changed
                 int rv = 0;
                 do {
                     // BEGIN Android-changed
diff --git a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
index 10f6b25..aa6d834 100644
--- a/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
+++ b/ojluni/src/main/java/sun/nio/ch/SocketAdaptor.java
@@ -453,6 +453,9 @@
         return !sc.isOutputOpen();
     }
 
+    /*
+     * Android-added: for testing and internal use.
+     */
     @Override
     public FileDescriptor getFileDescriptor$() {
         return sc.getFD();
diff --git a/ojluni/src/main/java/sun/reflect/Reflection.java b/ojluni/src/main/java/sun/reflect/Reflection.java
index f866d3e..a3fa56d 100644
--- a/ojluni/src/main/java/sun/reflect/Reflection.java
+++ b/ojluni/src/main/java/sun/reflect/Reflection.java
@@ -75,10 +75,9 @@
             return true;
         }
 
-        /* BEGIN Android-changed
-        if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {*/
+        // Android-changed
+        // if (!Modifier.isPublic(getClassAccessFlags(memberClass))) {
         if (!Modifier.isPublic(memberClass.getAccessFlags())) {
-        // END Android-changed
             isSameClassPackage = isSameClassPackage(currentClass, memberClass);
             gotIsSameClassPackage = true;
             if (!isSameClassPackage) {
diff --git a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
index 20d7495..b78fdf9 100644
--- a/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
+++ b/ojluni/src/main/java/sun/security/pkcs/SignerInfo.java
@@ -64,9 +64,8 @@
     byte[] encryptedDigest;
     Timestamp timestamp;
     private boolean hasTimestamp = true;
-    /* BEGIN Android-removed
-    private static final Debug debug = Debug.getInstance("jar");
-     * END Android-removed */
+    // Android-removed
+    // private static final Debug debug = Debug.getInstance("jar");
 
     PKCS9Attributes authenticatedAttributes;
     PKCS9Attributes unauthenticatedAttributes;
@@ -562,14 +561,16 @@
                 " is inapplicable");
         }
 
-        /* BEGIN Android-removed
+        // BEGIN Android-removed
+        /*
         if (debug != null) {
             debug.println();
             debug.println("Detected signature timestamp (#" +
                 token.getSerialNumber() + ") generated on " + token.getDate());
             debug.println();
         }
-         * END Android-removed */
+        */
+        // END Android-removed
     }
 
     public String toString() {
diff --git a/ojluni/src/main/java/sun/security/provider/X509Factory.java b/ojluni/src/main/java/sun/security/provider/X509Factory.java
index f894f89..4fa6ec2 100644
--- a/ojluni/src/main/java/sun/security/provider/X509Factory.java
+++ b/ojluni/src/main/java/sun/security/provider/X509Factory.java
@@ -25,24 +25,10 @@
 
 package sun.security.provider;
 
-/* BEGIN Android-removed
-import java.io.*;
-import java.util.*;
- * END Android-removed */
 import java.security.cert.*;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
-/* BEGIN Android-removed
-import sun.security.pkcs.PKCS7;
-import sun.security.provider.certpath.X509CertPath;
-import sun.security.provider.certpath.X509CertificatePair;
-import sun.security.util.DerValue;
- * END Android-removed */
 import sun.security.util.Cache;
-/* BEGIN Android-removed
-import java.util.Base64;
-import sun.security.pkcs.ParsingException;
- * END Android-removed */
 
 /**
  * This class defines a certificate factory for X.509 v3 certificates &
@@ -63,15 +49,14 @@
  * @see sun.security.x509.X509CRLImpl
  */
 
-// BEGIN Android-changed
-// Was: public class X509Factory extends CertificateFactorySpi {
+// Android-changed
+// public class X509Factory extends CertificateFactorySpi {
 public class X509Factory {
-// END Android-changed
 
-    /* BEGIN Android-removed
-    public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
-    public static final String END_CERT = "-----END CERTIFICATE-----";
-     * END Android-removed */
+    // BEGIN Android-removed
+    // public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
+    // public static final String END_CERT = "-----END CERTIFICATE-----";
+    // END Android-removed
 
     private static final int ENC_MAX_LENGTH = 4096 * 1024; // 4 MB MAX
 
@@ -80,7 +65,8 @@
     private static final Cache<Object, X509CRLImpl> crlCache
         = Cache.newSoftMemoryCache(750);
 
-    /* BEGIN Android-removed
+    // BEGIN Android-removed
+    /*
     /**
      * Generates an X.509 certificate object and initializes it with
      * the data read from the input stream <code>is</code>.
@@ -140,7 +126,8 @@
         }
         return read;
     }
-     * END Android-removed */
+    */
+    // END Android-removed
 
     /**
      * Return an interned X509CertImpl for the given certificate.
@@ -244,7 +231,8 @@
         cache.put(key, value);
     }
 
-    /* BEGIN Android-removed
+    // BEGIN Android-removed
+    /*
     /**
      * Generates a <code>CertPath</code> object and initializes it with
      * the data read from the <code>InputStream</code> inStream. The data
@@ -767,5 +755,6 @@
         }
         return tag;
     }
-     * END Android-removed */
+    */
+    // END Android-removed
 }
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java b/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
index 680795c..0ad5387 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/AdaptableX509CertSelector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,40 +26,42 @@
 package sun.security.provider.certpath;
 
 import java.io.IOException;
-import java.util.Date;
-
+import java.math.BigInteger;
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.security.cert.X509CertSelector;
 import java.security.cert.CertificateException;
+import java.util.Arrays;
+import java.util.Date;
 
-import sun.security.util.DerOutputStream;
+import sun.security.util.Debug;
+import sun.security.util.DerInputStream;
 import sun.security.x509.SerialNumber;
-import sun.security.x509.KeyIdentifier;
 import sun.security.x509.AuthorityKeyIdentifierExtension;
 
 /**
  * An adaptable X509 certificate selector for forward certification path
- * building.
+ * building. This selector overrides the default X509CertSelector matching
+ * rules for the subjectKeyIdentifier and serialNumber criteria, and adds
+ * additional rules for certificate validity.
  *
  * @since 1.7
  */
 class AdaptableX509CertSelector extends X509CertSelector {
+
+    private static final Debug debug = Debug.getInstance("certpath");
+
     // The start date of a validity period.
     private Date startDate;
 
     // The end date of a validity period.
     private Date endDate;
 
-    // Is subject key identifier sensitive?
-    private boolean isSKIDSensitive = false;
+    // The subject key identifier
+    private byte[] ski;
 
-    // Is serial number sensitive?
-    private boolean isSNSensitive = false;
-
-    AdaptableX509CertSelector() {
-        super();
-    }
+    // The serial number
+    private BigInteger serial;
 
     /**
      * Sets the criterion of the X509Certificate validity period.
@@ -86,51 +88,64 @@
     }
 
     /**
-     * Parse the authority key identifier extension.
-     *
-     * If the keyIdentifier field of the extension is non-null, set the
-     * subjectKeyIdentifier criterion. If the authorityCertSerialNumber
-     * field is non-null, set the serialNumber criterion.
-     *
-     * Note that we will not set the subject criterion according to the
-     * authorityCertIssuer field of the extension. The caller MUST set
-     * the subject criterion before call match().
-     *
-     * @param akidext the authorityKeyIdentifier extension
+     * This selector overrides the subjectKeyIdentifier matching rules of
+     * X509CertSelector, so it throws IllegalArgumentException if this method
+     * is ever called.
      */
-    void parseAuthorityKeyIdentifierExtension(
-            AuthorityKeyIdentifierExtension akidext) throws IOException {
-        if (akidext != null) {
-            KeyIdentifier akid = (KeyIdentifier)akidext.get(
-                    AuthorityKeyIdentifierExtension.KEY_ID);
-            if (akid != null) {
-                // Do not override the previous setting for initial selection.
-                if (isSKIDSensitive || getSubjectKeyIdentifier() == null) {
-                    DerOutputStream derout = new DerOutputStream();
-                    derout.putOctetString(akid.getIdentifier());
-                    super.setSubjectKeyIdentifier(derout.toByteArray());
+    @Override
+    public void setSubjectKeyIdentifier(byte[] subjectKeyID) {
+        throw new IllegalArgumentException();
+    }
 
-                    isSKIDSensitive = true;
-                }
-            }
+    /**
+     * This selector overrides the serialNumber matching rules of
+     * X509CertSelector, so it throws IllegalArgumentException if this method
+     * is ever called.
+     */
+    @Override
+    public void setSerialNumber(BigInteger serial) {
+        throw new IllegalArgumentException();
+    }
 
-            SerialNumber asn = (SerialNumber)akidext.get(
-                    AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
+    /**
+     * Sets the subjectKeyIdentifier and serialNumber criteria from the
+     * authority key identifier extension.
+     *
+     * The subjectKeyIdentifier criterion is set to the keyIdentifier field
+     * of the extension, or null if it is empty. The serialNumber criterion
+     * is set to the authorityCertSerialNumber field, or null if it is empty.
+     *
+     * Note that we do not set the subject criterion to the
+     * authorityCertIssuer field of the extension. The caller MUST set
+     * the subject criterion before calling match().
+     *
+     * @param ext the authorityKeyIdentifier extension
+     * @throws IOException if there is an error parsing the extension
+     */
+    void setSkiAndSerialNumber(AuthorityKeyIdentifierExtension ext)
+        throws IOException {
+
+        ski = null;
+        serial = null;
+
+        if (ext != null) {
+            ski = ext.getEncodedKeyIdentifier();
+            SerialNumber asn = (SerialNumber)ext.get(
+                AuthorityKeyIdentifierExtension.SERIAL_NUMBER);
             if (asn != null) {
-                // Do not override the previous setting for initial selection.
-                if (isSNSensitive || getSerialNumber() == null) {
-                    super.setSerialNumber(asn.getNumber());
-                    isSNSensitive = true;
-                }
+                serial = asn.getNumber();
             }
-
-            // the subject criterion should be set by the caller.
+            // the subject criterion should be set by the caller
         }
     }
 
     /**
      * Decides whether a <code>Certificate</code> should be selected.
      *
+     * This method overrides the matching rules for the subjectKeyIdentifier
+     * and serialNumber criteria and adds additional rules for certificate
+     * validity.
+     *
      * For the purpose of compatibility, when a certificate is of
      * version 1 and version 2, or the certificate does not include
      * a subject key identifier extension, the selection criterion
@@ -138,12 +153,28 @@
      */
     @Override
     public boolean match(Certificate cert) {
-        if (!(cert instanceof X509Certificate)) {
+        X509Certificate xcert = (X509Certificate)cert;
+
+        // match subject key identifier
+        if (!matchSubjectKeyID(xcert)) {
             return false;
         }
 
-        X509Certificate xcert = (X509Certificate)cert;
+        // In practice, a CA may replace its root certificate and require that
+        // the existing certificate is still valid, even if the AKID extension
+        // does not match the replacement root certificate fields.
+        //
+        // Conservatively, we only support the replacement for version 1 and
+        // version 2 certificate. As for version 3, the certificate extension
+        // may contain sensitive information (for example, policies), the
+        // AKID need to be respected to seek the exact certificate in case
+        // of key or certificate abuse.
         int version = xcert.getVersion();
+        if (serial != null && version > 2) {
+            if (!serial.equals(xcert.getSerialNumber())) {
+                return false;
+            }
+        }
 
         // Check the validity period for version 1 and 2 certificate.
         if (version < 3) {
@@ -154,7 +185,6 @@
                     return false;
                 }
             }
-
             if (endDate != null) {
                 try {
                     xcert.checkValidity(endDate);
@@ -164,26 +194,53 @@
             }
         }
 
-        // If no SubjectKeyIdentifier extension, don't bother to check it.
-        if (isSKIDSensitive &&
-            (version < 3 || xcert.getExtensionValue("2.5.29.14") == null)) {
-            setSubjectKeyIdentifier(null);
+
+        if (!super.match(cert)) {
+            return false;
         }
 
-        // In practice, a CA may replace its root certificate and require that
-        // the existing certificate is still valid, even if the AKID extension
-        // does not match the replacement root certificate fields.
-        //
-        // Conservatively, we only support the replacement for version 1 and
-        // version 2 certificate. As for version 2, the certificate extension
-        // may contain sensitive information (for example, policies), the
-        // AKID need to be respected to seek the exact certificate in case
-        // of key or certificate abuse.
-        if (isSNSensitive && version < 3) {
-            setSerialNumber(null);
-        }
+        return true;
+    }
 
-        return super.match(cert);
+    /*
+     * Match on subject key identifier extension value. These matching rules
+     * are identical to X509CertSelector except that if the certificate does
+     * not have a subject key identifier extension, it returns true.
+     */
+    private boolean matchSubjectKeyID(X509Certificate xcert) {
+        if (ski == null) {
+            return true;
+        }
+        try {
+            byte[] extVal = xcert.getExtensionValue("2.5.29.14");
+            if (extVal == null) {
+                if (debug != null) {
+                    debug.println("AdaptableX509CertSelector.match: "
+                        + "no subject key ID extension. Subject: "
+                        + xcert.getSubjectX500Principal());
+                }
+                return true;
+            }
+            DerInputStream in = new DerInputStream(extVal);
+            byte[] certSubjectKeyID = in.getOctetString();
+            if (certSubjectKeyID == null ||
+                    !Arrays.equals(ski, certSubjectKeyID)) {
+                if (debug != null) {
+                    debug.println("AdaptableX509CertSelector.match: "
+                        + "subject key IDs don't match. "
+                        + "Expected: " + Arrays.toString(ski) + " "
+                        + "Cert's: " + Arrays.toString(certSubjectKeyID));
+                }
+                return false;
+            }
+        } catch (IOException ex) {
+            if (debug != null) {
+                debug.println("AdaptableX509CertSelector.match: "
+                    + "exception in subject key ID check");
+            }
+            return false;
+        }
+        return true;
     }
 
     @Override
@@ -198,6 +255,9 @@
             copy.endDate = (Date)endDate.clone();
         }
 
+        if (ski != null) {
+            copy.ski = ski.clone();
+        }
         return copy;
     }
 }
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java
index ab75ff0..e92590a 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/AlgorithmChecker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,12 +31,10 @@
 import java.util.Collections;
 import java.util.Set;
 import java.util.EnumSet;
-import java.util.HashSet;
 import java.math.BigInteger;
 import java.security.PublicKey;
 import java.security.KeyFactory;
 import java.security.AlgorithmParameters;
-import java.security.NoSuchAlgorithmException;
 import java.security.GeneralSecurityException;
 import java.security.cert.Certificate;
 import java.security.cert.X509CRL;
@@ -48,10 +46,13 @@
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.CertPathValidatorException.BasicReason;
 import java.security.cert.PKIXReason;
-import java.io.IOException;
-import java.security.interfaces.*;
-import java.security.spec.*;
+import java.security.interfaces.DSAParams;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPublicKeySpec;
 
+import sun.security.util.AnchorCertificates;
+import sun.security.util.CertConstraintParameters;
+import sun.security.util.Debug;
 import sun.security.util.DisabledAlgorithmConstraints;
 import sun.security.x509.X509CertImpl;
 import sun.security.x509.X509CRLImpl;
@@ -69,18 +70,34 @@
  * @see PKIXParameters
  */
 final public class AlgorithmChecker extends PKIXCertPathChecker {
+    private static final Debug debug = Debug.getInstance("certpath");
 
     private final AlgorithmConstraints constraints;
     private final PublicKey trustedPubKey;
     private PublicKey prevPubKey;
 
     private final static Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
-                                    EnumSet.of(CryptoPrimitive.SIGNATURE);
+        Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
+    private final static Set<CryptoPrimitive> KU_PRIMITIVE_SET =
+        Collections.unmodifiableSet(EnumSet.of(
+            CryptoPrimitive.SIGNATURE,
+            CryptoPrimitive.KEY_ENCAPSULATION,
+            CryptoPrimitive.PUBLIC_KEY_ENCRYPTION,
+            CryptoPrimitive.KEY_AGREEMENT));
 
     private final static DisabledAlgorithmConstraints
         certPathDefaultConstraints = new DisabledAlgorithmConstraints(
             DisabledAlgorithmConstraints.PROPERTY_CERTPATH_DISABLED_ALGS);
 
+    // If there is no "cacerts" keyword, then disable anchor checking
+    private static final boolean publicCALimits =
+            certPathDefaultConstraints.checkProperty("jdkCA");
+
+    // If anchor checking enabled, this will be true if the trust anchor
+    // has a match in the cacerts file
+    private boolean trustedMatch = false;
+
     /**
      * Create a new <code>AlgorithmChecker</code> with the algorithm
      * constraints specified in security property
@@ -129,6 +146,11 @@
 
         if (anchor.getTrustedCert() != null) {
             this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+            // Check for anchor certificate restrictions
+            trustedMatch = checkFingerprint(anchor.getTrustedCert());
+            if (trustedMatch && debug != null) {
+                debug.println("trustedMatch = true");
+            }
         } else {
             this.trustedPubKey = anchor.getCAPublicKey();
         }
@@ -137,6 +159,19 @@
         this.constraints = constraints;
     }
 
+    // Check this 'cert' for restrictions in the AnchorCertificates
+    // trusted certificates list
+    private static boolean checkFingerprint(X509Certificate cert) {
+        if (!publicCALimits) {
+            return false;
+        }
+
+        if (debug != null) {
+            debug.println("AlgorithmChecker.contains: " + cert.getSigAlgName());
+        }
+        return AnchorCertificates.contains(cert);
+    }
+
     @Override
     public void init(boolean forward) throws CertPathValidatorException {
         //  Note that this class does not support forward mode.
@@ -174,45 +209,19 @@
             return;
         }
 
-        X509CertImpl x509Cert = null;
-        try {
-            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        PublicKey currPubKey = x509Cert.getPublicKey();
-        String currSigAlg = x509Cert.getSigAlgName();
-
-        AlgorithmId algorithmId = null;
-        try {
-            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
-        } catch (CertificateException ce) {
-            throw new CertPathValidatorException(ce);
-        }
-
-        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
-
-        // Check the current signature algorithm
-        if (!constraints.permits(
-                SIGNATURE_PRIMITIVE_SET,
-                currSigAlg, currSigAlgParams)) {
-            throw new CertPathValidatorException(
-                "Algorithm constraints check failed: " + currSigAlg,
-                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-        }
-
         // check the key usage and key size
-        boolean[] keyUsage = x509Cert.getKeyUsage();
+        boolean[] keyUsage = ((X509Certificate) cert).getKeyUsage();
         if (keyUsage != null && keyUsage.length < 9) {
             throw new CertPathValidatorException(
                 "incorrect KeyUsage extension",
                 null, null, -1, PKIXReason.INVALID_KEY_USAGE);
         }
 
+        // Assume all key usage bits are set if key usage is not present
+        Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
+
         if (keyUsage != null) {
-            Set<CryptoPrimitive> primitives =
-                        EnumSet.noneOf(CryptoPrimitive.class);
+            primitives = EnumSet.noneOf(CryptoPrimitive.class);
 
             if (keyUsage[0] || keyUsage[1] || keyUsage[5] || keyUsage[6]) {
                 // keyUsage[0]: KeyUsage.digitalSignature
@@ -237,26 +246,70 @@
             // KeyUsage.encipherOnly and KeyUsage.decipherOnly are
             // undefined in the absence of the keyAgreement bit.
 
-            if (!primitives.isEmpty()) {
-                if (!constraints.permits(primitives, currPubKey)) {
-                    throw new CertPathValidatorException(
-                        "algorithm constraints check failed",
-                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
-                }
+            if (primitives.isEmpty()) {
+                throw new CertPathValidatorException(
+                    "incorrect KeyUsage extension bits",
+                    null, null, -1, PKIXReason.INVALID_KEY_USAGE);
             }
         }
 
+        PublicKey currPubKey = cert.getPublicKey();
+
+        // Check against DisabledAlgorithmConstraints certpath constraints.
+        // permits() will throw exception on failure.
+        certPathDefaultConstraints.permits(primitives,
+                new CertConstraintParameters((X509Certificate)cert,
+                        trustedMatch));
+                // new CertConstraintParameters(x509Cert, trustedMatch));
+        // If there is no previous key, set one and exit
+        if (prevPubKey == null) {
+            prevPubKey = currPubKey;
+            return;
+        }
+
+        X509CertImpl x509Cert;
+        AlgorithmId algorithmId;
+        try {
+            x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+            algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+        } catch (CertificateException ce) {
+            throw new CertPathValidatorException(ce);
+        }
+
+        AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+        String currSigAlg = x509Cert.getSigAlgName();
+
+        // If 'constraints' is not of DisabledAlgorithmConstraints, check all
+        // everything individually
+        if (!(constraints instanceof DisabledAlgorithmConstraints)) {
+            // Check the current signature algorithm
+            if (!constraints.permits(
+                    SIGNATURE_PRIMITIVE_SET,
+                    currSigAlg, currSigAlgParams)) {
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on signature " +
+                                "algorithm: " + currSigAlg, null, null, -1,
+                        BasicReason.ALGORITHM_CONSTRAINED);
+            }
+
+        if (!constraints.permits(primitives, currPubKey)) {
+            throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on keysize: " +
+                                sun.security.util.KeyUtil.getKeySize(currPubKey),
+                null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+        }
+
         // Check with previous cert for signature algorithm and public key
         if (prevPubKey != null) {
-            if (currSigAlg != null) {
                 if (!constraints.permits(
                         SIGNATURE_PRIMITIVE_SET,
                         currSigAlg, prevPubKey, currSigAlgParams)) {
                     throw new CertPathValidatorException(
-                        "Algorithm constraints check failed: " + currSigAlg,
+                    "Algorithm constraints check failed on " +
+                            "signature algorithm: " + currSigAlg,
                         null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
                 }
-            }
 
             // Inherit key parameters from previous key
             if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
@@ -269,7 +322,7 @@
                 DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
                 if (params == null) {
                     throw new CertPathValidatorException(
-                                    "Key parameters missing");
+                        "Key parameters missing from public key.");
                 }
 
                 try {
@@ -317,6 +370,11 @@
             // Don't bother to change the trustedPubKey.
             if (anchor.getTrustedCert() != null) {
                 prevPubKey = anchor.getTrustedCert().getPublicKey();
+                // Check for anchor certificate restrictions
+                trustedMatch = checkFingerprint(anchor.getTrustedCert());
+                if (trustedMatch && debug != null) {
+                    debug.println("trustedMatch = true");
+                }
             } else {
                 prevPubKey = anchor.getCAPublicKey();
             }
@@ -357,10 +415,10 @@
         if (!certPathDefaultConstraints.permits(
                 SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
             throw new CertPathValidatorException(
-                "algorithm check failed: " + sigAlgName + " is disabled",
+                "Algorithm constraints check failed on signature algorithm: " +
+                sigAlgName + " is disabled",
                 null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
         }
     }
 
 }
-
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/Builder.java b/ojluni/src/main/java/sun/security/provider/certpath/Builder.java
index e053b20..84cbe66 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/Builder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/Builder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -435,7 +435,12 @@
             if (selector.match(targetCert) && !X509CertImpl.isSelfSigned
                 (targetCert, buildParams.sigProvider())) {
                 if (debug != null) {
-                    debug.println("Builder.addMatchingCerts: adding target cert");
+                    debug.println("Builder.addMatchingCerts: " +
+                        "adding target cert" +
+                        "\n  SN: " + Debug.toHexString(
+                                            targetCert.getSerialNumber()) +
+                        "\n  Subject: " + targetCert.getSubjectX500Principal() +
+                        "\n  Issuer: " + targetCert.getIssuerX500Principal());
                 }
                 return resultCerts.add(targetCert);
             }
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java
index a08c990..28fb322 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ConstraintsChecker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -145,8 +145,8 @@
         if (prevNC != null && ((i == certPathLength) ||
                 !X509CertImpl.isSelfIssued(currCert))) {
             if (debug != null) {
-                debug.println("prevNC = " + prevNC);
-                debug.println("currDN = " + currCert.getSubjectX500Principal());
+                debug.println("prevNC = " + prevNC +
+                    ", currDN = " + currCert.getSubjectX500Principal());
             }
 
             try {
@@ -184,8 +184,8 @@
             currCertImpl.getNameConstraintsExtension();
 
         if (debug != null) {
-            debug.println("prevNC = " + prevNC);
-            debug.println("newNC = " + String.valueOf(newConstraints));
+            debug.println("prevNC = " + prevNC +
+                        ", newNC = " + String.valueOf(newConstraints));
         }
 
         // if there are no previous name constraints, we just return the
@@ -225,8 +225,8 @@
         String msg = "basic constraints";
         if (debug != null) {
             debug.println("---checking " + msg + "...");
-            debug.println("i = " + i);
-            debug.println("maxPathLength = " + maxPathLength);
+            debug.println("i = " + i +
+                        ", maxPathLength = " + maxPathLength);
         }
 
         /* check if intermediate cert */
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java b/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
index 34bfbba..5d9e657 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/DistributionPointFetcher.java
@@ -33,7 +33,6 @@
 import java.util.*;
 
 import sun.security.util.Debug;
-import sun.security.util.DerOutputStream;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.*;
 
@@ -320,6 +319,14 @@
         Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
         Date validity) throws CRLException, IOException {
 
+        if (debug != null) {
+            debug.println("DistributionPointFetcher.verifyCRL: " +
+                "checking revocation status for" +
+                "\n  SN: " + Debug.toHexString(certImpl.getSerialNumber()) +
+                "\n  Subject: " + certImpl.getSubjectX500Principal() +
+                "\n  Issuer: " + certImpl.getIssuerX500Principal());
+        }
+
         boolean indirectCRL = false;
         X509CRLImpl crlImpl = X509CRLImpl.toImpl(crl);
         IssuingDistributionPointExtension idpExt =
@@ -600,12 +607,9 @@
             AuthorityKeyIdentifierExtension akidext =
                                             crlImpl.getAuthKeyIdExtension();
             if (akidext != null) {
-                KeyIdentifier akid = (KeyIdentifier)akidext.get(
-                        AuthorityKeyIdentifierExtension.KEY_ID);
-                if (akid != null) {
-                    DerOutputStream derout = new DerOutputStream();
-                    derout.putOctetString(akid.getIdentifier());
-                    certSel.setSubjectKeyIdentifier(derout.toByteArray());
+                byte[] kid = akidext.getEncodedKeyIdentifier();
+                if (kid != null) {
+                    certSel.setSubjectKeyIdentifier(kid);
                 }
 
                 SerialNumber asn = (SerialNumber)akidext.get(
@@ -753,9 +757,7 @@
          * issued. [section 5.2.1, RFC 2459]
          */
         AuthorityKeyIdentifierExtension crlAKID = crl.getAuthKeyIdExtension();
-        if (crlAKID != null) {
-            issuerSelector.parseAuthorityKeyIdentifierExtension(crlAKID);
-        }
+        issuerSelector.setSkiAndSerialNumber(crlAKID);
 
         matched = issuerSelector.match(cert);
 
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
index 8f2a929..57e819c 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ForwardBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -46,9 +46,10 @@
 import sun.security.util.Debug;
 import sun.security.x509.AccessDescription;
 import sun.security.x509.AuthorityInfoAccessExtension;
+import sun.security.x509.AuthorityKeyIdentifierExtension;
 import static sun.security.x509.PKIXExtensions.*;
 import sun.security.x509.X500Name;
-import sun.security.x509.AuthorityKeyIdentifierExtension;
+import sun.security.x509.X509CertImpl;
 
 /**
  * This class represents a forward builder, which is able to retrieve
@@ -69,7 +70,6 @@
     private AdaptableX509CertSelector caSelector;
     private X509CertSelector caTargetSelector;
     TrustAnchor trustAnchor;
-    private Comparator<X509Certificate> comparator;
     private boolean searchAllCertStores = true;
 
     /**
@@ -93,7 +93,6 @@
                 trustedSubjectDNs.add(anchor.getCA());
             }
         }
-        comparator = new PKIXCertComparator(trustedSubjectDNs);
         this.searchAllCertStores = searchAllCertStores;
     }
 
@@ -122,6 +121,8 @@
          * As each cert is added, it is sorted based on the PKIXCertComparator
          * algorithm.
          */
+        Comparator<X509Certificate> comparator =
+            new PKIXCertComparator(trustedSubjectDNs, currState.cert);
         Set<X509Certificate> certs = new TreeSet<>(comparator);
 
         /*
@@ -209,7 +210,8 @@
              * getMatchingEECerts
              */
             if (debug != null) {
-                debug.println("ForwardBuilder.getMatchingCACerts(): ca is target");
+                debug.println("ForwardBuilder.getMatchingCACerts(): " +
+                              "the target is a CA");
             }
 
             if (caTargetSelector == null) {
@@ -264,14 +266,6 @@
                 (caSelector, currentState.subjectNamesTraversed);
 
             /*
-             * Facilitate certification path construction with authority
-             * key identifier and subject key identifier.
-             */
-            AuthorityKeyIdentifierExtension akidext =
-                    currentState.cert.getAuthorityKeyIdentifierExtension();
-            caSelector.parseAuthorityKeyIdentifierExtension(akidext);
-
-            /*
              * check the validity period
              */
             caSelector.setValidityPeriod(currentState.cert.getNotBefore(),
@@ -291,8 +285,14 @@
         for (X509Certificate trustedCert : trustedCerts) {
             if (sel.match(trustedCert)) {
                 if (debug != null) {
-                    debug.println("ForwardBuilder.getMatchingCACerts: "
-                        + "found matching trust anchor");
+                    debug.println("ForwardBuilder.getMatchingCACerts: " +
+                        "found matching trust anchor." +
+                        "\n  SN: " +
+                            Debug.toHexString(trustedCert.getSerialNumber()) +
+                        "\n  Subject: " +
+                            trustedCert.getSubjectX500Principal() +
+                        "\n  Issuer: " +
+                            trustedCert.getIssuerX500Principal());
                 }
                 if (caCerts.add(trustedCert) && !searchAllCertStores) {
                     return;
@@ -397,41 +397,68 @@
      *
      * Preference order for current cert:
      *
-     * 1) Issuer matches a trusted subject
+     * 1) The key identifier of an AKID extension (if present) in the
+     *    previous certificate matches the key identifier in the SKID extension
+     *
+     * 2) Issuer matches a trusted subject
      *    Issuer: ou=D,ou=C,o=B,c=A
      *
-     * 2) Issuer is a descendant of a trusted subject (in order of
+     * 3) Issuer is a descendant of a trusted subject (in order of
      *    number of links to the trusted subject)
      *    a) Issuer: ou=E,ou=D,ou=C,o=B,c=A        [links=1]
      *    b) Issuer: ou=F,ou=E,ou=D,ou=C,ou=B,c=A  [links=2]
      *
-     * 3) Issuer is an ancestor of a trusted subject (in order of number of
+     * 4) Issuer is an ancestor of a trusted subject (in order of number of
      *    links to the trusted subject)
      *    a) Issuer: ou=C,o=B,c=A [links=1]
      *    b) Issuer: o=B,c=A      [links=2]
      *
-     * 4) Issuer is in the same namespace as a trusted subject (in order of
+     * 5) Issuer is in the same namespace as a trusted subject (in order of
      *    number of links to the trusted subject)
      *    a) Issuer: ou=G,ou=C,o=B,c=A  [links=2]
      *    b) Issuer: ou=H,o=B,c=A       [links=3]
      *
-     * 5) Issuer is an ancestor of certificate subject (in order of number
+     * 6) Issuer is an ancestor of certificate subject (in order of number
      *    of links to the certificate subject)
      *    a) Issuer:  ou=K,o=J,c=A
      *       Subject: ou=L,ou=K,o=J,c=A
      *    b) Issuer:  o=J,c=A
      *       Subject: ou=L,ou=K,0=J,c=A
      *
-     * 6) Any other certificates
+     * 7) Any other certificates
      */
     static class PKIXCertComparator implements Comparator<X509Certificate> {
 
-        final static String METHOD_NME = "PKIXCertComparator.compare()";
+        static final String METHOD_NME = "PKIXCertComparator.compare()";
 
         private final Set<X500Principal> trustedSubjectDNs;
+        private final X509CertSelector certSkidSelector;
 
-        PKIXCertComparator(Set<X500Principal> trustedSubjectDNs) {
+        PKIXCertComparator(Set<X500Principal> trustedSubjectDNs,
+                           X509CertImpl previousCert) throws IOException {
             this.trustedSubjectDNs = trustedSubjectDNs;
+            this.certSkidSelector = getSelector(previousCert);
+        }
+
+        /**
+         * Returns an X509CertSelector for matching on the authority key
+         * identifier, or null if not applicable.
+         */
+        private X509CertSelector getSelector(X509CertImpl previousCert)
+            throws IOException {
+            if (previousCert != null) {
+                AuthorityKeyIdentifierExtension akidExt =
+                    previousCert.getAuthorityKeyIdentifierExtension();
+                if (akidExt != null) {
+                    byte[] skid = akidExt.getEncodedKeyIdentifier();
+                    if (skid != null) {
+                        X509CertSelector selector = new X509CertSelector();
+                        selector.setSubjectKeyIdentifier(skid);
+                        return selector;
+                    }
+                }
+            }
+            return null;
         }
 
         /**
@@ -455,6 +482,16 @@
             // if certs are the same, return 0
             if (oCert1.equals(oCert2)) return 0;
 
+            // If akid/skid match then it is preferable
+            if (certSkidSelector != null) {
+                if (certSkidSelector.match(oCert1)) {
+                    return -1;
+                }
+                if (certSkidSelector.match(oCert2)) {
+                    return 1;
+                }
+            }
+
             X500Principal cIssuer1 = oCert1.getIssuerX500Principal();
             X500Principal cIssuer2 = oCert2.getIssuerX500Principal();
             X500Name cIssuer1Name = X500Name.asX500Name(cIssuer1);
@@ -666,12 +703,11 @@
 
         ForwardState currState = (ForwardState)currentState;
 
-        /**
-         * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
-         * Android.
-        // Don't bother to verify untrusted certificate more.
-        currState.untrustedChecker.check(cert, Collections.<String>emptySet());
-         * END Android-removed */
+        // BEGIN Android-removed: Certificate checking
+        // Android doesn't use this mechanism for checking untrusted certificates.
+        // // Don't bother to verify untrusted certificate more.
+        // currState.untrustedChecker.check(cert, Collections.<String>emptySet());
+        // END Android-removed: Certificate checking
 
         /*
          * check for looping - abort a loop if we encounter the same
@@ -776,6 +812,7 @@
          * encountered.
          */
         if (!currState.keyParamsNeeded()) {
+            // Android-changed: sigProvider is not required
             if (buildParams.sigProvider() != null) {
                 (currState.cert).verify(cert.getPublicKey(),
                                         buildParams.sigProvider());
@@ -836,6 +873,7 @@
              * Check signature
              */
             try {
+                // Android-changed: sigProvider is not required
                 if (buildParams.sigProvider() != null) {
                     cert.verify(publicKey, buildParams.sigProvider());
                 } else {
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java b/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java
index 09b9699..bdc437c 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ForwardState.java
@@ -75,11 +75,8 @@
 
 
     /* the untrusted certificates checker */
-    /**
-     * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
-     * Android.
-    UntrustedChecker untrustedChecker;
-     * END ANDROID_REMOVED */
+    // Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+    // UntrustedChecker untrustedChecker;
 
     /* The list of user-defined checkers that support forward checking */
     ArrayList<PKIXCertPathChecker> forwardCheckers;
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java b/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
index 550785e..492e851 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/PKIXCertPathValidator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,7 @@
              */
             try {
                 X509CertImpl firstCertImpl = X509CertImpl.toImpl(firstCert);
-                selector.parseAuthorityKeyIdentifierExtension(
+                selector.setSkiAndSerialNumber(
                             firstCertImpl.getAuthorityKeyIdentifierExtension());
             } catch (CertificateException | IOException e) {
                 // ignore
@@ -167,11 +167,8 @@
         // create PKIXCertPathCheckers
         List<PKIXCertPathChecker> certPathCheckers = new ArrayList<>();
         // add standard checkers that we will be using
-        /**
-         * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
-         * Android.
-        certPathCheckers.add(new UntrustedChecker());
-         * END Android-removed */
+        // Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+        // certPathCheckers.add(new UntrustedChecker());
         certPathCheckers.add(new AlgorithmChecker(anchor));
         certPathCheckers.add(new KeyChecker(certPathLen,
                                             params.targetCertConstraints()));
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java b/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
index db5edda..e85ef2d 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/PKIXMasterCertPathValidator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.StringJoiner;
 import java.security.cert.CertPath;
 import java.security.cert.CertPathValidatorException;
 import java.security.cert.PKIXCertPathChecker;
@@ -88,20 +89,25 @@
              * current certificate of this loop to be the previous certificate
              * of the next loop. The state is initialized during first loop.
              */
-            if (debug != null)
-                debug.println("Checking cert" + (i+1) + " ...");
-
             X509Certificate currCert = reversedCertList.get(i);
+
+            if (debug != null) {
+                debug.println("Checking cert" + (i+1) + " - Subject: " +
+                    currCert.getSubjectX500Principal());
+            }
+
             Set<String> unresCritExts = currCert.getCriticalExtensionOIDs();
             if (unresCritExts == null) {
                 unresCritExts = Collections.<String>emptySet();
             }
 
             if (debug != null && !unresCritExts.isEmpty()) {
-                debug.println("Set of critical extensions:");
+                StringJoiner joiner = new StringJoiner(", ", "{", "}");
                 for (String oid : unresCritExts) {
-                    debug.println(oid);
+                  joiner.add(oid);
                 }
+                debug.println("Set of critical extensions: " +
+                        joiner.toString());
             }
 
             for (int j = 0; j < certPathCheckers.size(); j++) {
@@ -125,8 +131,8 @@
 
                 } catch (CertPathValidatorException cpve) {
                     throw new CertPathValidatorException(cpve.getMessage(),
-                        cpve.getCause(), cpOriginal, cpSize - (i + 1),
-                        cpve.getReason());
+                        (cpve.getCause() != null) ? cpve.getCause() : cpve,
+                            cpOriginal, cpSize - (i + 1), cpve.getReason());
                 }
             }
 
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java
index 78e8db6..1815a22 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ReverseBuilder.java
@@ -356,13 +356,11 @@
             return;
         }
 
-        /**
-         * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
-         * Android.
-        // Don't bother to verify untrusted certificate more.
-        currentState.untrustedChecker.check(cert,
-                                    Collections.<String>emptySet());
-         * END Android-removed */
+        // BEGIN Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+        // // Don't bother to verify untrusted certificate more.
+        // currentState.untrustedChecker.check(cert,
+        //                             Collections.<String>emptySet());
+        // END Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
 
         /*
          * check for looping - abort a loop if
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java b/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java
index 7ffd924..a9944af 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/ReverseState.java
@@ -101,11 +101,8 @@
     AlgorithmChecker algorithmChecker;
 
     /* the untrusted certificates checker */
-    /**
-     * BEGIN Android-removed: this mechanism for checking untrusted certificates is not used in
-     * Android.
-    UntrustedChecker untrustedChecker;
-     * END Android-removed */
+    // Android-removed: Android doesn't use this mechanism for checking untrusted certificates.
+    // UntrustedChecker untrustedChecker;
 
     /* the trust anchor used to validate the path */
     TrustAnchor trustAnchor;
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java b/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
index 19b41f6..61d5fd7 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/RevocationChecker.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -343,11 +343,17 @@
                        PublicKey pubKey, boolean crlSignFlag)
         throws CertPathValidatorException
     {
+        if (debug != null) {
+            debug.println("RevocationChecker.check: checking cert" +
+                "\n  SN: " + Debug.toHexString(xcert.getSerialNumber()) +
+                "\n  Subject: " + xcert.getSubjectX500Principal() +
+                "\n  Issuer: " + xcert.getIssuerX500Principal());
+        }
         try {
             if (onlyEE && xcert.getBasicConstraints() != -1) {
                 if (debug != null) {
-                    debug.println("Skipping revocation check, not end " +
-                                  "entity cert");
+                    debug.println("Skipping revocation check; cert is not " +
+                                  "an end entity cert");
                 }
                 return;
             }
@@ -1035,6 +1041,9 @@
                 boolean signFlag = true;
                 List<? extends Certificate> cpList =
                     cpbr.getCertPath().getCertificates();
+                if (cpList.isEmpty()) {
+                    return;
+                }
                 try {
                     for (int i = cpList.size()-1; i >= 0; i-- ) {
                         X509Certificate cert = (X509Certificate)cpList.get(i);
diff --git a/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java b/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java
index d2f8d23..9b21a99 100644
--- a/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java
+++ b/ojluni/src/main/java/sun/security/provider/certpath/SunCertPathBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -136,7 +136,8 @@
         PKIXCertPathBuilderResult result = buildCertPath(false, adjList);
         if (result == null) {
             if (debug != null) {
-                debug.println("SunCertPathBuilder.engineBuild: 2nd pass");
+                debug.println("SunCertPathBuilder.engineBuild: 2nd pass; " +
+                              "try building again searching all certstores");
             }
             // try again
             adjList.clear();
diff --git a/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java b/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java
index 4c3efd9..1b64d9d 100644
--- a/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java
+++ b/ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,7 +29,6 @@
 import java.security.AlgorithmConstraints;
 import java.security.PrivilegedAction;
 import java.security.Security;
-import java.util.Map;
 import java.util.Set;
 
 /**
@@ -45,8 +44,7 @@
     }
 
     // Get algorithm constraints from the specified security property.
-    private static void loadAlgorithmsMap(Map<String, String[]> algorithmsMap,
-            String propertyName) {
+    static String[] getAlgorithms(String propertyName) {
         String property = AccessController.doPrivileged(
                 (PrivilegedAction<String>) () -> Security.getProperty(
                         propertyName));
@@ -69,18 +67,7 @@
         if (algorithmsInProperty == null) {
             algorithmsInProperty = new String[0];
         }
-        algorithmsMap.put(propertyName, algorithmsInProperty);
-    }
-
-    static String[] getAlgorithms(Map<String, String[]> algorithmsMap,
-            String propertyName) {
-        synchronized (algorithmsMap) {
-            if (!algorithmsMap.containsKey(propertyName)) {
-                loadAlgorithmsMap(algorithmsMap, propertyName);
-            }
-
-            return algorithmsMap.get(propertyName);
-        }
+        return algorithmsInProperty;
     }
 
     static boolean checkAlgorithm(String[] algorithms, String algorithm,
diff --git a/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java b/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java
index 394b846..dae529a 100644
--- a/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java
+++ b/ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,19 +38,7 @@
     private static final Pattern pattern =
                     Pattern.compile("with|and", Pattern.CASE_INSENSITIVE);
 
-    /**
-     * Decompose the standard algorithm name into sub-elements.
-     * <p>
-     * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
-     * so that we can check the "SHA1" and "RSA" algorithm constraints
-     * separately.
-     * <p>
-     * Please override the method if need to support more name pattern.
-     */
-    public Set<String> decompose(String algorithm) {
-        if (algorithm == null || algorithm.length() == 0) {
-            return new HashSet<>();
-        }
+    private static Set<String> decomposeImpl(String algorithm) {
 
         // algorithm/mode/padding
         String[] transTockens = transPattern.split(algorithm);
@@ -76,6 +64,24 @@
                 elements.add(token);
             }
         }
+        return elements;
+    }
+
+    /**
+     * Decompose the standard algorithm name into sub-elements.
+     * <p>
+     * For example, we need to decompose "SHA1WithRSA" into "SHA1" and "RSA"
+     * so that we can check the "SHA1" and "RSA" algorithm constraints
+     * separately.
+     * <p>
+     * Please override the method if need to support more name pattern.
+     */
+    public Set<String> decompose(String algorithm) {
+        if (algorithm == null || algorithm.length() == 0) {
+            return new HashSet<>();
+        }
+
+        Set<String> elements = decomposeImpl(algorithm);
 
         // In Java standard algorithm name specification, for different
         // purpose, the SHA-1 and SHA-2 algorithm names are different. For
@@ -127,4 +133,40 @@
         return elements;
     }
 
+    private static void hasLoop(Set<String> elements, String find, String replace) {
+        if (elements.contains(find)) {
+            if (!elements.contains(replace)) {
+                elements.add(replace);
+}
+            elements.remove(find);
+        }
+    }
+
+    /*
+     * This decomposes a standard name into sub-elements with a consistent
+     * message digest algorithm name to avoid overly complicated checking.
+     */
+    public static Set<String> decomposeOneHash(String algorithm) {
+        if (algorithm == null || algorithm.length() == 0) {
+            return new HashSet<>();
+        }
+
+        Set<String> elements = decomposeImpl(algorithm);
+
+        hasLoop(elements, "SHA-1", "SHA1");
+        hasLoop(elements, "SHA-224", "SHA224");
+        hasLoop(elements, "SHA-256", "SHA256");
+        hasLoop(elements, "SHA-384", "SHA384");
+        hasLoop(elements, "SHA-512", "SHA512");
+
+        return elements;
+    }
+
+    /*
+     * The provided message digest algorithm name will return a consistent
+     * naming scheme.
+     */
+    public static String hashName(String algorithm) {
+        return algorithm.replace("-", "");
+    }
 }
diff --git a/ojluni/src/main/java/sun/security/util/AnchorCertificates.java b/ojluni/src/main/java/sun/security/util/AnchorCertificates.java
new file mode 100644
index 0000000..6bc0030
--- /dev/null
+++ b/ojluni/src/main/java/sun/security/util/AnchorCertificates.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.security.AccessController;
+import java.security.KeyStore;
+import java.security.PrivilegedAction;
+import java.security.cert.X509Certificate;
+import java.util.Enumeration;
+import java.util.HashSet;
+
+import sun.security.x509.X509CertImpl;
+
+/**
+ * The purpose of this class is to determine the trust anchor certificates is in
+ * the cacerts file.  This is used for PKIX CertPath checking.
+ */
+public class AnchorCertificates {
+
+    private static final Debug debug = Debug.getInstance("certpath");
+    private static final String HASH = "SHA-256";
+    private static HashSet<String> certs;
+
+    static  {
+        AccessController.doPrivileged(new PrivilegedAction<Void>() {
+            @Override
+            public Void run() {
+                File f = new File(System.getProperty("java.home"),
+                        "lib/security/cacerts");
+                KeyStore cacerts;
+                try {
+                    cacerts = KeyStore.getInstance("JKS");
+                    try (FileInputStream fis = new FileInputStream(f)) {
+                        cacerts.load(fis, "changeit".toCharArray());
+                        certs = new HashSet<>();
+                        Enumeration<String> list = cacerts.aliases();
+                        String alias;
+                        while (list.hasMoreElements()) {
+                            alias = list.nextElement();
+                            // Check if this cert is labeled a trust anchor.
+                            if (alias.contains(" [jdk")) {
+                                X509Certificate cert = (X509Certificate) cacerts
+                                        .getCertificate(alias);
+                                certs.add(X509CertImpl.getFingerprint(HASH, cert));
+                            }
+                        }
+                    }
+                } catch (Exception e) {
+                    if (debug != null) {
+                        debug.println("Error parsing cacerts");
+                    }
+                    e.printStackTrace();
+                }
+                return null;
+            }
+        });
+    }
+
+    /**
+     * Checks if a certificate is a trust anchor.
+     *
+     * @param cert the certificate to check
+     * @return true if the certificate is trusted.
+     */
+    public static boolean contains(X509Certificate cert) {
+        String key = X509CertImpl.getFingerprint(HASH, cert);
+        boolean result = certs.contains(key);
+        if (result && debug != null) {
+            debug.println("AnchorCertificate.contains: matched " +
+                    cert.getSubjectDN());
+        }
+        return result;
+    }
+
+    private AnchorCertificates() {}
+}
diff --git a/ojluni/src/main/java/sun/security/util/CertConstraintParameters.java b/ojluni/src/main/java/sun/security/util/CertConstraintParameters.java
new file mode 100644
index 0000000..9f7a938
--- /dev/null
+++ b/ojluni/src/main/java/sun/security/util/CertConstraintParameters.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.security.util;
+
+import java.security.cert.X509Certificate;
+
+/**
+ * This class is a wrapper for keeping state and passing objects between PKIX,
+ * AlgorithmChecker, and DisabledAlgorithmConstraints.
+ */
+public class CertConstraintParameters {
+    // A certificate being passed to check against constraints.
+    private final X509Certificate cert;
+
+    // This is true if the trust anchor in the certificate chain matches a cert
+    // in AnchorCertificates
+    private final boolean trustedMatch;
+
+    public CertConstraintParameters(X509Certificate c, boolean match) {
+        cert = c;
+        trustedMatch = match;
+    }
+
+    public CertConstraintParameters(X509Certificate c) {
+        this(c, false);
+    }
+
+    // Returns if the trust anchor has a match if anchor checking is enabled.
+    public boolean isTrustedMatch() {
+        return trustedMatch;
+    }
+
+    public X509Certificate getCertificate() {
+        return cert;
+    }
+}
diff --git a/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java b/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java
index 05da9ba..d8c1462 100644
--- a/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java
+++ b/ojluni/src/main/java/sun/security/util/DisabledAlgorithmConstraints.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,14 @@
 import java.security.CryptoPrimitive;
 import java.security.AlgorithmParameters;
 import java.security.Key;
-import java.util.Locale;
-import java.util.Set;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Map;
+import java.security.cert.CertPathValidatorException;
+import java.security.cert.CertPathValidatorException.BasicReason;
+import java.security.cert.X509Certificate;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 
@@ -44,6 +46,7 @@
  * for the syntax of the disabled algorithm string.
  */
 public class DisabledAlgorithmConstraints extends AbstractAlgorithmConstraints {
+    private static final Debug debug = Debug.getInstance("certpath");
 
     // the known security property, jdk.certpath.disabledAlgorithms
     public final static String PROPERTY_CERTPATH_DISABLED_ALGS =
@@ -53,13 +56,9 @@
     public final static String PROPERTY_TLS_DISABLED_ALGS =
             "jdk.tls.disabledAlgorithms";
 
-    private final static Map<String, String[]> disabledAlgorithmsMap =
-                                                            new HashMap<>();
-    private final static Map<String, KeySizeConstraints> keySizeConstraintsMap =
-                                                            new HashMap<>();
 
     private final String[] disabledAlgorithms;
-    private final KeySizeConstraints keySizeConstraints;
+    private final Constraints algorithmConstraints;
 
     /**
      * Initialize algorithm constraints with the specified security property.
@@ -71,14 +70,25 @@
         this(propertyName, new AlgorithmDecomposer());
     }
 
+    /**
+     * Initialize algorithm constraints with the specified security property
+     * for a specific usage type.
+     *
+     * @param propertyName the security property name that define the disabled
+     *        algorithm constraints
+     * @param decomposer an alternate AlgorithmDecomposer.
+     */
     public DisabledAlgorithmConstraints(String propertyName,
             AlgorithmDecomposer decomposer) {
         super(decomposer);
-        disabledAlgorithms = getAlgorithms(disabledAlgorithmsMap, propertyName);
-        keySizeConstraints = getKeySizeConstraints(disabledAlgorithms,
-                propertyName);
+        disabledAlgorithms = getAlgorithms(propertyName);
+        algorithmConstraints = new Constraints(disabledAlgorithms);
     }
 
+    /*
+     * This only checks if the algorithm has been completely disabled.  If
+     * there are keysize or other limit, this method allow the algorithm.
+     */
     @Override
     final public boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, AlgorithmParameters parameters) {
@@ -90,11 +100,19 @@
         return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
     }
 
+    /*
+     * Checks if the key algorithm has been disabled or constraints have been
+     * placed on the key.
+     */
     @Override
     final public boolean permits(Set<CryptoPrimitive> primitives, Key key) {
         return checkConstraints(primitives, "", key, null);
     }
 
+    /*
+     * Checks if the key algorithm has been disabled or if constraints have
+     * been placed on the key.
+     */
     @Override
     final public boolean permits(Set<CryptoPrimitive> primitives,
             String algorithm, Key key, AlgorithmParameters parameters) {
@@ -106,7 +124,39 @@
         return checkConstraints(primitives, algorithm, key, parameters);
     }
 
-    // Check algorithm constraints
+    /*
+     * Check if a x509Certificate object is permitted.  Check if all
+     * algorithms are allowed, certificate constraints, and the
+     * public key against key constraints.
+     *
+     * Uses new style permit() which throws exceptions.
+     */
+    public final void permits(Set<CryptoPrimitive> primitives,
+            CertConstraintParameters cp) throws CertPathValidatorException {
+        checkConstraints(primitives, cp);
+    }
+
+    /*
+     * Check if Certificate object is within the constraints.
+     * Uses new style permit() which throws exceptions.
+     */
+    public final void permits(Set<CryptoPrimitive> primitives,
+            X509Certificate cert) throws CertPathValidatorException {
+        checkConstraints(primitives, new CertConstraintParameters(cert));
+    }
+
+    // Check if a string is contained inside the property
+    public boolean checkProperty(String param) {
+        param = param.toLowerCase(Locale.ENGLISH);
+        for (String block : disabledAlgorithms) {
+            if (block.toLowerCase(Locale.ENGLISH).indexOf(param) >= 0) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Check algorithm constraints with key and algorithm
     private boolean checkConstraints(Set<CryptoPrimitive> primitives,
             String algorithm, Key key, AlgorithmParameters parameters) {
 
@@ -115,7 +165,7 @@
             throw new IllegalArgumentException("The key cannot be null");
         }
 
-        // check the target algorithm
+        // check the signature algorithm
         if (algorithm != null && algorithm.length() != 0) {
             if (!permits(primitives, algorithm, parameters)) {
                 return false;
@@ -128,97 +178,203 @@
         }
 
         // check the key constraints
-        if (keySizeConstraints.disables(key)) {
-            return false;
-        }
-
-        return true;
+        return algorithmConstraints.permits(key);
     }
 
-    private static KeySizeConstraints getKeySizeConstraints(
-            String[] disabledAlgorithms, String propertyName) {
-        synchronized (keySizeConstraintsMap) {
-            if(!keySizeConstraintsMap.containsKey(propertyName)) {
-                // map the key constraints
-                KeySizeConstraints keySizeConstraints =
-                        new KeySizeConstraints(disabledAlgorithms);
-                keySizeConstraintsMap.put(propertyName, keySizeConstraints);
-            }
+    /*
+     * Check algorithm constraints with Certificate
+     * Uses new style permit() which throws exceptions.
+     */
+    private void checkConstraints(Set<CryptoPrimitive> primitives,
+            CertConstraintParameters cp) throws CertPathValidatorException {
 
-            return keySizeConstraintsMap.get(propertyName);
+        X509Certificate cert = cp.getCertificate();
+        String algorithm = cert.getSigAlgName();
+
+        // Check signature algorithm is not disabled
+        if (!permits(primitives, algorithm, null)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled "+
+                            "signature algorithm: " + algorithm,
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
         }
+
+        // Check key algorithm is not disabled
+        if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
+            throw new CertPathValidatorException(
+                    "Algorithm constraints check failed on disabled "+
+                            "public key algorithm: " + algorithm,
+                    null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+        }
+
+        // Check the certificate and key constraints
+        algorithmConstraints.permits(cp);
+
     }
 
     /**
-     * key constraints
+     * Key and Certificate Constraints
+     *
+     * The complete disabling of an algorithm is not handled by Constraints or
+     * Constraint classes.  That is addressed with
+     *   permit(Set<CryptoPrimitive>, String, AlgorithmParameters)
+     *
+     * When passing a Key to permit(), the boolean return values follow the
+     * same as the interface class AlgorithmConstraints.permit().  This is to
+     * maintain compatibility:
+     * 'true' means the operation is allowed.
+     * 'false' means it failed the constraints and is disallowed.
+     *
+     * When passing CertConstraintParameters through permit(), an exception
+     * will be thrown on a failure to better identify why the operation was
+     * disallowed.
      */
-    private static class KeySizeConstraints {
-        private static final Pattern pattern = Pattern.compile(
-                "(\\S+)\\s+keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
 
-        private Map<String, Set<KeySizeConstraint>> constraintsMap =
-            Collections.synchronizedMap(
-                        new HashMap<String, Set<KeySizeConstraint>>());
+    private static class Constraints {
+        private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
+        private static final Pattern keySizePattern = Pattern.compile(
+                "keySize\\s*(<=|<|==|!=|>|>=)\\s*(\\d+)");
 
-        public KeySizeConstraints(String[] restrictions) {
-            for (String restriction : restrictions) {
-                if (restriction == null || restriction.isEmpty()) {
+        public Constraints(String[] constraintArray) {
+            for (String constraintEntry : constraintArray) {
+                if (constraintEntry == null || constraintEntry.isEmpty()) {
                     continue;
                 }
 
-                Matcher matcher = pattern.matcher(restriction);
-                if (matcher.matches()) {
-                    String algorithm = matcher.group(1);
+                constraintEntry = constraintEntry.trim();
+                if (debug != null) {
+                    debug.println("Constraints: " + constraintEntry);
+                }
 
-                    KeySizeConstraint.Operator operator =
-                             KeySizeConstraint.Operator.of(matcher.group(2));
-                    int length = Integer.parseInt(matcher.group(3));
+                // Check if constraint is a complete disabling of an
+                // algorithm or has conditions.
+                String algorithm;
+                String policy;
+                int space = constraintEntry.indexOf(' ');
+                if (space > 0) {
+                    algorithm = AlgorithmDecomposer.hashName(
+                            constraintEntry.substring(0, space).
+                                    toUpperCase(Locale.ENGLISH));
+                    policy = constraintEntry.substring(space + 1);
+                } else {
+                    constraintsMap.computeIfAbsent(
+                            constraintEntry.toUpperCase(Locale.ENGLISH),
+                            k -> new HashSet<>());
+                    continue;
+                }
 
-                    algorithm = algorithm.toLowerCase(Locale.ENGLISH);
+                // Convert constraint conditions into Constraint classes
+                Constraint c, lastConstraint = null;
+                // Allow only one jdkCA entry per constraint entry
+                boolean jdkCALimit = false;
 
-                    synchronized (constraintsMap) {
-                        if (!constraintsMap.containsKey(algorithm)) {
-                            constraintsMap.put(algorithm,
-                                new HashSet<KeySizeConstraint>());
+                for (String entry : policy.split("&")) {
+                    entry = entry.trim();
+
+                    Matcher matcher = keySizePattern.matcher(entry);
+                    if (matcher.matches()) {
+                        if (debug != null) {
+                            debug.println("Constraints set to keySize: " +
+                                    entry);
                         }
+                        c = new KeySizeConstraint(algorithm,
+                                KeySizeConstraint.Operator.of(matcher.group(1)),
+                                Integer.parseInt(matcher.group(2)));
 
-                        Set<KeySizeConstraint> constraintSet =
-                            constraintsMap.get(algorithm);
-                        KeySizeConstraint constraint =
-                            new KeySizeConstraint(operator, length);
-                        constraintSet.add(constraint);
+                    } else if (entry.equalsIgnoreCase("jdkCA")) {
+                        if (debug != null) {
+                            debug.println("Constraints set to jdkCA.");
+                        }
+                        if (jdkCALimit) {
+                            throw new IllegalArgumentException("Only one " +
+                                    "jdkCA entry allowed in property. " +
+                                    "Constraint: " + constraintEntry);
+                        }
+                        c = new jdkCAConstraint(algorithm);
+                        jdkCALimit = true;
+                    } else {
+                        throw new IllegalArgumentException("Error in security" +
+                                " property. Constraint unknown: " + entry);
                     }
+
+                    // Link multiple conditions for a single constraint
+                    // into a linked list.
+                    if (lastConstraint == null) {
+                        if (!constraintsMap.containsKey(algorithm)) {
+                            constraintsMap.putIfAbsent(algorithm,
+                                    new HashSet<>());
+                        }
+                        constraintsMap.get(algorithm).add(c);
+                    } else {
+                        lastConstraint.nextConstraint = c;
+                    }
+                    lastConstraint = c;
                 }
             }
         }
 
-        // Does this KeySizeConstraints disable the specified key?
-        public boolean disables(Key key) {
-            String algorithm = key.getAlgorithm().toLowerCase(Locale.ENGLISH);
-            synchronized (constraintsMap) {
-                if (constraintsMap.containsKey(algorithm)) {
-                    Set<KeySizeConstraint> constraintSet =
-                                        constraintsMap.get(algorithm);
-                    for (KeySizeConstraint constraint : constraintSet) {
-                        if (constraint.disables(key)) {
-                            return true;
-                        }
-                    }
-                }
-            }
+        // Get applicable constraints based off the signature algorithm
+        private Set<Constraint> getConstraints(String algorithm) {
+            return constraintsMap.get(algorithm);
+        }
 
+        // Check if KeySizeConstraints permit the specified key
+        public boolean permits(Key key) {
+            Set<Constraint> set = getConstraints(key.getAlgorithm());
+            if (set == null) {
+                return true;
+            }
+            for (Constraint constraint : set) {
+                if (!constraint.permits(key)) {
+                    if (debug != null) {
+                        debug.println("keySizeConstraint: failed key " +
+                                "constraint check " + KeyUtil.getKeySize(key));
+                    }
             return false;
         }
+            }
+        return true;
     }
 
-    /**
-     * Key size constraint.
-     *
-     * e.g.  "keysize <= 1024"
-     */
-    private static class KeySizeConstraint {
+        // Check if constraints permit this cert.
+        public void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException {
+            X509Certificate cert = cp.getCertificate();
+
+            if (debug != null) {
+                debug.println("Constraints.permits(): " + cert.getSigAlgName());
+            }
+
+            // Get all signature algorithms to check for constraints
+            Set<String> algorithms =
+                    AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
+            if (algorithms == null || algorithms.isEmpty()) {
+                return;
+    }
+
+            // Attempt to add the public key algorithm to the set
+            algorithms.add(cert.getPublicKey().getAlgorithm());
+
+            // Check all applicable constraints
+            for (String algorithm : algorithms) {
+                Set<Constraint> set = getConstraints(algorithm);
+                if (set == null) {
+                    continue;
+                }
+                for (Constraint constraint : set) {
+                    constraint.permits(cp);
+                }
+            }
+        }
+                        }
+
+    // Abstract class for algorithm constraint checking
+    private abstract static class Constraint {
+        String algorithm;
+        Constraint nextConstraint = null;
+
         // operator
-        static enum Operator {
+        enum Operator {
             EQ,         // "=="
             NE,         // "!="
             LT,         // "<"
@@ -242,16 +398,77 @@
                         return GE;
                 }
 
-                throw new IllegalArgumentException(
-                        s + " is not a legal Operator");
+                throw new IllegalArgumentException("Error in security " +
+                        "property. " + s + " is not a legal Operator");
             }
         }
 
+        /**
+         * Check if an algorithm constraint permit this key to be used.
+         * @param key Public key
+         * @return true if constraints do not match
+         */
+        public boolean permits(Key key) {
+            return true;
+        }
+
+        /**
+         * Check if an algorithm constraint is permit this certificate to
+         * be used.
+         * @param cp CertificateParameter containing certificate and state info
+         * @return true if constraints do not match
+         */
+        public abstract void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException;
+    }
+
+    /*
+     * This class contains constraints dealing with the certificate chain
+     * of the certificate.
+     */
+    private static class jdkCAConstraint extends Constraint {
+        jdkCAConstraint(String algo) {
+            algorithm = algo;
+        }
+
+        /*
+         * Check if each constraint fails and check if there is a linked
+         * constraint  Any permitted constraint will exit the linked list
+         * to allow the operation.
+         */
+        public void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException {
+            if (debug != null) {
+                debug.println("jdkCAConstraints.permits(): " + algorithm);
+            }
+
+            // Return false if the chain has a trust anchor in cacerts
+            if (cp.isTrustedMatch()) {
+                if (nextConstraint != null) {
+                    nextConstraint.permits(cp);
+                    return;
+                }
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on certificate " +
+                                "anchor limits",
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+            }
+        }
+    }
+
+
+    /*
+     * This class contains constraints dealing with the key size
+     * support limits per algorithm.   e.g.  "keySize <= 1024"
+     */
+    private static class KeySizeConstraint extends Constraint {
+
         private int minSize;            // the minimal available key size
         private int maxSize;            // the maximal available key size
         private int prohibitedSize = -1;    // unavailable key sizes
 
-        public KeySizeConstraint(Operator operator, int length) {
+        public KeySizeConstraint(String algo, Operator operator, int length) {
+            algorithm = algo;
             switch (operator) {
                 case EQ:      // an unavailable key size
                     this.minSize = 0;
@@ -285,21 +502,58 @@
             }
         }
 
-        // Does this key constraint disable the specified key?
-        public boolean disables(Key key) {
-            int size = KeyUtil.getKeySize(key);
+        /*
+         * If we are passed a certificate, extract the public key and use it.
+         *
+         * Check if each constraint fails and check if there is a linked
+         * constraint  Any permitted constraint will exit the linked list
+         * to allow the operation.
+         */
+        public void permits(CertConstraintParameters cp)
+                throws CertPathValidatorException {
+            if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+                if (nextConstraint != null) {
+                    nextConstraint.permits(cp);
+                    return;
+                }
+                throw new CertPathValidatorException(
+                        "Algorithm constraints check failed on keysize limits",
+                        null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+            }
+        }
 
+
+        // Check if key constraint disable the specified key
+        // Uses old style permit()
+        public boolean permits(Key key) {
+            // If we recursively find a constraint that permits us to use
+            // this key, return true and skip any other constraint checks.
+            if (nextConstraint != null && nextConstraint.permits(key)) {
+                return true;
+            }
+            if (debug != null) {
+                debug.println("KeySizeConstraints.permits(): " + algorithm);
+            }
+
+            return permitsImpl(key);
+        }
+
+        private boolean permitsImpl(Key key) {
+            // Verify this constraint is for this public key algorithm
+            if (algorithm.compareToIgnoreCase(key.getAlgorithm()) != 0) {
+                return true;
+            }
+
+            int size = KeyUtil.getKeySize(key);
             if (size == 0) {
-                return true;    // we don't allow any key of size 0.
+                return false;    // we don't allow any key of size 0.
             } else if (size > 0) {
-                return ((size < minSize) || (size > maxSize) ||
+                return !((size < minSize) || (size > maxSize) ||
                     (prohibitedSize == size));
             }   // Otherwise, the key size is not accessible. Conservatively,
                 // please don't disable such keys.
 
-            return false;
+            return true;
+        }
         }
     }
-
-}
-
diff --git a/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java b/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java
index afd7c99..9e76a3a 100644
--- a/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java
+++ b/ojluni/src/main/java/sun/security/x509/AuthorityKeyIdentifierExtension.java
@@ -307,4 +307,16 @@
     public String getName() {
         return (NAME);
     }
+
+    /**
+     * Return the encoded key identifier, or null if not specified.
+     */
+    public byte[] getEncodedKeyIdentifier() throws IOException {
+        if (id != null) {
+            DerOutputStream derOut = new DerOutputStream();
+            id.encode(derOut);
+            return derOut.toByteArray();
+        }
+        return null;
+    }
 }
diff --git a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
index f9db2c5..de4d313 100644
--- a/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
+++ b/ojluni/src/main/java/sun/security/x509/X509CertImpl.java
@@ -1970,7 +1970,7 @@
 // BEGIN Android-removed
 //    public String getFingerprint(String algorithm) {
 //        return fingerprints.computeIfAbsent(algorithm,
-//                x -> getCertificateFingerPrint(x));
+//                x -> getFingerprint(x, this));
 //    }
 // END Android-removed
 
@@ -1978,11 +1978,12 @@
      * Gets the requested finger print of the certificate. The result
      * only contains 0-9 and A-F. No small case, no colon.
      */
-    private String getCertificateFingerPrint(String mdAlg) {
+    public static String getFingerprint(String algorithm,
+            X509Certificate cert) {
         String fingerPrint = "";
         try {
-            byte[] encCertInfo = getEncoded();
-            MessageDigest md = MessageDigest.getInstance(mdAlg);
+            byte[] encCertInfo = cert.getEncoded();
+            MessageDigest md = MessageDigest.getInstance(algorithm);
             byte[] digest = md.digest(encCertInfo);
             StringBuffer buf = new StringBuffer();
             for (int i = 0; i < digest.length; i++) {
diff --git a/ojluni/src/main/native/PlainSocketImpl.c b/ojluni/src/main/native/PlainSocketImpl.c
index e2ba1dc..c4b5be7 100644
--- a/ojluni/src/main/native/PlainSocketImpl.c
+++ b/ojluni/src/main/native/PlainSocketImpl.c
@@ -90,33 +90,6 @@
 }
 
 /*
- * Create the marker file descriptor by establishing a loopback connection
- * which we shutdown but do not close the fd. The result is an fd that
- * can be used for read/write.
- */
-static int getMarkerFD()
-{
-    int sv[2];
-
-#ifdef AF_UNIX
-    if (socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == -1) {
-        return -1;
-    }
-#else
-    return -1;
-#endif
-
-    /*
-     * Finally shutdown sv[0] (any reads to this fd will get
-     * EOF; any writes will get an error).
-     */
-    JVM_SocketShutdown(sv[0], 2);
-    JVM_SocketClose(sv[1]);
-
-    return sv[0];
-}
-
-/*
  * Return the file descriptor given a PlainSocketImpl
  */
 static int getFD(JNIEnv *env, jobject this) {
@@ -162,724 +135,6 @@
 
 /*
  * Class:     java_net_PlainSocketImpl
- * Method:    socketCreate
- * Signature: (Z)V */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketCreate(JNIEnv *env, jobject this,
-                                           jboolean stream) {
-    jobject fdObj, ssObj;
-    int fd;
-    int type = (stream ? SOCK_STREAM : SOCK_DGRAM);
-#ifdef AF_INET6
-    int domain = ipv6_available() ? AF_INET6 : AF_INET;
-#else
-    int domain = AF_INET;
-#endif
-
-    if (socketExceptionCls == NULL) {
-        jclass c = (*env)->FindClass(env, "java/net/SocketException");
-        CHECK_NULL(c);
-        socketExceptionCls = (jclass)(*env)->NewGlobalRef(env, c);
-        CHECK_NULL(socketExceptionCls);
-    }
-    fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    if (fdObj == NULL) {
-        (*env)->ThrowNew(env, socketExceptionCls, "null fd object");
-        return;
-    }
-
-    if ((fd = JVM_Socket(domain, type, 0)) == JVM_IO_ERR) {
-        /* note: if you run out of fds, you may not be able to load
-         * the exception class, and get a NoClassDefFoundError
-         * instead.
-         */
-        NET_ThrowNew(env, errno, "can't create socket");
-        return;
-    }
-    tagSocket(env, fd);
-
-#ifdef AF_INET6
-    /* Disable IPV6_V6ONLY to ensure dual-socket support */
-    if (domain == AF_INET6) {
-        int 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 */
-
-    /*
-     * If this is a server socket then enable SO_REUSEADDR
-     * automatically and set to non blocking.
-     */
-    ssObj = (*env)->GetObjectField(env, this, psi_serverSocketID);
-    if (ssObj != NULL) {
-        int arg = 1;
-        SET_NONBLOCKING(fd);
-        if (JVM_SetSockOpt(fd, SOL_SOCKET, SO_REUSEADDR, (char*)&arg,
-                           sizeof(arg)) < 0) {
-            NET_ThrowNew(env, errno, "cannot set SO_REUSEADDR");
-            untagSocket(env, fd);
-            close(fd);
-            return;
-        }
-    }
-
-    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
-}
-
-/*
- * inetAddress is the address object passed to the socket connect
- * call.
- *
- * Class:     java_net_PlainSocketImpl
- * Method:    socketConnect
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketConnect(JNIEnv *env, jobject this,
-                                            jobject iaObj, jint port,
-                                            jint timeout)
-{
-    jint localport = (*env)->GetIntField(env, this, psi_localportID);
-    int len = 0;
-
-    /* fdObj is the FileDescriptor field on this */
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    jclass clazz = (*env)->GetObjectClass(env, this);
-
-    jobject fdLock;
-
-    jint trafficClass = (*env)->GetIntField(env, this, psi_trafficClassID);
-
-    /* fd is an int field on iaObj */
-    jint fd;
-
-    SOCKADDR him;
-    /* The result of the connection */
-    int connect_rv = -1;
-
-    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, "inet address argument null.");
-        return;
-    }
-
-    /* connect */
-    if (NET_InetAddressToSockaddr(env, iaObj, port, (struct sockaddr *)&him, &len, JNI_TRUE) != 0) {
-      return;
-    }
-    setDefaultScopeID(env, (struct sockaddr *)&him);
-
-#ifdef AF_INET6
-    if (trafficClass != 0 && ipv6_available()) {
-        NET_SetTrafficClass((struct sockaddr *)&him, trafficClass);
-    }
-#endif /* AF_INET6 */
-    if (timeout <= 0) {
-        connect_rv = NET_Connect(fd, (struct sockaddr *)&him, len);
-#ifdef __solaris__
-        if (connect_rv == JVM_IO_ERR && errno == EINPROGRESS ) {
-
-            /* This can happen if a blocking connect is interrupted by a signal.
-             * See 6343810.
-             */
-            while (1) {
-#ifndef USE_SELECT
-                {
-                    struct pollfd pfd;
-                    pfd.fd = fd;
-                    pfd.events = POLLOUT;
-
-                    connect_rv = NET_Poll(&pfd, 1, -1);
-                }
-#else
-                {
-                    fd_set wr, ex;
-
-                    FD_ZERO(&wr);
-                    FD_SET(fd, &wr);
-                    FD_ZERO(&ex);
-                    FD_SET(fd, &ex);
-
-                    connect_rv = NET_Select(fd+1, 0, &wr, &ex, 0);
-                }
-#endif
-
-                if (connect_rv == JVM_IO_ERR) {
-                    if (errno == EINTR) {
-                        continue;
-                    } else {
-                        break;
-                    }
-                }
-                if (connect_rv > 0) {
-                    int optlen;
-                    /* has connection been established */
-                    optlen = sizeof(connect_rv);
-                    if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR,
-                                        (void*)&connect_rv, &optlen) <0) {
-                        connect_rv = errno;
-                    }
-
-                    if (connect_rv != 0) {
-                        /* restore errno */
-                        errno = connect_rv;
-                        connect_rv = JVM_IO_ERR;
-                    }
-                    break;
-                }
-            }
-        }
-#endif
-    } else {
-        /*
-         * A timeout was specified. We put the socket into non-blocking
-         * mode, connect, and then wait for the connection to be
-         * established, fail, or timeout.
-         */
-        SET_NONBLOCKING(fd);
-
-        /* no need to use NET_Connect as non-blocking */
-        connect_rv = connect(fd, (struct sockaddr *)&him, len);
-
-        /* connection not established immediately */
-        if (connect_rv != 0) {
-            int optlen;
-            jlong prevTime = JVM_CurrentTimeMillis(env, 0);
-
-            if (errno != EINPROGRESS) {
-                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
-                             "connect failed");
-                SET_BLOCKING(fd);
-                return;
-            }
-
-            /*
-             * Wait for the connection to be established or a
-             * timeout occurs. poll/select needs to handle EINTR in
-             * case lwp sig handler redirects any process signals to
-             * this thread.
-             */
-            while (1) {
-                jlong newTime;
-#ifndef USE_SELECT
-                {
-                    struct pollfd pfd;
-                    pfd.fd = fd;
-                    pfd.events = POLLOUT;
-
-                    errno = 0;
-                    connect_rv = NET_Poll(&pfd, 1, timeout);
-                }
-#else
-                {
-                    fd_set wr, ex;
-                    struct timeval t;
-
-                    t.tv_sec = timeout / 1000;
-                    t.tv_usec = (timeout % 1000) * 1000;
-
-                    FD_ZERO(&wr);
-                    FD_SET(fd, &wr);
-                    FD_ZERO(&ex);
-                    FD_SET(fd, &ex);
-
-                    errno = 0;
-                    connect_rv = NET_Select(fd+1, 0, &wr, &ex, &t);
-                }
-#endif
-
-                if (connect_rv >= 0) {
-                    break;
-                }
-                if (errno != EINTR) {
-                    break;
-                }
-
-                /*
-                 * The poll was interrupted so adjust timeout and
-                 * restart
-                 */
-                newTime = JVM_CurrentTimeMillis(env, 0);
-                timeout -= (newTime - prevTime);
-                if (timeout <= 0) {
-                    connect_rv = 0;
-                    break;
-                }
-                prevTime = newTime;
-
-            } /* while */
-
-            if (connect_rv == 0) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                            "connect timed out");
-
-                /*
-                 * Timeout out but connection may still be established.
-                 * At the high level it should be closed immediately but
-                 * just in case we make the socket blocking again and
-                 * shutdown input & output.
-                 */
-                SET_BLOCKING(fd);
-                JVM_SocketShutdown(fd, 2);
-                return;
-            }
-
-            /* has connection been established */
-            optlen = sizeof(connect_rv);
-            if (JVM_GetSockOpt(fd, SOL_SOCKET, SO_ERROR, (void*)&connect_rv,
-                               &optlen) <0) {
-                connect_rv = errno;
-            }
-        }
-
-        /* make socket blocking again */
-        SET_BLOCKING(fd);
-
-        /* restore errno */
-        if (connect_rv != 0) {
-            errno = connect_rv;
-            connect_rv = JVM_IO_ERR;
-        }
-    }
-
-    /* report the appropriate exception */
-    if (connect_rv < 0) {
-
-#ifdef __linux__
-        /*
-         * Linux/GNU distribution setup /etc/hosts so that
-         * InetAddress.getLocalHost gets back the loopback address
-         * rather than the host address. Thus a socket can be
-         * bound to the loopback address and the connect will
-         * fail with EADDRNOTAVAIL. In addition the Linux kernel
-         * returns the wrong error in this case - it returns EINVAL
-         * instead of EADDRNOTAVAIL. We handle this here so that
-         * a more descriptive exception text is used.
-         */
-        if (connect_rv == JVM_IO_ERR && errno == EINVAL) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                "Invalid argument or cannot assign requested address");
-            return;
-        }
-#endif
-        if (connect_rv == JVM_IO_INTR) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-#if defined(EPROTO)
-        } else if (errno == EPROTO) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ProtocolException",
-                           "Protocol error");
-#endif
-        } else if (errno == ECONNREFUSED) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
-                           "Connection refused");
-        } else if (errno == ETIMEDOUT) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "ConnectException",
-                           "Connection timed out");
-        } else if (errno == EHOSTUNREACH) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
-                           "Host unreachable");
-        } else if (errno == EADDRNOTAVAIL) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "NoRouteToHostException",
-                             "Address not available");
-        } else if ((errno == EISCONN) || (errno == EBADF)) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                            "Socket closed");
-        } else {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "connect failed");
-        }
-        return;
-    }
-
-    (*env)->SetIntField(env, fdObj, IO_fd_fdID, fd);
-
-    /* set the remote peer address and port */
-    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
-    (*env)->SetIntField(env, this, psi_portID, port);
-
-    /*
-     * we need to initialize the local port field if bind was called
-     * previously to the connect (by the client) then localport field
-     * will already be initialized
-     */
-    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.
-         */
-        len = SOCKADDR_LEN;
-        if (JVM_GetSockName(fd, (struct sockaddr *)&him, &len) == -1) {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                           "Error getting socket name");
-        } else {
-            localport = NET_GetPortFromSockaddr((struct sockaddr *)&him);
-            (*env)->SetIntField(env, this, psi_localportID, localport);
-        }
-    }
-}
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketBind
- * Signature: (Ljava/net/InetAddress;I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketBind(JNIEnv *env, jobject this,
-                                         jobject iaObj, jint localport) {
-
-    /* fdObj is the FileDescriptor field on this */
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    /* fd is an int field on fdObj */
-    int fd;
-    int len;
-    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;
-    }
-
-    /* set the address */
-    (*env)->SetObjectField(env, this, psi_addressID, iaObj);
-
-    /* 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, psi_localportID, localport);
-    } else {
-        (*env)->SetIntField(env, this, psi_localportID, localport);
-    }
-}
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketListen
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketListen (JNIEnv *env, jobject this,
-                                            jint count)
-{
-    /* this FileDescriptor fd field */
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    /* fdObj's int fd field */
-    int fd;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-
-    /*
-     * Workaround for bugid 4101691 in Solaris 2.6. See 4106600.
-     * If listen backlog is Integer.MAX_VALUE then subtract 1.
-     */
-    if (count == 0x7fffffff)
-        count -= 1;
-
-    if (JVM_Listen(fd, count) == JVM_IO_ERR) {
-        NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                       "Listen failed");
-    }
-}
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketAccept
- * Signature: (Ljava/net/SocketImpl;)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketAccept(JNIEnv *env, jobject this,
-                                           jobject socket)
-{
-    /* fields on this */
-    int port;
-    jint timeout = (*env)->GetIntField(env, this, psi_timeoutID);
-    jlong prevTime = 0;
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-
-    /* the FileDescriptor field on socket */
-    jobject socketFdObj;
-    /* the InetAddress field on socket */
-    jobject socketAddressObj;
-
-    /* the ServerSocket fd int field on fdObj */
-    jint fd;
-
-    /* accepted fd */
-    jint newfd;
-
-    SOCKADDR him;
-    int len;
-
-    len = SOCKADDR_LEN;
-
-    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(socket)) {
-        JNU_ThrowNullPointerException(env, "socket is null");
-        return;
-    }
-
-    /*
-     * accept connection but ignore ECONNABORTED indicating that
-     * connection was eagerly accepted by the OS but was reset
-     * before accept() was called.
-     *
-     * If accept timeout in place and timeout is adjusted with
-     * each ECONNABORTED or EWOULDBLOCK to ensure that semantics
-     * of timeout are preserved.
-     */
-    for (;;) {
-        int ret;
-
-        /* first usage pick up current time */
-        if (prevTime == 0 && timeout > 0) {
-            prevTime = JVM_CurrentTimeMillis(env, 0);
-        }
-
-        /* passing a timeout of 0 to poll will return immediately,
-           but in the case of ServerSocket 0 means infinite. */
-        if (timeout <= 0) {
-            ret = NET_Timeout(fd, -1);
-        } else {
-            ret = NET_Timeout(fd, timeout);
-        }
-
-        if (ret == 0) {
-            JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                            "Accept timed out");
-            return;
-        } else if (ret == JVM_IO_ERR) {
-            if (errno == EBADF) {
-               JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-            } else {
-               NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed");
-            }
-            return;
-        } else if (ret == JVM_IO_INTR) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-            return;
-        }
-
-        newfd = NET_Accept(fd, (struct sockaddr *)&him, (jint*)&len);
-
-        /* connection accepted */
-        if (newfd >= 0) {
-            SET_BLOCKING(newfd);
-            break;
-        }
-
-        /* non (ECONNABORTED or EWOULDBLOCK) error */
-        if (!(errno == ECONNABORTED || errno == EWOULDBLOCK)) {
-            break;
-        }
-
-        /* ECONNABORTED or EWOULDBLOCK error so adjust timeout if there is one. */
-        if (timeout) {
-            jlong currTime = JVM_CurrentTimeMillis(env, 0);
-            timeout -= (currTime - prevTime);
-
-            if (timeout <= 0) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketTimeoutException",
-                                "Accept timed out");
-                return;
-            }
-            prevTime = currTime;
-        }
-    }
-
-    if (newfd < 0) {
-        if (newfd == -2) {
-            JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException",
-                            "operation interrupted");
-        } else {
-            if (errno == EINVAL) {
-                errno = EBADF;
-            }
-            if (errno == EBADF) {
-                JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", "Socket closed");
-            } else {
-                NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", "Accept failed");
-            }
-        }
-        return;
-    }
-
-    /*
-     * fill up the remote peer port and address in the new socket structure.
-     */
-    socketAddressObj = NET_SockaddrToInetAddress(env, (struct sockaddr *)&him, &port);
-    if (socketAddressObj == NULL) {
-        /* should be pending exception */
-        untagSocket(env, fd);
-        close(newfd);
-        return;
-    }
-
-    /*
-     * Populate SocketImpl.fd.fd
-     */
-    socketFdObj = (*env)->GetObjectField(env, socket, psi_fdID);
-    (*env)->SetIntField(env, socketFdObj, IO_fd_fdID, newfd);
-
-    (*env)->SetObjectField(env, socket, psi_addressID, socketAddressObj);
-    (*env)->SetIntField(env, socket, psi_portID, port);
-    /* also fill up the local port information */
-     port = (*env)->GetIntField(env, this, psi_localportID);
-    (*env)->SetIntField(env, socket, psi_localportID, port);
-}
-
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketAvailable
- * Signature: ()I
- */
-JNIEXPORT jint JNICALL
-PlainSocketImpl_socketAvailable(JNIEnv *env, jobject this) {
-
-    jint ret = -1;
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jint fd;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "Socket closed");
-        return -1;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    /* JVM_SocketAvailable returns 0 for failure, 1 for success */
-    if (!JVM_SocketAvailable(fd, &ret)){
-        if (errno == ECONNRESET) {
-            JNU_ThrowByName(env, "sun/net/ConnectionResetException", "");
-        } else {
-            NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
-                                         "ioctl FIONREAD failed");
-        }
-    }
-    return ret;
-}
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketClose0
- * Signature: (Z)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketClose0(JNIEnv *env, jobject this,
-                                          jboolean useDeferredClose) {
-
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jint fd;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket already closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    if (fd != -1) {
-        int marker_fd = -1;
-        if (useDeferredClose) {
-            marker_fd = getMarkerFD();
-        }
-        if (useDeferredClose && marker_fd >= 0) {
-            NET_Dup2(marker_fd, fd);
-            NET_SocketClose(marker_fd);
-        } else {
-            (*env)->SetIntField(env, fdObj, IO_fd_fdID, -1);
-            NET_SocketClose(fd);
-        }
-    }
-}
-
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketShutdown
- * Signature: (I)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketShutdown(JNIEnv *env, jobject this,
-                                             jint howto)
-{
-
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    jint fd;
-
-    /*
-     * WARNING: THIS NEEDS LOCKING. ALSO: SHOULD WE CHECK for fd being
-     * -1 already?
-     */
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException",
-                        "socket already closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-    }
-    JVM_SocketShutdown(fd, howto);
-}
-
-
-/*
- * Class:     java_net_PlainSocketImpl
  * Method:    socketSetOption0
  * Signature: (IZLjava/lang/Object;)V
  */
@@ -1067,56 +322,9 @@
 }
 
 
-/*
- * Class:     java_net_PlainSocketImpl
- * Method:    socketSendUrgentData
- * Signature: (B)V
- */
-JNIEXPORT void JNICALL
-PlainSocketImpl_socketSendUrgentData(JNIEnv *env, jobject this,
-                                             jint data) {
-    /* The fd field */
-    jobject fdObj = (*env)->GetObjectField(env, this, psi_fdID);
-    int n, fd;
-    unsigned char d = data & 0xFF;
-
-    if (IS_NULL(fdObj)) {
-        JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
-        return;
-    } else {
-        fd = (*env)->GetIntField(env, fdObj, IO_fd_fdID);
-        /* Bug 4086704 - If the Socket associated with this file descriptor
-         * was closed (sysCloseFD), the the file descriptor is set to -1.
-         */
-        if (fd == -1) {
-            JNU_ThrowByName(env, "java/net/SocketException", "Socket closed");
-            return;
-        }
-
-    }
-    n = JVM_Send(fd, (char *)&d, 1, MSG_OOB);
-    if (n == JVM_IO_ERR) {
-        NET_ThrowByNameWithLastError(env, "java/io/IOException", "Write failed");
-        return;
-    }
-    if (n == JVM_IO_INTR) {
-        JNU_ThrowByName(env, "java/io/InterruptedIOException", 0);
-        return;
-    }
-}
-
 static JNINativeMethod gMethods[] = {
-  NATIVE_METHOD(PlainSocketImpl, socketSendUrgentData, "(I)V"),
   NATIVE_METHOD(PlainSocketImpl, socketGetOption, "(ILjava/lang/Object;)I"),
   NATIVE_METHOD(PlainSocketImpl, socketSetOption0, "(IZLjava/lang/Object;)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketShutdown, "(I)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketClose0, "(Z)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketAccept, "(Ljava/net/SocketImpl;)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketAvailable, "()I"),
-  NATIVE_METHOD(PlainSocketImpl, socketListen, "(I)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketBind, "(Ljava/net/InetAddress;I)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketConnect, "(Ljava/net/InetAddress;II)V"),
-  NATIVE_METHOD(PlainSocketImpl, socketCreate, "(Z)V"),
 };
 
 void register_java_net_PlainSocketImpl(JNIEnv* env) {
diff --git a/ojluni/src/test/java/security/cert/AKISerialNumberTest.java b/ojluni/src/test/java/security/cert/AKISerialNumberTest.java
new file mode 100644
index 0000000..aae931d
--- /dev/null
+++ b/ojluni/src/test/java/security/cert/AKISerialNumberTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+/**
+ * @test
+ * @bug 8025708
+ * @summary make sure a PKIX CertPathBuilder can build a path when an
+ *     intermediate CA certificate contains an AKI extension with a key
+ *     identifier and no serial number and the end-entity certificate contains
+ *     an AKI extension with both a key identifier and a serial number.
+ */
+// Android-changed: Adapted from
+// jdk/test/java/security/cert/CertPathBuilder/akiExt/AKISerialNumber.java
+// Android-changed: Added package & Test import
+package test.java.security.cert;
+import org.testng.annotations.Test;
+
+import java.io.ByteArrayInputStream;
+import java.security.cert.*;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.Collections;
+
+public class AKISerialNumberTest {
+
+    private static final String ROOT_CERT =
+        "MIICfTCCAeagAwIBAgIBATANBgkqhkiG9w0BAQUFADB3MQ0wCwYDVQQDEwRSb290\n" +
+        "MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0IE9yZzEWMBQG\n" +
+        "A1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkG\n" +
+        "A1UEBhMCVVMwHhcNMTQwMjAxMDUwMDAwWhcNMjQwMjAxMDUwMDAwWjB3MQ0wCwYD\n" +
+        "VQQDEwRSb290MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0\n" +
+        "IE9yZzEWMBQGA1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVz\n" +
+        "ZXR0czELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJvL\n" +
+        "cZu6Rzf9IrduEDjJxEFv5uBvUNMlIAph7NhfmFH9puPW3Ksci4a5yTCzxI9VeVf3\n" +
+        "oYZ/UrZdF+mNZmS23RUh71X5tjMO+xew196M1xNpCRLbjcZ6i4tNdZYkdRIe8ejN\n" +
+        "sbBoD7OAvPbQqTygeG4jYjK6ODofSrba3BndNoFxAgMBAAGjGTAXMBUGA1UdEwEB\n" +
+        "/wQLMAkBAf8CBH////8wDQYJKoZIhvcNAQEFBQADgYEATvCqn69pNHv0zLiZAXk7\n" +
+        "3AKwAoza0wa+1S2rVuZGfBWbV7CxmBHbgcDDbU7/I8pQVkCwOHNkVFnBgNpMuAvU\n" +
+        "aDyrHSNS/av5d1yk5WAuGX2B9mSwZdhnAvtz2fsV1q9NptdF54EkIiKtQQmTGnr9\n" +
+        "TID8CFEk/qje+AB272B1UJw=\n";
+
+    /**
+     * This certificate contains an AuthorityKeyIdentifier with only the
+     * keyIdentifier field filled in.
+     */
+    private static final String INT_CERT_WITH_KEYID_AKI =
+        "MIICqTCCAhKgAwIBAgIBAjANBgkqhkiG9w0BAQUFADB3MQ0wCwYDVQQDEwRSb290\n" +
+        "MRYwFAYDVQQLEw1UZXN0IE9yZyBVbml0MREwDwYDVQQKEwhUZXN0IE9yZzEWMBQG\n" +
+        "A1UEBxMNVGVzdCBMb2NhbGl0eTEWMBQGA1UECBMNTWFzc2FjaHVzZXR0czELMAkG\n" +
+        "A1UEBhMCVVMwHhcNMTQwMjAxMDUwMDAwWhcNMjQwMjAxMDUwMDAwWjCBhDEaMBgG\n" +
+        "A1UEAxMRSW50ZXJtZWRpYXRlIENBIDIxFjAUBgNVBAsTDVRlc3QgT3JnIFVuaXQx\n" +
+        "ETAPBgNVBAoTCFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5MRYwFAYD\n" +
+        "VQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG9w0BAQEF\n" +
+        "AAOBjQAwgYkCgYEAwKTZekCqb9F9T54s2IXjkQbmLIjQamMpkUlZNrpjjNq9CpTT\n" +
+        "POkfxv2UPwzTz3Ij4XFL/kJFBLm8NUOsS5xPJ62pGoZBPw9R0iMTsTce+Fpukqnr\n" +
+        "I+8jTRaAvr0tR3pqrE6uHKg7dWYN2SsWesDia/LHhwEN38yyWtSuTTLo4hcCAwEA\n" +
+        "AaM3MDUwHwYDVR0jBBgwFoAU6gZP1pO8v7+i8gsFf1gWTf/j3PkwEgYDVR0TAQH/\n" +
+        "BAgwBgEB/wIBADANBgkqhkiG9w0BAQUFAAOBgQAQxeQruav4AqQM4gmEfrHr5hOq\n" +
+        "mB2CNJ1ZqVfpDZ8GHijncKTpjNoXzzQtV23Ge+39JHOVBNWtk+aghB3iu6xGq7Qn\n" +
+        "HlBhg9meqHFqd3igDDD/jhABL2/bEo/M9rv6saYWDFZ8nCIEE6iTLTpRRko4W2Xb\n" +
+        "DyzMzMsO1kPNrJaxRg==\n";
+
+    /**
+     * This certificate contains an AuthorityKeyIdentifier with all 3 fields
+     * (keyIdentifier, authorityCertIssuer, and authorityCertSerialNumber)
+     * filled in.
+     */
+    private static final String EE_CERT_WITH_FULL_AKI =
+        "MIIDLjCCApegAwIBAgIBAzANBgkqhkiG9w0BAQUFADCBhDEaMBgGA1UEAxMRSW50\n" +
+        "ZXJtZWRpYXRlIENBIDIxFjAUBgNVBAsTDVRlc3QgT3JnIFVuaXQxETAPBgNVBAoT\n" +
+        "CFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5MRYwFAYDVQQIEw1NYXNz\n" +
+        "YWNodXNldHRzMQswCQYDVQQGEwJVUzAeFw0xNDAyMDEwNTAwMDBaFw0yNDAyMDEw\n" +
+        "NTAwMDBaMH0xEzARBgNVBAMTCkVuZCBFbnRpdHkxFjAUBgNVBAsTDVRlc3QgT3Jn\n" +
+        "IFVuaXQxETAPBgNVBAoTCFRlc3QgT3JnMRYwFAYDVQQHEw1UZXN0IExvY2FsaXR5\n" +
+        "MRYwFAYDVQQIEw1NYXNzYWNodXNldHRzMQswCQYDVQQGEwJVUzCBnzANBgkqhkiG\n" +
+        "9w0BAQEFAAOBjQAwgYkCgYEAqady46PdwlKHVP1iaP11CxVyL6cDlPjpwhHCcIUv\n" +
+        "nKHbzdamqmHebDcWVBNN/I0TLNCl3ga7n8KyygSN379fG7haU8SNjpy4IDAXM0/x\n" +
+        "mwTWNTbKfJEkSoiqx1WUy2JTzRUMhgYPguQNECPxBXAdQrthZ7wQosv6Ro2ySP9O\n" +
+        "YqsCAwEAAaOBtTCBsjCBoQYDVR0jBIGZMIGWgBQdeoKxTvlTgW2KgprD69vgHV4X\n" +
+        "kKF7pHkwdzENMAsGA1UEAxMEUm9vdDEWMBQGA1UECxMNVGVzdCBPcmcgVW5pdDER\n" +
+        "MA8GA1UEChMIVGVzdCBPcmcxFjAUBgNVBAcTDVRlc3QgTG9jYWxpdHkxFjAUBgNV\n" +
+        "BAgTDU1hc3NhY2h1c2V0dHMxCzAJBgNVBAYTAlVTggECMAwGA1UdEwEB/wQCMAAw\n" +
+        "DQYJKoZIhvcNAQEFBQADgYEAuG4mM1nLF7STQWwmceELZEl49ntapH/RVoekknmd\n" +
+        "aNzcL4XQf6BTl8KFUXuThHaukQnGIzFbSZV0hrpSQ5fTN2cSZgD4Fji+HuNURmmd\n" +
+        "+Kayl0piHyO1FSbrty0TFhlVNvzKXjmMp6Jdn42KyGOSCoROQcvUWN6xkV3Hvrei\n" +
+        "0ZE=\n";
+
+    private static Base64.Decoder b64Decoder = Base64.getMimeDecoder();
+    private static CertificateFactory cf;
+
+    // Android-changed: Removed args & added @Test
+    @Test
+    public static void main() throws Exception {
+
+        cf = CertificateFactory.getInstance("X.509");
+
+        X509Certificate rootCert = getCertFromMimeEncoding(ROOT_CERT);
+        TrustAnchor anchor = new TrustAnchor(rootCert, null);
+
+        X509Certificate eeCert = getCertFromMimeEncoding(EE_CERT_WITH_FULL_AKI);
+        X509Certificate intCert = getCertFromMimeEncoding(INT_CERT_WITH_KEYID_AKI);
+
+        X509CertSelector sel = new X509CertSelector();
+        sel.setCertificate(eeCert);
+        PKIXBuilderParameters params = new PKIXBuilderParameters
+            (Collections.singleton(anchor), sel);
+        params.setRevocationEnabled(false);
+
+        ArrayList<X509Certificate> certs = new ArrayList<>();
+        certs.add(intCert);
+        certs.add(eeCert);
+        CollectionCertStoreParameters ccsp =
+            new CollectionCertStoreParameters(certs);
+        CertStore cs = CertStore.getInstance("Collection", ccsp);
+        params.addCertStore(cs);
+
+        CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
+        CertPathBuilderResult res = cpb.build(params);
+    }
+
+    private static X509Certificate getCertFromMimeEncoding(String encoded)
+        throws CertificateException
+    {
+        byte[] bytes = b64Decoder.decode(encoded);
+        ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
+        return (X509Certificate)cf.generateCertificate(stream);
+    }
+}
\ No newline at end of file
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index 4285911..3b38617 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1610,6 +1610,8 @@
     ojluni/src/main/java/sun/security/provider/certpath/X509CertificatePair.java \
     ojluni/src/main/java/sun/security/provider/X509Factory.java \
     ojluni/src/main/java/sun/security/timestamp/TimestampToken.java \
+    ojluni/src/main/java/sun/security/util/AnchorCertificates.java \
+    ojluni/src/main/java/sun/security/util/CertConstraintParameters.java \
     ojluni/src/main/java/sun/security/util/AbstractAlgorithmConstraints.java \
     ojluni/src/main/java/sun/security/util/AlgorithmDecomposer.java \
     ojluni/src/main/java/sun/security/util/BitArray.java \
diff --git a/tools/docs/crypto/crypto_docs.py b/tools/docs/crypto/crypto_docs.py
new file mode 100644
index 0000000..d1f220d
--- /dev/null
+++ b/tools/docs/crypto/crypto_docs.py
@@ -0,0 +1,31 @@
+# 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.
+
+'''Utility functions for crypto doc updating tools.'''
+
+import json
+
+
+def load_json(filename):
+    '''Returns an object containing the JSON data from the provided file.'''
+    f = open(filename)
+    # JSON doesn't allow comments, but we have some header docs in our file,
+    # so strip comments out before parsing
+    stripped_contents = ''
+    for line in f:
+        if not line.strip().startswith('#'):
+            stripped_contents += line
+    data = json.loads(stripped_contents)
+    f.close()
+    return data
diff --git a/tools/docs/crypto/data/crypto_support.json b/tools/docs/crypto/data/crypto_support.json
index d50eb2c..38834d9 100644
--- a/tools/docs/crypto/data/crypto_support.json
+++ b/tools/docs/crypto/data/crypto_support.json
@@ -16,7 +16,7 @@
         },
         {
           "deprecated": "true",
-          "name": "DESEDE",
+          "name": "DESede",
           "supported_api_levels": "1-8"
         },
         {
@@ -45,7 +45,7 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "DESEDE",
+          "name": "DESede",
           "supported_api_levels": "1+"
         },
         {
@@ -74,43 +74,43 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHHMACSHA1ANDAES_128",
+          "name": "PBEwithHmacSHA1AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA1ANDAES_256",
+          "name": "PBEwithHmacSHA1AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA224ANDAES_128",
+          "name": "PBEwithHmacSHA224AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA224ANDAES_256",
+          "name": "PBEwithHmacSHA224AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA256ANDAES_128",
+          "name": "PBEwithHmacSHA256AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA256ANDAES_256",
+          "name": "PBEwithHmacSHA256AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA384ANDAES_128",
+          "name": "PBEwithHmacSHA384AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA384ANDAES_256",
+          "name": "PBEwithHmacSHA384AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA512ANDAES_128",
+          "name": "PBEwithHmacSHA512AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA512ANDAES_256",
+          "name": "PBEwithHmacSHA512AndAES_256",
           "supported_api_levels": "26+"
         },
         {
@@ -145,7 +145,7 @@
     {
       "algorithms": [
         {
-          "name": "COLLECTION",
+          "name": "Collection",
           "supported_api_levels": "1+"
         }
       ],
@@ -163,6 +163,411 @@
     {
       "algorithms": [
         {
+          "name": "AES/CBC/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CBC/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CBC/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CFB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CFB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CFB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CTR/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CTR/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CTR/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CTS/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CTS/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/CTS/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/ECB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/ECB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/ECB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/GCM/NOPADDING",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "AES/OFB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/OFB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES/OFB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "AES_128/CBC/NoPadding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_128/CBC/PKCS5Padding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_128/ECB/NoPadding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_128/ECB/PKCS5Padding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_128/GCM/NoPadding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_256/CBC/NoPadding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_256/CBC/PKCS5Padding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_256/ECB/NoPadding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_256/ECB/PKCS5Padding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "AES_256/GCM/NoPadding",
+          "supported_api_levels": "26+"
+        },
+        {
+          "name": "ARC4/ECB/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CBC/ISO10126Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CBC/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CBC/PKCS5Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CFB/ISO10126Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CFB/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CFB/PKCS5Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CTR/ISO10126Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CTR/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CTR/PKCS5Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CTS/ISO10126Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CTS/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/CTS/PKCS5Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/ECB/ISO10126Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/ECB/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/ECB/PKCS5Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/OFB/ISO10126Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/OFB/NoPadding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "BLOWFISH/OFB/PKCS5Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "DES/CBC/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CBC/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CBC/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CFB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CFB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CFB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CTR/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CTR/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CTR/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CTS/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CTS/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/CTS/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/ECB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/ECB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/ECB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/OFB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/OFB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DES/OFB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CBC/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CBC/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CBC/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CFB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CFB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CFB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CTR/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CTR/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CTR/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CTS/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CTS/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/CTS/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/ECB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/ECB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/ECB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/OFB/ISO10126Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/OFB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "DESede/OFB/PKCS5Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "RSA/ECB/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "RSA/ECB/OAEPPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "RSA/ECB/OAEPwithSHA-1andMGF1Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "RSA/ECB/OAEPwithSHA-224andMGF1Padding",
+          "supported_api_levels": "23+"
+        },
+        {
+          "name": "RSA/ECB/OAEPwithSHA-256andMGF1Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "RSA/ECB/OAEPwithSHA-384andMGF1Padding",
+          "supported_api_levels": "23+"
+        },
+        {
+          "name": "RSA/ECB/OAEPwithSHA-512andMGF1Padding",
+          "supported_api_levels": "23+"
+        },
+        {
+          "name": "RSA/ECB/PKCS1Padding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "RSA/NONE/NoPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "RSA/NONE/OAEPPadding",
+          "supported_api_levels": "1+"
+        },
+        {
+          "name": "RSA/NONE/OAEPwithSHA-1andMGF1Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "RSA/NONE/OAEPwithSHA-224andMGF1Padding",
+          "supported_api_levels": "23+"
+        },
+        {
+          "name": "RSA/NONE/OAEPwithSHA-256andMGF1Padding",
+          "supported_api_levels": "10+"
+        },
+        {
+          "name": "RSA/NONE/OAEPwithSHA-384andMGF1Padding",
+          "supported_api_levels": "23+"
+        },
+        {
+          "name": "RSA/NONE/OAEPwithSHA-512andMGF1Padding",
+          "supported_api_levels": "23+"
+        },
+        {
+          "name": "RSA/NONE/PKCS1Padding",
+          "supported_api_levels": "1+"
+        }
+      ],
+      "name": "Cipher"
+    },
+    {
+      "algorithms": [
+        {
           "name": "DH",
           "supported_api_levels": "1+"
         },
@@ -223,36 +628,36 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "DESEDE",
+          "name": "DESede",
           "supported_api_levels": "1+"
         },
         {
           "deprecated": "true",
-          "name": "DESEDEWRAP",
+          "name": "DESedeWRAP",
           "supported_api_levels": "1-8"
         },
         {
-          "name": "HMACMD5",
+          "name": "HmacMD5",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA1",
+          "name": "HmacSHA1",
           "supported_api_levels": "11+"
         },
         {
-          "name": "HMACSHA224",
+          "name": "HmacSHA224",
           "supported_api_levels": "1-8,22+"
         },
         {
-          "name": "HMACSHA256",
+          "name": "HmacSHA256",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA384",
+          "name": "HmacSHA384",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA512",
+          "name": "HmacSHA512",
           "supported_api_levels": "1+"
         },
         {
@@ -296,11 +701,11 @@
     {
       "algorithms": [
         {
-          "name": "ANDROIDCASTORE",
+          "name": "AndroidCAStore",
           "supported_api_levels": "14+"
         },
         {
-          "name": "ANDROIDKEYSTORE",
+          "name": "AndroidKeyStore",
           "supported_api_levels": "18+"
         },
         {
@@ -313,7 +718,7 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "BOUNCYCASTLE",
+          "name": "BouncyCastle",
           "supported_api_levels": "1+"
         },
         {
@@ -332,21 +737,6 @@
       "algorithms": [
         {
           "deprecated": "true",
-          "name": "DESEDEMAC",
-          "supported_api_levels": "1-8"
-        },
-        {
-          "deprecated": "true",
-          "name": "DESEDEMAC/CFB8",
-          "supported_api_levels": "1-8"
-        },
-        {
-          "deprecated": "true",
-          "name": "DESEDEMAC64",
-          "supported_api_levels": "1-8"
-        },
-        {
-          "deprecated": "true",
           "name": "DESMAC",
           "supported_api_levels": "1-8"
         },
@@ -357,31 +747,46 @@
         },
         {
           "deprecated": "true",
-          "name": "DESWITHISO9797",
+          "name": "DESedeMAC",
           "supported_api_levels": "1-8"
         },
         {
-          "name": "HMACMD5",
+          "deprecated": "true",
+          "name": "DESedeMAC/CFB8",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "DESedeMAC64",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "deprecated": "true",
+          "name": "DESwithISO9797",
+          "supported_api_levels": "1-8"
+        },
+        {
+          "name": "HmacMD5",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA1",
+          "name": "HmacSHA1",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA224",
+          "name": "HmacSHA224",
           "supported_api_levels": "1-8,22+"
         },
         {
-          "name": "HMACSHA256",
+          "name": "HmacSHA256",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA384",
+          "name": "HmacSHA384",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA512",
+          "name": "HmacSHA512",
           "supported_api_levels": "1+"
         },
         {
@@ -390,27 +795,27 @@
           "supported_api_levels": "1-8"
         },
         {
-          "name": "PBEWITHHMACSHA",
+          "name": "PBEwithHmacSHA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHHMACSHA1",
+          "name": "PBEwithHmacSHA1",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHHMACSHA224",
+          "name": "PBEwithHmacSHA224",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA256",
+          "name": "PBEwithHmacSHA256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA384",
+          "name": "PBEwithHmacSHA384",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA512",
+          "name": "PBEwithHmacSHA512",
           "supported_api_levels": "26+"
         }
       ],
@@ -448,7 +853,7 @@
     {
       "algorithms": [
         {
-          "name": "DEFAULT",
+          "name": "Default",
           "supported_api_levels": "10+"
         },
         {
@@ -457,7 +862,7 @@
         },
         {
           "deprecated": "true",
-          "name": "SSLV3",
+          "name": "SSLv3",
           "supported_api_levels": "10-25"
         },
         {
@@ -465,15 +870,15 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "TLSV1",
+          "name": "TLSv1",
           "supported_api_levels": "10+"
         },
         {
-          "name": "TLSV1.1",
+          "name": "TLSv1.1",
           "supported_api_levels": "16+"
         },
         {
-          "name": "TLSV1.2",
+          "name": "TLSv1.2",
           "supported_api_levels": "16+"
         }
       ],
@@ -490,175 +895,175 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "DESEDE",
+          "name": "DESede",
           "supported_api_levels": "1+"
         },
         {
-          "name": "HMACSHA1",
+          "name": "HmacSHA1",
           "supported_api_levels": "23+"
         },
         {
-          "name": "HMACSHA224",
+          "name": "HmacSHA224",
           "supported_api_levels": "23+"
         },
         {
-          "name": "HMACSHA256",
+          "name": "HmacSHA256",
           "supported_api_levels": "23+"
         },
         {
-          "name": "HMACSHA384",
+          "name": "HmacSHA384",
           "supported_api_levels": "23+"
         },
         {
-          "name": "HMACSHA512",
+          "name": "HmacSHA512",
           "supported_api_levels": "23+"
         },
         {
-          "name": "PBEWITHHMACSHA1",
+          "name": "PBEwithHmacSHA1",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHHMACSHA1ANDAES_128",
+          "name": "PBEwithHmacSHA1AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA1ANDAES_256",
+          "name": "PBEwithHmacSHA1AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA224ANDAES_128",
+          "name": "PBEwithHmacSHA224AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA224ANDAES_256",
+          "name": "PBEwithHmacSHA224AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA256ANDAES_128",
+          "name": "PBEwithHmacSHA256AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA256ANDAES_256",
+          "name": "PBEwithHmacSHA256AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA384ANDAES_128",
+          "name": "PBEwithHmacSHA384AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA384ANDAES_256",
+          "name": "PBEwithHmacSHA384AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA512ANDAES_128",
+          "name": "PBEwithHmacSHA512AndAES_128",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHHMACSHA512ANDAES_256",
+          "name": "PBEwithHmacSHA512AndAES_256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
+          "name": "PBEwithMD5AND128BITAES-CBC-OPENSSL",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
+          "name": "PBEwithMD5AND192BITAES-CBC-OPENSSL",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHMD5AND256BITAES-CBC-OPENSSL",
+          "name": "PBEwithMD5AND256BITAES-CBC-OPENSSL",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHMD5ANDDES",
+          "name": "PBEwithMD5ANDDES",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHMD5ANDRC2",
+          "name": "PBEwithMD5ANDRC2",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHA1ANDDES",
+          "name": "PBEwithSHA1ANDDES",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHA1ANDRC2",
+          "name": "PBEwithSHA1ANDRC2",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHA256AND128BITAES-CBC-BC",
+          "name": "PBEwithSHA256AND128BITAES-CBC-BC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHA256AND192BITAES-CBC-BC",
+          "name": "PBEwithSHA256AND192BITAES-CBC-BC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHA256AND256BITAES-CBC-BC",
+          "name": "PBEwithSHA256AND256BITAES-CBC-BC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND128BITAES-CBC-BC",
+          "name": "PBEwithSHAAND128BITAES-CBC-BC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND128BITRC2-CBC",
+          "name": "PBEwithSHAAND128BITRC2-CBC",
           "supported_api_levels": "10+"
         },
         {
-          "name": "PBEWITHSHAAND128BITRC4",
+          "name": "PBEwithSHAAND128BITRC4",
           "supported_api_levels": "10+"
         },
         {
-          "name": "PBEWITHSHAAND192BITAES-CBC-BC",
+          "name": "PBEwithSHAAND192BITAES-CBC-BC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND2-KEYTRIPLEDES-CBC",
+          "name": "PBEwithSHAAND2-KEYTRIPLEDES-CBC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND256BITAES-CBC-BC",
+          "name": "PBEwithSHAAND256BITAES-CBC-BC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND3-KEYTRIPLEDES-CBC",
+          "name": "PBEwithSHAAND3-KEYTRIPLEDES-CBC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND40BITRC2-CBC",
+          "name": "PBEwithSHAAND40BITRC2-CBC",
           "supported_api_levels": "1+"
         },
         {
-          "name": "PBEWITHSHAAND40BITRC4",
+          "name": "PBEwithSHAAND40BITRC4",
           "supported_api_levels": "10+"
         },
         {
-          "name": "PBEWITHSHAANDTWOFISH-CBC",
+          "name": "PBEwithSHAANDTWOFISH-CBC",
           "supported_api_levels": "10+"
         },
         {
-          "name": "PBKDF2WITHHMACSHA1",
+          "name": "PBKDF2withHmacSHA1",
           "supported_api_levels": "10+"
         },
         {
-          "name": "PBKDF2WITHHMACSHA1AND8BIT",
+          "name": "PBKDF2withHmacSHA1And8BIT",
           "supported_api_levels": "19+"
         },
         {
-          "name": "PBKDF2WITHHMACSHA224",
+          "name": "PBKDF2withHmacSHA224",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBKDF2WITHHMACSHA256",
+          "name": "PBKDF2withHmacSHA256",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBKDF2WITHHMACSHA384",
+          "name": "PBKDF2withHmacSHA384",
           "supported_api_levels": "26+"
         },
         {
-          "name": "PBKDF2WITHHMACSHA512",
+          "name": "PBKDF2withHmacSHA512",
           "supported_api_levels": "26+"
         }
       ],
@@ -680,7 +1085,7 @@
           "supported_api_levels": "1+"
         },
         {
-          "name": "DSAWITHSHA1",
+          "name": "DSAwithSHA1",
           "supported_api_levels": "1+"
         },
         {
@@ -693,38 +1098,38 @@
           "supported_api_levels": "11+"
         },
         {
-          "name": "ECDSAWITHSHA1",
+          "name": "ECDSAwithSHA1",
           "supported_api_levels": "11+"
         },
         {
           "deprecated": "true",
-          "name": "MD2WITHRSA",
+          "name": "MD2withRSA",
           "supported_api_levels": "1-3"
         },
         {
           "deprecated": "true",
-          "name": "MD4WITHRSA",
+          "name": "MD4withRSA",
           "supported_api_levels": "1-8"
         },
         {
-          "name": "MD5WITHRSA",
+          "name": "MD5withRSA",
           "supported_api_levels": "1+"
         },
         {
           "deprecated": "true",
-          "name": "MD5WITHRSA/ISO9796-2",
+          "name": "MD5withRSA/ISO9796-2",
           "supported_api_levels": "1-8"
         },
         {
-          "name": "NONEWITHDSA",
+          "name": "NONEwithDSA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "NONEWITHECDSA",
+          "name": "NONEwithECDSA",
           "supported_api_levels": "11+"
         },
         {
-          "name": "NONEWITHRSA",
+          "name": "NONEwithRSA",
           "supported_api_levels": "17+"
         },
         {
@@ -733,80 +1138,80 @@
           "supported_api_levels": "1-8"
         },
         {
-          "name": "SHA1WITHDSA",
+          "name": "SHA1withDSA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "SHA1WITHECDSA",
+          "name": "SHA1withECDSA",
           "supported_api_levels": "11+"
         },
         {
-          "name": "SHA1WITHRSA",
+          "name": "SHA1withRSA",
           "supported_api_levels": "1+"
         },
         {
           "deprecated": "true",
-          "name": "SHA1WITHRSA/ISO9796-2",
+          "name": "SHA1withRSA/ISO9796-2",
           "supported_api_levels": "1-8"
         },
         {
-          "name": "SHA1WITHRSA/PSS",
+          "name": "SHA1withRSA/PSS",
           "supported_api_levels": "23+"
         },
         {
-          "name": "SHA224WITHDSA",
+          "name": "SHA224withDSA",
           "supported_api_levels": "20+"
         },
         {
-          "name": "SHA224WITHECDSA",
+          "name": "SHA224withECDSA",
           "supported_api_levels": "20+"
         },
         {
-          "name": "SHA224WITHRSA",
+          "name": "SHA224withRSA",
           "supported_api_levels": "20+"
         },
         {
-          "name": "SHA224WITHRSA/PSS",
+          "name": "SHA224withRSA/PSS",
           "supported_api_levels": "23+"
         },
         {
-          "name": "SHA256WITHDSA",
+          "name": "SHA256withDSA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "SHA256WITHECDSA",
+          "name": "SHA256withECDSA",
           "supported_api_levels": "11+"
         },
         {
-          "name": "SHA256WITHRSA",
+          "name": "SHA256withRSA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "SHA256WITHRSA/PSS",
+          "name": "SHA256withRSA/PSS",
           "supported_api_levels": "23+"
         },
         {
-          "name": "SHA384WITHECDSA",
+          "name": "SHA384withECDSA",
           "supported_api_levels": "11+"
         },
         {
-          "name": "SHA384WITHRSA",
+          "name": "SHA384withRSA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "SHA384WITHRSA/PSS",
+          "name": "SHA384withRSA/PSS",
           "supported_api_levels": "23+"
         },
         {
-          "name": "SHA512WITHECDSA",
+          "name": "SHA512withECDSA",
           "supported_api_levels": "11+"
         },
         {
-          "name": "SHA512WITHRSA",
+          "name": "SHA512withRSA",
           "supported_api_levels": "1+"
         },
         {
-          "name": "SHA512WITHRSA/PSS",
+          "name": "SHA512withRSA/PSS",
           "supported_api_levels": "23+"
         }
       ],
@@ -822,5 +1227,5 @@
       "name": "TrustManagerFactory"
     }
   ],
-  "last_updated": "2017-03-14 15:13:50 UTC"
+  "last_updated": "2017-03-21 16:04:30 UTC"
 }
\ No newline at end of file
diff --git a/tools/docs/crypto/format_supported_algorithm_table.py b/tools/docs/crypto/format_supported_algorithm_table.py
index f07f9d9..3b23066 100755
--- a/tools/docs/crypto/format_supported_algorithm_table.py
+++ b/tools/docs/crypto/format_supported_algorithm_table.py
@@ -20,8 +20,10 @@
 reflect the crypto algorithm support shown in the provided data file.
 """
 
-import json
-import sys
+import argparse
+import operator
+
+import crypto_docs
 
 
 def sort_by_name(seq):
@@ -29,40 +31,155 @@
 
 
 def main():
-    if len(sys.argv) < 2:
-        print 'Must supply argument to data file.'
-        sys.exit(1)
-    data = json.load(open(sys.argv[1]))
+    parser = argparse.ArgumentParser(description='Output algorithm support HTML tables')
+    parser.add_argument('--for_javadoc',
+                        action='store_true',
+                        help='If specified, format for inclusion in class documentation')
+    parser.add_argument('file',
+                        help='The JSON file to use for data')
+    args = parser.parse_args()
+
+    output = []
+    data = crypto_docs.load_json(args.file)
     categories = sort_by_name(data['categories'])
-    print '<h2 id="SupportedAlgorithms">Supported Algorithms</h2>'
-    print
-    print '<ul>'
+    output.append('<h2 id="SupportedAlgorithms">Supported Algorithms</h2>')
+    output.append('')
+    output.append('<ul>')
     for category in categories:
-        print ('  <li><a href="#Supported{name}">'
+        output.append('  <li><a href="#Supported{name}">'
                '<code>{name}</code></a></li>'.format(**category))
-    print '</ul>'
+    output.append('</ul>')
     for category in categories:
-        print '''
-<h3 id="Supported{name}">{name}</h3>
-<table>
-  <thead>
-    <th>Algorithm</th>
-    <th>Supported API Levels</th>
-  </thead>
-  <tbody>'''.format(**category)
-        algorithms = sort_by_name(category['algorithms'])
-        for algorithm in algorithms:
-            dep_class = ''
-            if 'deprecated' in algorithm and algorithm['deprecated']:
-                dep_class = ' class="deprecated"'
-            print '''
-    <tr{deprecated_class}>
-      <td>{name}</td>
-      <td>{supported_api_levels}</td>
-    </tr>'''.format(deprecated_class=dep_class, **algorithm)
-        print '''
-  </tbody>
-</table>'''
+        if category['name'] == 'Cipher':
+            # We display ciphers in a four-column table to conserve space and
+            # so that it's more comprehensible.  To do this, we have to
+            # collapse all our ciphers into "equivalence classes" of a sort.
+
+            # First, collect the relevant data for each algorithm into a tuple.
+            # The mode and padding are in lists because we are going to collapse
+            # multiple tuples with those in later steps.
+            algorithms = sort_by_name(category['algorithms'])
+            tuples = []
+            for algorithm in algorithms:
+                name, mode, padding = algorithm['name'].split('/')
+                tuples.append((
+                    name,
+                    [mode],
+                    [padding],
+                    algorithm['supported_api_levels'],
+                    'deprecated' in algorithm and algorithm['deprecated']))
+            # Sort the tuples by all items except padding, then collapse
+            # items with all non-padding values the same (which will always be
+            # neighboring items) into a single item.
+            tuples.sort(key=operator.itemgetter(0, 1, 3, 4))
+            i = 0
+            while i < len(tuples) - 1:
+                if (tuples[i][0] == tuples[i+1][0]
+                    and tuples[i][1] == tuples[i+1][1]
+                    and tuples[i][3] == tuples[i+1][3]
+                    and tuples[i][4] == tuples[i+1][4]):
+                    tuples[i][2].extend(tuples[i+1][2])
+                    del tuples[i+1]
+                else:
+                    i += 1
+            # Do the same thing as above, but with modes.
+            tuples.sort(key=operator.itemgetter(0, 2, 3, 4))
+            i = 0
+            while i < len(tuples) - 1:
+                if (tuples[i][0] == tuples[i+1][0]
+                    and tuples[i][2] == tuples[i+1][2]
+                    and tuples[i][3] == tuples[i+1][3]
+                    and tuples[i][4] == tuples[i+1][4]):
+                    tuples[i][1].extend(tuples[i+1][1])
+                    del tuples[i+1]
+                else:
+                    i += 1
+            # Display the table with rowspans for those entries where all the
+            # items have the same algorithm, mode, etc
+            output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
+            output.append('<table>')
+            output.append('  <thead>')
+            output.append('    <tr>')
+            output.append('      <th>Algorithm</th>')
+            output.append('      <th>Modes</th>')
+            output.append('      <th>Paddings</th>')
+            output.append('      <th>Supported API Levels</th>')
+            output.append('    </tr>')
+            output.append('  </thead>')
+            output.append('  <tbody>')
+            tuples.sort(key=operator.itemgetter(0, 4, 1, 2, 3))
+            i = 0
+            cur_deprecated = None
+            cur_algorithm = None
+            cur_mode = None
+            while i < len(tuples):
+                row = tuples[i]
+                if row[4] != cur_deprecated:
+                    cur_deprecated = row[4]
+                    cur_algorithm = None
+                    cur_mode = None
+                if cur_deprecated:
+                    output.append('    <tr class="deprecated">')
+                else:
+                    output.append('    <tr>')
+                if row[0] != cur_algorithm:
+                    cur_algorithm = row[0]
+                    cur_mode = None
+                    j = i + 1
+                    while (j < len(tuples)
+                           and tuples[j][4] == cur_deprecated
+                           and tuples[j][0] == cur_algorithm):
+                        j += 1
+                    rowspan = j - i
+                    if rowspan > 1:
+                        output.append('      <td rowspan="%d">%s</td>' % (rowspan, cur_algorithm))
+                    else:
+                        output.append('      <td>%s</td>' % cur_algorithm)
+                if row[1] != cur_mode:
+                    cur_mode = row[1]
+                    j = i + 1
+                    while (j < len(tuples)
+                           and tuples[j][4] == cur_deprecated
+                           and tuples[j][0] == cur_algorithm
+                           and tuples[j][1] == cur_mode):
+                        j += 1
+                    rowspan = j - i
+                    modestring = '<br>'.join(cur_mode)
+                    if rowspan > 1:
+                        output.append('      <td rowspan="%d">%s</td>' % (rowspan, modestring))
+                    else:
+                        output.append('      <td>%s</td>' % modestring)
+                output.append('      <td>%s</td>' % '<br>'.join(row[2]))
+                output.append('      <td>%s</td>' % row[3])
+                output.append('    </tr>')
+                i += 1
+            output.append('  </tbody>')
+            output.append('</table>')
+        else:
+            output.append('<h3 id="Supported{name}">{name}</h3>'.format(**category))
+            output.append('<table>')
+            output.append('  <thead>')
+            output.append('    <tr>')
+            output.append('      <th>Algorithm</th>')
+            output.append('      <th>Supported API Levels</th>')
+            output.append('    </tr>')
+            output.append('  </thead>')
+            output.append('  <tbody>')
+            algorithms = sort_by_name(category['algorithms'])
+            for algorithm in algorithms:
+                if 'deprecated' in algorithm and algorithm['deprecated']:
+                    output.append('    <tr class="deprecated">')
+                else:
+                    output.append('    <tr>')
+                output.append('      <td>{name}</td>'.format(**algorithm))
+                output.append('      <td>{supported_api_levels}</td>'.format(**algorithm))
+                output.append('    </tr>')
+            output.append('  </tbody>')
+            output.append('</table>')
+    if args.for_javadoc:
+        for i in range(len(output)):
+            output[i] = ' * ' + output[i]
+    print '\n'.join(output)
 
 
 if __name__ == '__main__':
diff --git a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
index 34aed4b..1cd8646 100644
--- a/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
+++ b/tools/docs/crypto/src/java/libcore/java/security/ListProviders.java
@@ -16,6 +16,7 @@
 
 package libcore.java.security;
 
+import java.security.NoSuchAlgorithmException;
 import java.security.Provider;
 import java.security.Security;
 import java.util.ArrayList;
@@ -25,6 +26,8 @@
 import java.util.List;
 import java.util.Set;
 import java.util.TreeSet;
+import javax.crypto.Cipher;
+import javax.crypto.NoSuchPaddingException;
 
 /**
  * Prints a list of all algorithms provided by security providers.  Intended to be run
@@ -34,15 +37,50 @@
  */
 public class ListProviders {
 
+    private static final boolean SHOW_PROVIDER = false;
+
     // These algorithms were previously provided, but now are aliases for a different
     // algorithm.  For documentation purposes, we want to continue having them show up
     // as supported.
-    private static final Set<String> KNOWN_ALIASES = new HashSet<>(Arrays.asList(new String[]{
+    private static final Set<String> KNOWN_ALIASES = new TreeSet<>(Arrays.asList(new String[]{
             "Alg.Alias.Signature.DSA",
             "Alg.Alias.Signature.DSAwithSHA1",
             "Alg.Alias.Signature.ECDSA",
             "Alg.Alias.Signature.ECDSAwithSHA1",
     }));
+
+    // Ciphers come in algorithm/mode/padding combinations, and not all combinations are explicitly
+    // registered by the providers (sometimes only the base algorithm is registered).  While there
+    // is a mechanism for providers to specify which modes and/or paddings are supported for a
+    // given algorithm, none of our providers use it.  Thus, when a base algorithm is seen, all
+    // combinations of modes and paddings will be tried to see which ones are supported.
+    private static final Set<String> CIPHER_MODES = new TreeSet<>(Arrays.asList(new String[]{
+            "CBC",
+            "CFB",
+            "CTR",
+            "CTS",
+            "ECB",
+            "GCM",
+            "OFB",
+            "NONE",
+    }));
+    private static final Set<String> CIPHER_PADDINGS = new TreeSet<>(Arrays.asList(new String[]{
+            "NoPadding",
+            "OAEPPadding",
+            "OAEPwithSHA-1andMGF1Padding",
+            "OAEPwithSHA-224andMGF1Padding",
+            "OAEPwithSHA-256andMGF1Padding",
+            "OAEPwithSHA-384andMGF1Padding",
+            "OAEPwithSHA-512andMGF1Padding",
+            "PKCS1Padding",
+            "PKCS5Padding",
+            "ISO10126Padding",
+    }));
+
+    private static void print(Provider p, String type, String algorithm) {
+        System.out.println((SHOW_PROVIDER ? p.getName() + ": " : "") + type + " " + algorithm);
+    }
+
     public static void main(String[] argv) {
         System.out.println("BEGIN ALGORITHM LIST");
         for (Provider p : Security.getProviders()) {
@@ -58,12 +96,33 @@
                     });
             services.addAll(p.getServices());
             for (Provider.Service s : services) {
-                System.out.println(s.getType() + " " + s.getAlgorithm());
+                if (s.getType().equals("Cipher") && s.getAlgorithm().startsWith("PBE")) {
+                    // PBE ciphers are a mess and generally don't do anything but delegate
+                    // to the underlying cipher.  We don't want to document them.
+                    continue;
+                }
+                if (s.getType().equals("Cipher") && s.getAlgorithm().indexOf('/') == -1) {
+                    for (String mode : CIPHER_MODES) {
+                        for (String padding : CIPHER_PADDINGS) {
+                            try {
+                                String name = s.getAlgorithm() + "/" + mode + "/" + padding;
+                                Cipher.getInstance(name, p);
+                                print(p, s.getType(), name);
+                            } catch (NoSuchAlgorithmException
+                                    |NoSuchPaddingException
+                                    |IllegalArgumentException e) {
+                                // This combination doesn't work
+                            }
+                        }
+                    }
+                } else {
+                    print(p, s.getType(), s.getAlgorithm());
+                }
             }
             for (String alias : KNOWN_ALIASES) {
                 if (p.containsKey(alias)) {
                     String[] elements = alias.split("\\.");  // Split takes a regex
-                    System.out.println(elements[2] + " " + elements[3]);
+                    print(p, elements[2], elements[3]);
                 }
             }
         }
diff --git a/tools/docs/crypto/update_crypto_support.py b/tools/docs/crypto/update_crypto_support.py
index c8d19df..207e0f4 100755
--- a/tools/docs/crypto/update_crypto_support.py
+++ b/tools/docs/crypto/update_crypto_support.py
@@ -24,12 +24,13 @@
 
 import argparse
 import collections
-import copy
 import datetime
 import json
+import re
 import sys
 
-# TODO(b/35793879): Support more categories
+import crypto_docs
+
 SUPPORTED_CATEGORIES = [
     'AlgorithmParameterGenerator',
     'AlgorithmParameters',
@@ -37,6 +38,7 @@
     'CertPathBuilder',
     'CertPathValidator',
     'CertStore',
+    'Cipher',
     'KeyAgreement',
     'KeyFactory',
     'KeyGenerator',
@@ -61,6 +63,14 @@
     return None
 
 
+def find_by_normalized_name(seq, name):
+    """Returns the first element in seq with the given normalized name."""
+    for item in seq:
+        if normalize_name(item['name']) == name:
+            return item
+    return None
+
+
 def sort_by_name(seq):
     """Returns a copy of the input sequence sorted by name."""
     return sorted(seq, key=lambda x: x['name'])
@@ -73,8 +83,31 @@
     # reverse.  X.509 is the official name of the standard, so use that.
     if name == "X509":
         name = "X.509"
+    # PKCS5PADDING and PKCS7PADDING are the same thing (more accurately, PKCS#5
+    # is a special case of PKCS#7), but providers are inconsistent in their
+    # naming.  Use PKCS5PADDING because that's what our docs have used
+    # historically.
+    if name.endswith("/PKCS7PADDING"):
+        name = name[:-1 * len("/PKCS7PADDING")] + "/PKCS5PADDING"
     return name
 
+
+def fix_name_caps_for_output(name):
+    """Returns a version of the given algorithm name with capitalization fixed."""
+    # It's important that this must only change the capitalization of the
+    # name, not any of its text, otherwise future runs won't be able to
+    # match this name with the name coming from the device.
+
+    # We current make the following capitalization fixes
+    # DESede (not DESEDE)
+    # FOOwithBAR (not FOOWITHBAR or FOOWithBAR)
+    # Hmac (not HMAC)
+    name = re.sub('WITH', 'with', name, flags=re.I)
+    name = re.sub('DESEDE', 'DESede', name, flags=re.I)
+    name = re.sub('HMAC', 'Hmac', name, flags=re.I)
+    return name
+
+
 def get_current_data(f):
     """Returns a map of the algorithms in the given input.
 
@@ -86,12 +119,17 @@
 
     The returned algorithms will have their names normalized.
 
+    Returns:
+      A dict of categories to lists of normalized algorithm names and a
+        dict of normalized algorithm names to original algorithm names.
+
     Raises:
       EOFError: If either the BEGIN or END sentinel lines are not present.
       ValueError: If a line between the BEGIN and END sentinel lines is not
         made up of two identifiers separated by whitespace.
     """
     current_data = collections.defaultdict(list)
+    name_dict = {}
 
     saw_begin = False
     saw_end = False
@@ -107,7 +145,9 @@
         category, algorithm = line.split()
         if category not in SUPPORTED_CATEGORIES:
             continue
-        current_data[category].append(normalize_name(algorithm))
+        normalized_name = normalize_name(algorithm)
+        current_data[category].append(normalized_name)
+        name_dict[normalized_name] = algorithm
 
     if not saw_begin:
         raise EOFError(
@@ -115,10 +155,10 @@
     if not saw_end:
         raise EOFError(
             'Reached the end of input without encountering the end sentinel')
-    return dict(current_data)
+    return dict(current_data), name_dict
 
 
-def update_data(prev_data, current_data, api_level, date):
+def update_data(prev_data, current_data, name_dict, api_level, date):
     """Returns a copy of prev_data, modified to take into account current_data.
 
     Updates the algorithm support metadata structure by starting with the
@@ -143,14 +183,20 @@
         current_category = (
             current_data[category] if category in current_data else [])
         new_category = {'name': category, 'algorithms': []}
-        prev_algorithms = [x['name'] for x in prev_category['algorithms']]
+        prev_algorithms = [normalize_name(x['name']) for x in prev_category['algorithms']]
         alg_union = set(prev_algorithms) | set(current_category)
         for alg in alg_union:
-            new_algorithm = {'name': alg}
+            prev_alg = find_by_normalized_name(prev_category['algorithms'], alg)
+            if alg in name_dict:
+                new_algorithm = {'name': name_dict[alg]}
+            elif prev_alg is not None:
+                new_algorithm = {'name': prev_alg['name']}
+            else:
+                new_algorithm = {'name': alg}
+            new_algorithm['name'] = fix_name_caps_for_output(new_algorithm['name'])
             new_level = None
             if alg in current_category and alg in prev_algorithms:
                 # Both old and new have it, just ensure the API level is right
-                prev_alg = find_by_name(prev_category['algorithms'], alg)
                 if prev_alg['supported_api_levels'].endswith('+'):
                     new_level = prev_alg['supported_api_levels']
                 else:
@@ -159,7 +205,6 @@
             elif alg in prev_algorithms:
                 # Only in the old set, so ensure the API level is marked
                 # as ending
-                prev_alg = find_by_name(prev_category['algorithms'], alg)
                 if prev_alg['supported_api_levels'].endswith('+'):
                     # The algorithm is newly missing, so modify the support
                     # to end at the previous level
@@ -199,20 +244,13 @@
                         help='The JSON file to update')
     args = parser.parse_args()
 
-    f = open(args.file)
-    # JSON doesn't allow comments, but we have some header docs in our file,
-    # so strip comments out before parsing
-    stripped_contents = ''
-    for line in f:
-        if not line.strip().startswith('#'):
-            stripped_contents += line
-    prev_data = json.loads(stripped_contents)
-    f.close()
+    prev_data = crypto_docs.load_json(args.file)
 
-    current_data = get_current_data(sys.stdin)
+    current_data, name_dict = get_current_data(sys.stdin)
 
     new_data = update_data(prev_data,
                            current_data,
+                           name_dict,
                            args.api_level,
                            datetime.datetime.utcnow())
 
diff --git a/tools/docs/crypto/update_crypto_support_test.py b/tools/docs/crypto/update_crypto_support_test.py
index cb8fe87..4fbc210 100755
--- a/tools/docs/crypto/update_crypto_support_test.py
+++ b/tools/docs/crypto/update_crypto_support_test.py
@@ -20,10 +20,11 @@
 import update_crypto_support
 
 
-def do_update_data(prev_data, current_data):
+def do_update_data(prev_data, current_data, name_dict={}):
     return update_crypto_support.update_data(
         prev_data,
         current_data,
+        name_dict,
         72,
         datetime.datetime.utcfromtimestamp(1234567890))
 
@@ -88,8 +89,12 @@
                 OtherThing Mary
                 END ALGORITHM LIST
                 ''')),
-            {'Mac': ['BOB', 'JONES', 'AMY'],
-             'MessageDigest': ['JIM']})
+            ({'Mac': ['BOB', 'JONES', 'AMY'],
+              'MessageDigest': ['JIM']},
+             {'AMY': 'Amy',
+              'BOB': 'Bob',
+              'JONES': 'Jones',
+              'JIM': 'Jim'}))
         self.assertEqual(update_crypto_support.get_current_data(
             StringIO.StringIO(
                 '''
@@ -102,8 +107,12 @@
                 OtherThing Mary
                 END ALGORITHM LIST
                 ''')),
-            {'Mac': ['DUPE', 'JONES', 'AMY', 'DUPE'],
-             'MessageDigest': ['JIM']})
+            ({'Mac': ['DUPE', 'JONES', 'AMY', 'DUPE'],
+              'MessageDigest': ['JIM']},
+             {'AMY': 'Amy',
+              'DUPE': 'Dupe',
+              'JONES': 'Jones',
+              'JIM': 'Jim'}))
         self.assertEqual(update_crypto_support.get_current_data(
             StringIO.StringIO(
                 '''
@@ -117,8 +126,12 @@
                 END ALGORITHM LIST
                 Mac AlsoNotAValue
                 ''')),
-            {'Mac': ['BOB', 'JONES', 'AMY'],
-             'MessageDigest': ['JIM']})
+            ({'Mac': ['BOB', 'JONES', 'AMY'],
+              'MessageDigest': ['JIM']},
+             {'AMY': 'Amy',
+              'BOB': 'Bob',
+              'JONES': 'Jones',
+              'JIM': 'Jim'}))
         self.assertEqual(update_crypto_support.get_current_data(
             StringIO.StringIO(
                 '''
@@ -132,8 +145,12 @@
                 OtherThing Mary
                 END ALGORITHM LIST
                 ''')),
-            {'Mac': ['BOB', 'JONES', 'AMY'],
-             'MessageDigest': ['JIM']})
+            ({'Mac': ['BOB', 'JONES', 'AMY'],
+              'MessageDigest': ['JIM']},
+             {'AMY': 'Amy',
+              'BOB': 'Bob',
+              'JONES': 'Jones',
+              'JIM': 'Jim'}))
         with self.assertRaises(EOFError):
             update_crypto_support.get_current_data(StringIO.StringIO(
                 '''
@@ -342,6 +359,59 @@
                 'api_level': '72',
                 'last_updated': LAST_UPDATED_TEXT})
 
+    def test_update_name_matching(self):
+        self.assertEqual(
+            do_update_data(
+                {'categories': [
+                    {'name': 'MessageDigest',
+                     'algorithms': [
+                         {'name': 'sha-1',
+                          'supported_api_levels': '1+'},
+                         {'name': 'Sha-2',
+                          'supported_api_levels': '1-22',
+                          'deprecated': 'true'},
+                         {'name': 'SHA-3',
+                          'supported_api_levels': '7+'}]}]},
+                {'MessageDigest': ['SHA-1', 'SHA-2', 'SHA-3']},
+                {'SHA-1': 'Sha-1', 'SHA-2': 'Sha-2', 'SHA-3': 'Sha-3'}),
+            {'categories': [
+                {'name': 'MessageDigest',
+                 'algorithms': [
+                     {'name': 'Sha-1',
+                      'supported_api_levels': '1+'},
+                     {'name': 'Sha-2',
+                      'supported_api_levels': '1-22,72+'},
+                     {'name': 'Sha-3',
+                      'supported_api_levels': '7+'}]}],
+                'api_level': '72',
+                'last_updated': LAST_UPDATED_TEXT})
+        self.assertEqual(
+            do_update_data(
+                {'categories': [
+                    {'name': 'MessageDigest',
+                     'algorithms': [
+                         {'name': 'sha-1',
+                          'supported_api_levels': '1+'},
+                         {'name': 'Sha-2',
+                          'supported_api_levels': '1-22',
+                          'deprecated': 'true'},
+                         {'name': 'SHA-3',
+                          'supported_api_levels': '7+'}]}]},
+                {'MessageDigest': ['SHA-1', 'SHA-3']},
+                {'SHA-1': 'Sha-1', 'SHA-3': 'Sha-3'}),
+            {'categories': [
+                {'name': 'MessageDigest',
+                 'algorithms': [
+                     {'name': 'Sha-1',
+                      'supported_api_levels': '1+'},
+                     {'name': 'Sha-2',
+                      'supported_api_levels': '1-22',
+                      'deprecated': 'true'},
+                     {'name': 'Sha-3',
+                      'supported_api_levels': '7+'}]}],
+                'api_level': '72',
+                'last_updated': LAST_UPDATED_TEXT})
+
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tools/upstream/oj_upstream_comparison.py b/tools/upstream/oj_upstream_comparison.py
new file mode 100755
index 0000000..deab5fb
--- /dev/null
+++ b/tools/upstream/oj_upstream_comparison.py
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+#
+# 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.
+
+"""Helps compare openjdk_java_files contents against upstream file contents.
+
+Outputs a tab-separated table comparing each openjdk_java_files entry
+against OpenJDK upstreams. This can help verify updates to later upstreams
+or focus attention towards files that may have been missed in a previous
+update (http://b/36461944) or are otherwise surprising (http://b/36429512).
+
+ - Identifies each file as identical to, different from or missing from
+   each upstream; diffs are not produced.
+ - Optionally, copies all openjdk_java_files from the default upstream
+   (eg. OpenJDK8u121-b13) to a new directory, for easy directory comparison
+   using e.g. kdiff3, which allows inspecting detailed diffs.
+ - The ANDROID_BUILD_TOP environment variable must be set to point to the
+   AOSP root directory (parent of libcore).
+ - Run with -h command line argument to get usage instructions.
+
+To check out upstreams OpenJDK 7u40, 8u60 and 8u121-b13, run:
+
+mkdir openjdk
+cd openjdk
+hg clone http://hg.openjdk.java.net/jdk7u/jdk7u40/ 7u40
+(cd !$ ; sh get_source.sh)
+hg clone http://hg.openjdk.java.net/jdk8u/jdk8u 8u121-b13
+(cd !$ ; hg update -r jdk8u121-b13 && sh get_source.sh)
+hg clone http://hg.openjdk.java.net/jdk8u/jdk8u60/ 8u60
+(cd !$ ; sh get_source.sh)
+
+The newly created openjdk directory is then a suitable argument for the
+--upstream_root parameter.
+"""
+
+import argparse
+import csv
+import filecmp
+import os
+import re
+import shutil
+import sys
+
+def rel_paths_from_makefile(build_top):
+    """Returns the list of relative paths to .java files parsed from openjdk_java_files.mk"""
+    list_file = os.path.join(build_top, "libcore", "openjdk_java_files.mk")
+
+    result = []
+    with open(list_file, "r") as f:
+        for line in f:
+            match = re.match("\s+ojluni/src/main/java/(.+\.java)\s*\\\s*", line)
+            if match:
+                path = match.group(1)
+                # convert / to the appropriate separator (e.g. \ on Windows), just in case
+                path = os.path.normpath(path)
+                result.append(path)
+    return result
+
+def ojluni_path(build_top, rel_path):
+    """The full path of the file at the given rel_path in ojluni"""
+    return os.path.join(build_top, "libcore", "ojluni", "src", "main", "java", rel_path)
+
+def upstream_path(upstream_root, upstream, rel_path):
+    """The full path of the file at the given rel_path in the given upstream"""
+    source_dirs = [
+        "jdk/src/share/classes",
+        "jdk/src/solaris/classes"
+    ]
+    for source_dir in source_dirs:
+        source_dir = os.path.normpath(source_dir)
+        result = os.path.join(upstream_root, upstream, source_dir, rel_path)
+        if os.path.exists(result):
+            return result
+    return None
+
+
+# For files with N and M lines, respectively, this runs in time
+# O(N+M) if the files are identical or O(N*M) if not. This could
+# be improved to O(D*(N+M)) for files with at most D lines
+# difference by only considering array elements within D cells
+# from the diagonal.
+def edit_distance_lines(file_a, file_b):
+    """
+    Computes the line-based edit distance between two text files, i.e.
+    the smallest number of line deletions, additions or replacements
+    that would transform the content of one file into that of the other.
+    """
+    if filecmp.cmp(file_a, file_b, shallow=False):
+        return 0 # files identical
+    with open(file_a) as f:
+        lines_a = f.readlines()
+    with open(file_b) as f:
+        lines_b = f.readlines()
+    prev_cost = range(0, len(lines_b) + 1)
+    for end_a in range(1, len(lines_a) + 1):
+        # For each valid index i, prev_cost[i] is the edit distance between
+        # lines_a[:end_a-1] and lines_b[:i].
+        # We now calculate cur_cost[end_b] as the edit distance between
+        # line_a[:end_a] and lines_b[:end_b]
+        cur_cost = [end_a]
+        for end_b in range(1, len(lines_b) + 1):
+            c = min(
+                cur_cost[-1] + 1, # append line from b
+                prev_cost[end_b] + 1, # append line from a
+                # match or replace line
+                prev_cost[end_b - 1] + (0 if lines_a[end_a - 1] == lines_b[end_b - 1] else 1)
+                )
+            cur_cost.append(c)
+        prev_cost = cur_cost
+    return prev_cost[-1]
+
+def compare_to_upstreams_and_save(out_file, build_top, upstream_root, upstreams, rel_paths, best_only=False):
+    """
+    Prints tab-separated values comparing ojluni files vs. each
+    upstream, for each of the rel_paths, suitable for human
+    analysis in a spreadsheet.
+    This includes whether the corresponding upstream file is
+    missing, identical, or by how many lines it differs, and
+    a guess as to the correct upstream based on minimal line
+    difference (ties broken in favor of upstreams that occur
+    earlier in the list).
+    """
+    writer = csv.writer(out_file, delimiter='\t')
+    writer.writerow(["rel_path", "guessed_upstream"] + upstreams)
+    for rel_path in rel_paths:
+        ojluni_file = ojluni_path(build_top, rel_path)
+        upstream_comparisons = []
+        best_distance = sys.maxint
+        guessed_upstream = ""
+        for upstream in upstreams:
+            upstream_file = upstream_path(upstream_root, upstream, rel_path)
+            if upstream_file is None:
+                upstream_comparison = "missing"
+            else:
+                edit_distance = edit_distance_lines(upstream_file, ojluni_file)
+                if edit_distance == 0:
+                    upstream_comparison = "identical"
+                else:
+                    upstream_comparison = "different (%d lines)" % (edit_distance)
+                if edit_distance < best_distance:
+                    best_distance = edit_distance
+                    guessed_upstream = upstream
+            upstream_comparisons.append(upstream_comparison)
+        writer.writerow([rel_path, guessed_upstream ] + upstream_comparisons)
+
+def copy_files(rel_paths, upstream_root, upstream, output_dir):
+    """Copies files at the given rel_paths from upstream to output_dir"""
+    for rel_path in rel_paths:
+        upstream_file = upstream_path(upstream_root, upstream, rel_path)
+        if upstream_file is not None:
+            out_file = os.path.join(output_dir, rel_path)
+            out_dir = os.path.dirname(out_file)
+            if not os.path.exists(out_dir):
+                os.makedirs(out_dir)
+            shutil.copyfile(upstream_file, out_file)
+
+def main():
+    parser = argparse.ArgumentParser(
+    description="Check openjdk_java_files contents against upstream file contents.")
+    parser.add_argument("--upstream_root",
+        help="Path below where upstream sources are checked out. This should be a "
+            "directory with one child directory for each upstream (select the "
+            "upstreams to compare against via --upstreams).",
+        required=True,)
+    parser.add_argument("--upstreams", 
+        default="8u121-b13,8u60,7u40",
+        help="Comma separated list of subdirectory names of --upstream_root that "
+            "each hold one upstream.")
+    parser.add_argument("--output_dir",
+        help="(optional) path where default upstream sources should be copied to; "
+            "this path must not yet exist and will be created. "
+            "The default upstream is the one that occurs first in --upstreams.")
+    parser.add_argument("--build_top",
+        default=os.environ.get('ANDROID_BUILD_TOP'),
+        help="Path where Android sources are checked out (defaults to $ANDROID_BUILD_TOP).")
+    args = parser.parse_args()
+    if args.output_dir is not None and os.path.exists(args.output_dir):
+        raise Exception("Output dir already exists: " + args.output_dir)
+
+    upstreams = [upstream.strip() for upstream in args.upstreams.split(',')]
+    default_upstream = upstreams[0]
+    for upstream in upstreams:
+        upstream_path = os.path.join(args.upstream_root, upstream)
+        if not os.path.exists(upstream_path):
+            raise Exception("Upstream not found: " + upstream_path)
+
+    rel_paths = rel_paths_from_makefile(args.build_top)
+
+    compare_to_upstreams_and_save(
+        sys.stdout, args.build_top, args.upstream_root, upstreams, rel_paths)
+
+    if args.output_dir is not None:
+        copy_files(rel_paths, args.upstream_root, default_upstream, args.output_dir)
+
+if __name__ == '__main__':
+    main()
diff --git a/tzdata/shared2/Android.mk b/tzdata/shared2/Android.mk
new file mode 100644
index 0000000..634386b
--- /dev/null
+++ b/tzdata/shared2/Android.mk
@@ -0,0 +1,46 @@
+# Copyright (C) 2015 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.
+
+LOCAL_PATH:= $(call my-dir)
+
+# Library of support classes for tzdata updates. Used on-device for handling distros and for
+# testing.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_shared2
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := core-oj core-libart
+LOCAL_NO_STANDARD_LIBRARIES := true
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Library of support classes for tzdata updates. Used on host for host-side tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_shared2-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_JAVA_LIBRARY)
+
+# Tests for tzdata_update2 code
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_shared2-tests
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/test)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_STATIC_JAVA_LIBRARIES := tzdata_shared2 junit
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/DistroException.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroException.java
similarity index 96%
rename from tzdata/update2/src/main/libcore/tzdata/update2/DistroException.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/DistroException.java
index d83e473..d989486 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/DistroException.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroException.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 /**
  * A checked exception used in connection with time zone distro creation / installation.
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/DistroVersion.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroVersion.java
similarity index 95%
rename from tzdata/update2/src/main/libcore/tzdata/update2/DistroVersion.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/DistroVersion.java
index 4848db7..80f37bc 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/DistroVersion.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/DistroVersion.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 import java.nio.charset.StandardCharsets;
 import java.util.Locale;
@@ -63,7 +63,7 @@
      * The length of a well-formed distro version file:
      * {Distro version}|{Rule version}|{Revision}
      */
-    static final int DISTRO_VERSION_FILE_LENGTH = FORMAT_VERSION_STRING_LENGTH + 1
+    public static final int DISTRO_VERSION_FILE_LENGTH = FORMAT_VERSION_STRING_LENGTH + 1
             + RULES_VERSION_LENGTH
             + 1 + REVISION_LENGTH;
 
@@ -152,6 +152,15 @@
     }
 
     @Override
+    public int hashCode() {
+        int result = formatMajorVersion;
+        result = 31 * result + formatMinorVersion;
+        result = 31 * result + rulesVersion.hashCode();
+        result = 31 * result + revision;
+        return result;
+    }
+
+    @Override
     public String toString() {
         return "DistroVersion{" +
                 "formatMajorVersion=" + formatMajorVersion +
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/FileUtils.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/FileUtils.java
similarity index 94%
rename from tzdata/update2/src/main/libcore/tzdata/update2/FileUtils.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/FileUtils.java
index 3d9a73a..39626ac 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/FileUtils.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/FileUtils.java
@@ -13,10 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.LinkedList;
@@ -173,4 +175,14 @@
             return toReturn;
         }
     }
+
+    /**
+     * Creates an empty file.
+     *
+     * @param file the file to create
+     * @throws IOException if the file cannot be created
+     */
+    public static void createEmptyFile(File file) throws IOException {
+        new FileOutputStream(file, false /* append */).close();
+    }
 }
diff --git a/tzdata/shared2/src/main/libcore/tzdata/shared2/StagedDistroOperation.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/StagedDistroOperation.java
new file mode 100644
index 0000000..0492e12
--- /dev/null
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/StagedDistroOperation.java
@@ -0,0 +1,78 @@
+/*
+ * 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.tzdata.shared2;
+
+/**
+ * Information about a staged time zone distro operation.
+ */
+public class StagedDistroOperation {
+
+    private static final StagedDistroOperation UNINSTALL_STAGED =
+            new StagedDistroOperation(true /* isUninstall */, null /* stagedVersion */);
+
+    public final boolean isUninstall;
+    public final DistroVersion distroVersion;
+
+    private StagedDistroOperation(boolean isUninstall, DistroVersion distroVersion) {
+        this.isUninstall = isUninstall;
+        this.distroVersion = distroVersion;
+    }
+
+    public static StagedDistroOperation install(DistroVersion distroVersion) {
+        if (distroVersion == null) {
+            throw new NullPointerException("distroVersion==null");
+        }
+        return new StagedDistroOperation(false /* isUninstall */, distroVersion);
+    }
+
+    public static StagedDistroOperation uninstall() {
+        return UNINSTALL_STAGED;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+
+        StagedDistroOperation that = (StagedDistroOperation) o;
+
+        if (isUninstall != that.isUninstall) {
+            return false;
+        }
+        return distroVersion != null ? distroVersion.equals(that.distroVersion)
+                : that.distroVersion == null;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = (isUninstall ? 1 : 0);
+        result = 31 * result + (distroVersion != null ? distroVersion.hashCode() : 0);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return "StagedDistroOperation{" +
+                "isUninstall=" + isUninstall +
+                ", distroVersion=" + distroVersion +
+                '}';
+    }
+}
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistro.java b/tzdata/shared2/src/main/libcore/tzdata/shared2/TimeZoneDistro.java
similarity index 99%
rename from tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistro.java
rename to tzdata/shared2/src/main/libcore/tzdata/shared2/TimeZoneDistro.java
index 04e3f2a..dd01fb0 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistro.java
+++ b/tzdata/shared2/src/main/libcore/tzdata/shared2/TimeZoneDistro.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/DistroVersionTest.java b/tzdata/shared2/src/test/libcore/tzdata/shared2/DistroVersionTest.java
similarity index 98%
rename from tzdata/update2/src/test/libcore/tzdata/update2/DistroVersionTest.java
rename to tzdata/shared2/src/test/libcore/tzdata/shared2/DistroVersionTest.java
index 79ba9d8..5d3df3f 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/DistroVersionTest.java
+++ b/tzdata/shared2/src/test/libcore/tzdata/shared2/DistroVersionTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 import junit.framework.TestCase;
 
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/FileUtilsTest.java b/tzdata/shared2/src/test/libcore/tzdata/shared2/FileUtilsTest.java
similarity index 91%
rename from tzdata/update2/src/test/libcore/tzdata/update2/FileUtilsTest.java
rename to tzdata/shared2/src/test/libcore/tzdata/shared2/FileUtilsTest.java
index 470d1c1..87e6e6e 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/FileUtilsTest.java
+++ b/tzdata/shared2/src/test/libcore/tzdata/shared2/FileUtilsTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 import junit.framework.TestCase;
 
@@ -253,6 +253,43 @@
         assertTrue(Arrays.equals(contents, exhaustedFileRead));
     }
 
+    public void testCreateEmptyFile() throws Exception {
+        File dir = createTempDir();
+        File file = new File(dir, "one");
+        assertFalse(file.exists());
+        FileUtils.createEmptyFile(file);
+        assertTrue(file.exists());
+        assertEquals(0, file.length());
+    }
+
+    public void testCreateEmptyFile_isDir() throws Exception {
+        File dir = createTempDir();
+        assertTrue(dir.exists());
+        assertTrue(dir.isDirectory());
+
+        try {
+            FileUtils.createEmptyFile(dir);
+        } catch (FileNotFoundException expected) {
+        }
+        assertTrue(dir.exists());
+        assertTrue(dir.isDirectory());
+    }
+
+    public void testCreateEmptyFile_truncatesExisting() throws Exception {
+        File dir = createTempDir();
+        File file = new File(dir, "one");
+
+        try (FileOutputStream fos = new FileOutputStream(file)) {
+            fos.write(new byte[1000]);
+        }
+        assertTrue(file.exists());
+        assertEquals(1000, file.length());
+
+        FileUtils.createEmptyFile(file);
+        assertTrue(file.exists());
+        assertEquals(0, file.length());
+    }
+
     private File createFile(byte[] contents) throws IOException {
         File file = File.createTempFile(getClass().getSimpleName(), ".txt");
         try (FileOutputStream fos = new FileOutputStream(file)) {
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroTest.java b/tzdata/shared2/src/test/libcore/tzdata/shared2/TimeZoneDistroTest.java
similarity index 99%
rename from tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroTest.java
rename to tzdata/shared2/src/test/libcore/tzdata/shared2/TimeZoneDistroTest.java
index dad1cc4..e5b6a17 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroTest.java
+++ b/tzdata/shared2/src/test/libcore/tzdata/shared2/TimeZoneDistroTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package libcore.tzdata.update2;
+package libcore.tzdata.shared2;
 
 import junit.framework.TestCase;
 
diff --git a/tzdata/testing/Android.mk b/tzdata/testing/Android.mk
index f6b9b3c..d86255b 100644
--- a/tzdata/testing/Android.mk
+++ b/tzdata/testing/Android.mk
@@ -25,6 +25,15 @@
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
+# Library of test-support classes for tzdata updates. Shared between CTS and other tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata-testing-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_JAVA_LIBRARY)
+
 # Host version of the above library. For libcore host testing.
 include $(CLEAR_VARS)
 LOCAL_MODULE := tzdata-testing-hostdex
diff --git a/tzdata/tools2/Android.mk b/tzdata/tools2/Android.mk
index 7789700..f91fc6a 100644
--- a/tzdata/tools2/Android.mk
+++ b/tzdata/tools2/Android.mk
@@ -14,14 +14,23 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-# Library of tools classes for tzdata updates. Not required on device, except in tests.
+# Library of tools classes for tzdata updates. Only used in tests.
 include $(CLEAR_VARS)
 LOCAL_MODULE := tzdata_tools2
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
 LOCAL_JAVACFLAGS := -encoding UTF-8
-LOCAL_JAVA_LIBRARIES := core-oj core-libart
+LOCAL_JAVA_LIBRARIES := core-oj core-libart tzdata_shared2
 LOCAL_NO_STANDARD_LIBRARIES := true
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
+
+# Library of tools classes for tzdata updates. Used when generating distros and in host-side tests.
+include $(CLEAR_VARS)
+LOCAL_MODULE := tzdata_tools2-host
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
+LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := tzdata_shared2-host
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+include $(BUILD_HOST_JAVA_LIBRARY)
diff --git a/tzdata/tools2/createTimeZoneDistro.sh b/tzdata/tools2/createTimeZoneDistro.sh
index 7e103e7..dc76c3d 100755
--- a/tzdata/tools2/createTimeZoneDistro.sh
+++ b/tzdata/tools2/createTimeZoneDistro.sh
@@ -5,23 +5,19 @@
 # Usage: ./createTimeZoneDistro.sh <tzupdate.properties file> <output file>
 # See libcore.tzdata.update2.tools.CreateTimeZoneDistro for more information.
 
-TOOLS_DIR=src/main/libcore/tzdata/update2/tools
-UPDATE_DIR=../update2/src/main/libcore/tzdata/update2
-GEN_DIR=./gen
-
 # Fail if anything below fails
 set -e
 
-rm -rf ${GEN_DIR}
-mkdir -p ${GEN_DIR}
+if [[ -z "${ANDROID_BUILD_TOP}" ]]; then
+  echo "Configure your environment with build/envsetup.sh and lunch"
+  exit 1
+fi
 
-javac \
-    ${TOOLS_DIR}/CreateTimeZoneDistro.java \
-    ${TOOLS_DIR}/TimeZoneDistroBuilder.java \
-    ${UPDATE_DIR}/DistroException.java \
-    ${UPDATE_DIR}/DistroVersion.java \
-    ${UPDATE_DIR}/FileUtils.java \
-    ${UPDATE_DIR}/TimeZoneDistro.java \
-    -d ${GEN_DIR}
+cd ${ANDROID_BUILD_TOP}
+make tzdata_tools2-host
 
-java -cp ${GEN_DIR} libcore.tzdata.update2.tools.CreateTimeZoneDistro $@
+TOOLS_LIB=${ANDROID_BUILD_TOP}/out/host/common/obj/JAVA_LIBRARIES/tzdata_tools2-host_intermediates/javalib.jar
+SHARED_LIB=${ANDROID_BUILD_TOP}/out/host/common/obj/JAVA_LIBRARIES/tzdata_shared2-host_intermediates/javalib.jar
+
+cd -
+java -cp ${TOOLS_LIB}:${SHARED_LIB} libcore.tzdata.update2.tools.CreateTimeZoneDistro $@
diff --git a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java
index b2b3fa4..4b70152 100644
--- a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java
+++ b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/CreateTimeZoneDistro.java
@@ -23,8 +23,8 @@
 import java.io.OutputStream;
 import java.io.Reader;
 import java.util.Properties;
-import libcore.tzdata.update2.DistroVersion;
-import libcore.tzdata.update2.TimeZoneDistro;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.TimeZoneDistro;
 
 /**
  * A command-line tool for creating a timezone update distro.
diff --git a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java
index 6577401..4c12e96 100644
--- a/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java
+++ b/tzdata/tools2/src/main/libcore/tzdata/update2/tools/TimeZoneDistroBuilder.java
@@ -21,9 +21,9 @@
 import java.io.IOException;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipOutputStream;
-import libcore.tzdata.update2.DistroException;
-import libcore.tzdata.update2.DistroVersion;
-import libcore.tzdata.update2.TimeZoneDistro;
+import libcore.tzdata.shared2.DistroException;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.TimeZoneDistro;
 
 /**
  * A class for creating a {@link TimeZoneDistro} containing timezone update data. Used in real
diff --git a/tzdata/update2/Android.mk b/tzdata/update2/Android.mk
index 9e32862..0e197ba 100644
--- a/tzdata/update2/Android.mk
+++ b/tzdata/update2/Android.mk
@@ -14,13 +14,13 @@
 
 LOCAL_PATH:= $(call my-dir)
 
-# Library of support classes for tzdata updates. Shared between update generation and
-# on-device code.
+# The classes needed to handle installation of time zone updates.
 include $(CLEAR_VARS)
 LOCAL_MODULE := tzdata_update2
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
 LOCAL_JAVACFLAGS := -encoding UTF-8
+LOCAL_JAVA_LIBRARIES := tzdata_shared2
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
 
@@ -30,6 +30,6 @@
 LOCAL_MODULE_TAGS := optional
 LOCAL_SRC_FILES := $(call all-java-files-under, src/test)
 LOCAL_JAVACFLAGS := -encoding UTF-8
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2 tzdata_tools2 tzdata-testing junit
+LOCAL_STATIC_JAVA_LIBRARIES := tzdata_shared2 tzdata_update2 tzdata_tools2 tzdata-testing junit
 LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
index 1b56ebf..e1ed794 100644
--- a/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
+++ b/tzdata/update2/src/main/libcore/tzdata/update2/TimeZoneDistroInstaller.java
@@ -20,45 +20,67 @@
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import libcore.tzdata.shared2.DistroException;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.FileUtils;
+import libcore.tzdata.shared2.StagedDistroOperation;
+import libcore.tzdata.shared2.TimeZoneDistro;
 import libcore.util.ZoneInfoDB;
 
 /**
  * A distro-validation / extraction class. Separate from the services code that uses it for easier
  * testing. This class is not thread-safe: callers are expected to handle mutual exclusion.
  */
-public final class TimeZoneDistroInstaller {
-    /** {@link #installWithErrorCode(byte[])} result code: Success. */
+public class TimeZoneDistroInstaller {
+    /** {@link #stageInstallWithErrorCode(byte[])} result code: Success. */
     public final static int INSTALL_SUCCESS = 0;
-    /** {@link #installWithErrorCode(byte[])} result code: Distro corrupt. */
+    /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro corrupt. */
     public final static int INSTALL_FAIL_BAD_DISTRO_STRUCTURE = 1;
-    /** {@link #installWithErrorCode(byte[])} result code: Distro version incompatible. */
+    /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro version incompatible. */
     public final static int INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION = 2;
-    /** {@link #installWithErrorCode(byte[])} result code: Distro rules too old for device. */
+    /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro rules too old for device. */
     public final static int INSTALL_FAIL_RULES_TOO_OLD = 3;
-    /** {@link #installWithErrorCode(byte[])} result code: Distro content failed validation. */
+    /** {@link #stageInstallWithErrorCode(byte[])} result code: Distro content failed validation. */
     public final static int INSTALL_FAIL_VALIDATION_ERROR = 4;
 
+    // This constant must match one in system/core/tzdatacheck.cpp.
+    private static final String STAGED_TZ_DATA_DIR_NAME = "staged";
+    // This constant must match one in system/core/tzdatacheck.cpp.
     private static final String CURRENT_TZ_DATA_DIR_NAME = "current";
     private static final String WORKING_DIR_NAME = "working";
     private static final String OLD_TZ_DATA_DIR_NAME = "old";
 
+    /**
+     * The name of the file in the staged directory used to indicate a staged uninstallation.
+     */
+    // This constant must match one in system/core/tzdatacheck.cpp.
+    // VisibleForTesting.
+    public static final String UNINSTALL_TOMBSTONE_FILE_NAME = "STAGED_UNINSTALL_TOMBSTONE";
+
     private final String logTag;
     private final File systemTzDataFile;
-    private final File oldTzDataDir;
+    private final File oldStagedDataDir;
+    private final File stagedTzDataDir;
     private final File currentTzDataDir;
     private final File workingDir;
 
     public TimeZoneDistroInstaller(String logTag, File systemTzDataFile, File installDir) {
         this.logTag = logTag;
         this.systemTzDataFile = systemTzDataFile;
-        oldTzDataDir = new File(installDir, OLD_TZ_DATA_DIR_NAME);
+        oldStagedDataDir = new File(installDir, OLD_TZ_DATA_DIR_NAME);
+        stagedTzDataDir = new File(installDir, STAGED_TZ_DATA_DIR_NAME);
         currentTzDataDir = new File(installDir, CURRENT_TZ_DATA_DIR_NAME);
         workingDir = new File(installDir, WORKING_DIR_NAME);
     }
 
     // VisibleForTesting
-    File getOldTzDataDir() {
-        return oldTzDataDir;
+    File getOldStagedDataDir() {
+        return oldStagedDataDir;
+    }
+
+    // VisibleForTesting
+    File getStagedTzDataDir() {
+        return stagedTzDataDir;
     }
 
     // VisibleForTesting
@@ -72,34 +94,35 @@
     }
 
     /**
-     * Install the supplied content.
+     * Stage an install of the supplied content, to be installed the next time the device boots.
      *
-     * <p>Errors during unpacking or installation will throw an {@link IOException}.
+     * <p>Errors during unpacking or staging will throw an {@link IOException}.
      * If the distro content is invalid this method returns {@code false}.
      * If the installation completed successfully this method returns {@code true}.
      */
     public boolean install(byte[] content) throws IOException {
-        int result = installWithErrorCode(content);
+        int result = stageInstallWithErrorCode(content);
         return result == INSTALL_SUCCESS;
     }
 
     /**
-     * Install the supplied time zone distro.
+     * Stage an install of the supplied content, to be installed the next time the device boots.
      *
-     * <p>Errors during unpacking or installation will throw an {@link IOException}.
+     * <p>Errors during unpacking or staging will throw an {@link IOException}.
      * Returns {@link #INSTALL_SUCCESS} or an error code.
      */
-    public int installWithErrorCode(byte[] content) throws IOException {
-        if (oldTzDataDir.exists()) {
-            FileUtils.deleteRecursive(oldTzDataDir);
+    public int stageInstallWithErrorCode(byte[] content) throws IOException {
+        if (oldStagedDataDir.exists()) {
+            FileUtils.deleteRecursive(oldStagedDataDir);
         }
         if (workingDir.exists()) {
             FileUtils.deleteRecursive(workingDir);
         }
 
         Slog.i(logTag, "Unpacking / verifying time zone update");
-        unpackDistro(content, workingDir);
         try {
+            unpackDistro(content, workingDir);
+
             DistroVersion distroVersion;
             try {
                 distroVersion = readDistroVersion(workingDir);
@@ -147,52 +170,78 @@
             Slog.i(logTag, "Applying time zone update");
             FileUtils.makeDirectoryWorldAccessible(workingDir);
 
-            if (currentTzDataDir.exists()) {
-                Slog.i(logTag, "Moving " + currentTzDataDir + " to " + oldTzDataDir);
-                FileUtils.rename(currentTzDataDir, oldTzDataDir);
+            // Check if there is already a staged install or uninstall and remove it if there is.
+            if (!stagedTzDataDir.exists()) {
+                Slog.i(logTag, "Nothing to unstage at " + stagedTzDataDir);
+            } else {
+                Slog.i(logTag, "Moving " + stagedTzDataDir + " to " + oldStagedDataDir);
+                // Move stagedTzDataDir out of the way in one operation so we can't partially delete
+                // the contents.
+                FileUtils.rename(stagedTzDataDir, oldStagedDataDir);
             }
-            Slog.i(logTag, "Moving " + workingDir + " to " + currentTzDataDir);
-            FileUtils.rename(workingDir, currentTzDataDir);
-            Slog.i(logTag, "Update applied: " + currentTzDataDir + " successfully created");
+
+            // Move the workingDir to be the new staged directory.
+            Slog.i(logTag, "Moving " + workingDir + " to " + stagedTzDataDir);
+            FileUtils.rename(workingDir, stagedTzDataDir);
+            Slog.i(logTag, "Install staged: " + stagedTzDataDir + " successfully created");
             return INSTALL_SUCCESS;
         } finally {
-            deleteBestEffort(oldTzDataDir);
+            deleteBestEffort(oldStagedDataDir);
             deleteBestEffort(workingDir);
         }
     }
 
     /**
-     * Uninstall the current timezone update in /data, returning the device to using data from
-     * /system. Returns {@code true} if uninstallation was successful, {@code false} if there was
-     * nothing installed in /data to uninstall.
+     * Stage an uninstall of the current timezone update in /data which, on reboot, will return the
+     * device to using data from /system. Returns {@code true} if staging the uninstallation was
+     * successful, {@code false} if there was nothing installed in /data to uninstall. If there was
+     * something else staged it will be replaced by this call.
      *
      * <p>Errors encountered during uninstallation will throw an {@link IOException}.
      */
-    public boolean uninstall() throws IOException {
+    public boolean stageUninstall() throws IOException {
         Slog.i(logTag, "Uninstalling time zone update");
 
-        // Make sure we don't have a dir where we're going to move the currently installed data to.
-        if (oldTzDataDir.exists()) {
+        if (oldStagedDataDir.exists()) {
             // If we can't remove this, an exception is thrown and we don't continue.
-            FileUtils.deleteRecursive(oldTzDataDir);
+            FileUtils.deleteRecursive(oldStagedDataDir);
+        }
+        if (workingDir.exists()) {
+            FileUtils.deleteRecursive(workingDir);
         }
 
-        if (!currentTzDataDir.exists()) {
-            Slog.i(logTag, "Nothing to uninstall at " + currentTzDataDir);
-            return false;
+        try {
+            // Check if there is already an install or uninstall staged and remove it.
+            if (!stagedTzDataDir.exists()) {
+                Slog.i(logTag, "Nothing to unstage at " + stagedTzDataDir);
+            } else {
+                Slog.i(logTag, "Moving " + stagedTzDataDir + " to " + oldStagedDataDir);
+                // Move stagedTzDataDir out of the way in one operation so we can't partially delete
+                // the contents.
+                FileUtils.rename(stagedTzDataDir, oldStagedDataDir);
+            }
+
+            // If there's nothing actually installed, there's nothing to uninstall so no need to
+            // stage anything.
+            if (!currentTzDataDir.exists()) {
+                Slog.i(logTag, "Nothing to uninstall at " + currentTzDataDir);
+                return false;
+            }
+
+            // Stage an uninstall in workingDir.
+            FileUtils.ensureDirectoriesExist(workingDir, true /* makeWorldReadable */);
+            FileUtils.createEmptyFile(new File(workingDir, UNINSTALL_TOMBSTONE_FILE_NAME));
+
+            // Move the workingDir to be the new staged directory.
+            Slog.i(logTag, "Moving " + workingDir + " to " + stagedTzDataDir);
+            FileUtils.rename(workingDir, stagedTzDataDir);
+            Slog.i(logTag, "Uninstall staged: " + stagedTzDataDir + " successfully created");
+
+            return true;
+        } finally {
+            deleteBestEffort(oldStagedDataDir);
+            deleteBestEffort(workingDir);
         }
-
-        Slog.i(logTag, "Moving " + currentTzDataDir + " to " + oldTzDataDir);
-        // Move currentTzDataDir out of the way in one operation so we can't partially delete
-        // the contents, which would leave a partial install.
-        FileUtils.rename(currentTzDataDir, oldTzDataDir);
-
-        // Do our best to delete the now uninstalled timezone data.
-        deleteBestEffort(oldTzDataDir);
-
-        Slog.i(logTag, "Time zone update uninstalled.");
-
-        return true;
     }
 
     /**
@@ -210,6 +259,24 @@
     }
 
     /**
+     * Reads information about any currently staged distro operation. Returns {@code null} if there
+     * is no distro operation staged.
+     *
+     * @throws IOException if there was a problem reading data from /data
+     * @throws DistroException if there was a problem with the staged distro format/structure
+     */
+    public StagedDistroOperation getStagedDistroOperation() throws DistroException, IOException {
+        if (!stagedTzDataDir.exists()) {
+            return null;
+        }
+        if (new File(stagedTzDataDir, UNINSTALL_TOMBSTONE_FILE_NAME).exists()) {
+            return StagedDistroOperation.uninstall();
+        } else {
+            return StagedDistroOperation.install(readDistroVersion(stagedTzDataDir));
+        }
+    }
+
+    /**
      * Reads the timezone rules version present in /system. i.e. the version that would be present
      * after a factory reset.
      *
@@ -246,8 +313,7 @@
 
     private DistroVersion readDistroVersion(File distroDir) throws DistroException, IOException {
         Slog.i(logTag, "Reading distro format version");
-        File distroVersionFile =
-                new File(distroDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+        File distroVersionFile = new File(distroDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
         if (!distroVersionFile.exists()) {
             throw new DistroException("No distro version file found: " + distroVersionFile);
         }
diff --git a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java b/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
index 6ae0e56..cf40bf6 100644
--- a/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
+++ b/tzdata/update2/src/test/libcore/tzdata/update2/TimeZoneDistroInstallerTest.java
@@ -30,9 +30,15 @@
 import java.util.zip.ZipOutputStream;
 import libcore.io.IoUtils;
 import libcore.io.Streams;
+import libcore.tzdata.shared2.DistroVersion;
+import libcore.tzdata.shared2.FileUtils;
+import libcore.tzdata.shared2.StagedDistroOperation;
+import libcore.tzdata.shared2.TimeZoneDistro;
 import libcore.tzdata.testing.ZoneInfoTestHelper;
 import libcore.tzdata.update2.tools.TimeZoneDistroBuilder;
 
+import static org.junit.Assert.assertArrayEquals;
+
 /**
  * Tests for {@link TimeZoneDistroInstaller}.
  */
@@ -87,100 +93,110 @@
     }
 
     /** Tests the an update on a device will fail if the /system tzdata file cannot be found. */
-    public void testInstall_badSystemFile() throws Exception {
+    public void testStageInstallWithErrorCode_badSystemFile() throws Exception {
         File doesNotExist = new File(testSystemTzDataDir, "doesNotExist");
         TimeZoneDistroInstaller brokenSystemInstaller = new TimeZoneDistroInstaller(
                 "TimeZoneDistroInstallerTest", doesNotExist, testInstallDir);
         TimeZoneDistro tzData = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
 
         try {
-            brokenSystemInstaller.installWithErrorCode(tzData.getBytes());
+            brokenSystemInstaller.stageInstallWithErrorCode(tzData.getBytes());
             fail();
         } catch (IOException expected) {}
 
-        assertNoContentInstalled();
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
     /** Tests the first successful update on a device */
-    public void testInstall_successfulFirstUpdate() throws Exception {
+    public void testStageInstallWithErrorCode_successfulFirstUpdate() throws Exception {
         TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
 
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertDistroInstalled(distro);
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertInstallDistroStaged(distro);
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests we can install an update the same version as is in /system.
      */
-    public void testInstall_successfulFirstUpdate_sameVersionAsSystem() throws Exception {
+    public void testStageInstallWithErrorCode_successfulFirstUpdate_sameVersionAsSystem()
+            throws Exception {
         TimeZoneDistro distro = createValidTimeZoneDistro(SYSTEM_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertDistroInstalled(distro);
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertInstallDistroStaged(distro);
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests we cannot install an update older than the version in /system.
      */
-    public void testInstall_unsuccessfulFirstUpdate_olderVersionThanSystem() throws Exception {
+    public void testStageInstallWithErrorCode_unsuccessfulFirstUpdate_olderVersionThanSystem()
+            throws Exception {
         TimeZoneDistro distro = createValidTimeZoneDistro(OLDER_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertNoContentInstalled();
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
     /**
-     * Tests an update on a device when there is a prior update already applied.
+     * Tests an update on a device when there is a prior update already staged.
      */
-    public void testInstall_successfulFollowOnUpdate_newerVersion() throws Exception {
+    public void testStageInstallWithErrorCode_successfulFollowOnUpdate_newerVersion()
+            throws Exception {
         TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro1.getBytes()));
-        assertDistroInstalled(distro1);
+                installer.stageInstallWithErrorCode(distro1.getBytes()));
+        assertInstallDistroStaged(distro1);
 
         TimeZoneDistro distro2 = createValidTimeZoneDistro(NEW_RULES_VERSION, 2);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro2.getBytes()));
-        assertDistroInstalled(distro2);
+                installer.stageInstallWithErrorCode(distro2.getBytes()));
+        assertInstallDistroStaged(distro2);
 
         TimeZoneDistro distro3 = createValidTimeZoneDistro(NEWER_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro3.getBytes()));
-        assertDistroInstalled(distro3);
+                installer.stageInstallWithErrorCode(distro3.getBytes()));
+        assertInstallDistroStaged(distro3);
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests an update on a device when there is a prior update already applied, but the follow
      * on update is older than in /system.
      */
-    public void testInstall_unsuccessfulFollowOnUpdate_olderVersion() throws Exception {
+    public void testStageInstallWithErrorCode_unsuccessfulFollowOnUpdate_olderVersion()
+            throws Exception {
         TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 2);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro1.getBytes()));
-        assertDistroInstalled(distro1);
+                installer.stageInstallWithErrorCode(distro1.getBytes()));
+        assertInstallDistroStaged(distro1);
 
         TimeZoneDistro distro2 = createValidTimeZoneDistro(OLDER_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_RULES_TOO_OLD,
-                installer.installWithErrorCode(distro2.getBytes()));
-        assertDistroInstalled(distro1);
+                installer.stageInstallWithErrorCode(distro2.getBytes()));
+        assertInstallDistroStaged(distro1);
+        assertNoInstalledDistro();
     }
 
     /** Tests that a distro with a missing file will not update the content. */
-    public void testInstall_missingTzDataFile() throws Exception {
-        TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+    public void testStageInstallWithErrorCode_missingTzDataFile() throws Exception {
+        TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(installedDistro.getBytes()));
-        assertDistroInstalled(installedDistro);
+                installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+        assertInstallDistroStaged(stagedDistro);
 
         TimeZoneDistro incompleteDistro =
                 createValidTimeZoneDistroBuilder(NEWER_RULES_VERSION, 1)
@@ -188,17 +204,18 @@
                         .buildUnvalidated();
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
-                installer.installWithErrorCode(incompleteDistro.getBytes()));
-        assertDistroInstalled(installedDistro);
+                installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+        assertInstallDistroStaged(stagedDistro);
+        assertNoInstalledDistro();
     }
 
     /** Tests that a distro with a missing file will not update the content. */
-    public void testInstall_missingIcuFile() throws Exception {
-        TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+    public void testStageInstallWithErrorCode_missingIcuFile() throws Exception {
+        TimeZoneDistro stagedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(installedDistro.getBytes()));
-        assertDistroInstalled(installedDistro);
+                installer.stageInstallWithErrorCode(stagedDistro.getBytes()));
+        assertInstallDistroStaged(stagedDistro);
 
         TimeZoneDistro incompleteDistro =
                 createValidTimeZoneDistroBuilder(NEWER_RULES_VERSION, 1)
@@ -206,14 +223,15 @@
                         .buildUnvalidated();
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
-                installer.installWithErrorCode(incompleteDistro.getBytes()));
-        assertDistroInstalled(installedDistro);
+                installer.stageInstallWithErrorCode(incompleteDistro.getBytes()));
+        assertInstallDistroStaged(stagedDistro);
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests that an update will be unpacked even if there is a partial update from a previous run.
      */
-    public void testInstall_withWorkingDir() throws Exception {
+    public void testStageInstallWithErrorCode_withWorkingDir() throws Exception {
         File workingDir = installer.getWorkingDir();
         assertTrue(workingDir.mkdir());
         createFile(new File(workingDir, "myFile"), new byte[] { 'a' });
@@ -221,42 +239,45 @@
         TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_SUCCESS,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertDistroInstalled(distro);
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertInstallDistroStaged(distro);
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests that a distro without a distro version file will be rejected.
      */
-    public void testInstall_withMissingDistroVersionFile() throws Exception {
+    public void testStageInstallWithErrorCode_withMissingDistroVersionFile() throws Exception {
         // Create a distro without a version file.
         TimeZoneDistro distro = createValidTimeZoneDistroBuilder(NEW_RULES_VERSION, 1)
                 .clearVersionForTests()
                 .buildUnvalidated();
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertNoContentInstalled();
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests that a distro with an newer distro version will be rejected.
      */
-    public void testInstall_withNewerDistroVersion() throws Exception {
+    public void testStageInstallWithErrorCode_withNewerDistroVersion() throws Exception {
         // Create a distro that will appear to be newer than the one currently supported.
         TimeZoneDistro distro = createValidTimeZoneDistroBuilder(NEW_RULES_VERSION, 1)
                 .replaceFormatVersionForTests(2, 1)
                 .buildUnvalidated();
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_FORMAT_VERSION,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertNoContentInstalled();
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests that a distro with a badly formed distro version will be rejected.
      */
-    public void testInstall_withBadlyFormedDistroVersion() throws Exception {
+    public void testStageInstallWithErrorCode_withBadlyFormedDistroVersion() throws Exception {
         // Create a distro that has an invalid major distro version. It should be 3 numeric
         // characters, "." and 3 more numeric characters.
         DistroVersion validDistroVersion = new DistroVersion(1, 1, NEW_RULES_VERSION, 1);
@@ -266,14 +287,15 @@
         TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidFormatVersionBytes);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertNoContentInstalled();
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests that a distro with a badly formed revision will be rejected.
      */
-    public void testInstall_withBadlyFormedRevision() throws Exception {
+    public void testStageInstallWithErrorCode_withBadlyFormedRevision() throws Exception {
         // Create a distro that has an invalid revision. It should be 3 numeric characters.
         DistroVersion validDistroVersion = new DistroVersion(1, 1, NEW_RULES_VERSION, 1);
         byte[] invalidRevisionBytes = validDistroVersion.toBytes();
@@ -282,14 +304,15 @@
         TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidRevisionBytes);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertNoContentInstalled();
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
     /**
      * Tests that a distro with a badly formed rules version will be rejected.
      */
-    public void testInstall_withBadlyFormedRulesVersion() throws Exception {
+    public void testStageInstallWithErrorCode_withBadlyFormedRulesVersion() throws Exception {
         // Create a distro that has an invalid rules version. It should be in the form "2016c".
         DistroVersion validDistroVersion = new DistroVersion(1, 1, NEW_RULES_VERSION, 1);
         byte[] invalidRulesVersionBytes = validDistroVersion.toBytes();
@@ -298,38 +321,124 @@
         TimeZoneDistro distro = createTimeZoneDistroWithVersionBytes(invalidRulesVersionBytes);
         assertEquals(
                 TimeZoneDistroInstaller.INSTALL_FAIL_BAD_DISTRO_STRUCTURE,
-                installer.installWithErrorCode(distro.getBytes()));
-        assertNoContentInstalled();
+                installer.stageInstallWithErrorCode(distro.getBytes()));
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
-    public void testUninstall_noExistingDataDistro() throws Exception {
-        assertFalse(installer.uninstall());
-        assertNoContentInstalled();
+    public void testStageUninstall_noExistingDistro() throws Exception {
+        // To stage an uninstall, there would need to be installed rules.
+        assertFalse(installer.stageUninstall());
+
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
     }
 
-    public void testUninstall_existingDataDistro() throws Exception {
-        File currentDataDir = installer.getCurrentTzDataDir();
-        assertTrue(currentDataDir.mkdir());
+    public void testStageUninstall_existingStagedDataDistro() throws Exception {
+        // To stage an uninstall, we need to have some installed rules.
+        TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+        simulateInstalledDistro(installedDistro);
 
-        assertTrue(installer.uninstall());
-        assertNoContentInstalled();
+        File stagedDataDir = installer.getStagedTzDataDir();
+        assertTrue(stagedDataDir.mkdir());
+
+        assertTrue(installer.stageUninstall());
+        assertDistroUninstallStaged();
+        assertInstalledDistro(installedDistro);
     }
 
-    public void testUninstall_oldDirsAlreadyExists() throws Exception {
-        File oldTzDataDir = installer.getOldTzDataDir();
-        assertTrue(oldTzDataDir.mkdir());
+    public void testStageUninstall_oldDirsAlreadyExists() throws Exception {
+        // To stage an uninstall, we need to have some installed rules.
+        TimeZoneDistro installedDistro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+        simulateInstalledDistro(installedDistro);
 
-        File currentDataDir = installer.getCurrentTzDataDir();
-        assertTrue(currentDataDir.mkdir());
+        File oldStagedDataDir = installer.getOldStagedDataDir();
+        assertTrue(oldStagedDataDir.mkdir());
 
-        assertTrue(installer.uninstall());
-        assertNoContentInstalled();
+        File workingDir = installer.getWorkingDir();
+        assertTrue(workingDir.mkdir());
+
+        assertTrue(installer.stageUninstall());
+
+        assertDistroUninstallStaged();
+        assertFalse(workingDir.exists());
+        assertFalse(oldStagedDataDir.exists());
+        assertInstalledDistro(installedDistro);
     }
 
     public void testGetSystemRulesVersion() throws Exception {
         assertEquals(SYSTEM_RULES_VERSION, installer.getSystemRulesVersion());
     }
 
+    public void testGetInstalledDistroVersion() throws Exception {
+        // Check result when nothing installed.
+        assertNull(installer.getInstalledDistroVersion());
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
+
+        // Now simulate there being an existing install active.
+        TimeZoneDistro distro = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+        simulateInstalledDistro(distro);
+        assertInstalledDistro(distro);
+
+        // Check result when something installed.
+        assertEquals(distro.getDistroVersion(), installer.getInstalledDistroVersion());
+        assertNoDistroOperationStaged();
+        assertInstalledDistro(distro);
+    }
+
+    public void testGetStagedDistroOperation() throws Exception {
+        TimeZoneDistro distro1 = createValidTimeZoneDistro(NEW_RULES_VERSION, 1);
+        TimeZoneDistro distro2 = createValidTimeZoneDistro(NEWER_RULES_VERSION, 1);
+
+        // Check result when nothing staged.
+        assertNull(installer.getStagedDistroOperation());
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
+
+        // Check result after unsuccessfully staging an uninstall.
+        // Can't stage an uninstall without an installed distro.
+        assertFalse(installer.stageUninstall());
+        assertNull(installer.getStagedDistroOperation());
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
+
+        // Check result after staging an install.
+        assertTrue(installer.install(distro1.getBytes()));
+        StagedDistroOperation expectedStagedInstall =
+                StagedDistroOperation.install(distro1.getDistroVersion());
+        assertEquals(expectedStagedInstall, installer.getStagedDistroOperation());
+        assertInstallDistroStaged(distro1);
+        assertNoInstalledDistro();
+
+        // Check result after unsuccessfully staging an uninstall (but after removing a staged
+        // install). Can't stage an uninstall without an installed distro.
+        assertFalse(installer.stageUninstall());
+        assertNull(installer.getStagedDistroOperation());
+        assertNoDistroOperationStaged();
+        assertNoInstalledDistro();
+
+        // Now simulate there being an existing install active.
+        simulateInstalledDistro(distro1);
+        assertInstalledDistro(distro1);
+
+        // Check state after successfully staging an uninstall.
+        assertTrue(installer.stageUninstall());
+        StagedDistroOperation expectedStagedUninstall = StagedDistroOperation.uninstall();
+        assertEquals(expectedStagedUninstall, installer.getStagedDistroOperation());
+        assertDistroUninstallStaged();
+        assertInstalledDistro(distro1);
+
+        // Check state after successfully staging an install.
+        assertEquals(TimeZoneDistroInstaller.INSTALL_SUCCESS,
+                installer.stageInstallWithErrorCode(distro2.getBytes()));
+        StagedDistroOperation expectedStagedInstall2 =
+                StagedDistroOperation.install(distro2.getDistroVersion());
+        assertEquals(expectedStagedInstall2, installer.getStagedDistroOperation());
+        assertInstallDistroStaged(distro2);
+        assertInstalledDistro(distro1);
+    }
+
     private static TimeZoneDistro createValidTimeZoneDistro(
             String rulesVersion, int revision) throws Exception {
         return createValidTimeZoneDistroBuilder(rulesVersion, revision).build();
@@ -351,24 +460,27 @@
                 .setIcuData(icuData);
     }
 
-    private void assertDistroInstalled(TimeZoneDistro expectedDistro) throws Exception {
+    private void assertInstallDistroStaged(TimeZoneDistro expectedDistro) throws Exception {
         assertTrue(testInstallDir.exists());
 
-        File currentTzDataDir = installer.getCurrentTzDataDir();
-        assertTrue(currentTzDataDir.exists());
+        File stagedTzDataDir = installer.getStagedTzDataDir();
+        assertTrue(stagedTzDataDir.exists());
 
         File distroVersionFile =
-                new File(currentTzDataDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+                new File(stagedTzDataDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
         assertTrue(distroVersionFile.exists());
 
-        File bionicFile = new File(currentTzDataDir, TimeZoneDistro.TZDATA_FILE_NAME);
+        File bionicFile = new File(stagedTzDataDir, TimeZoneDistro.TZDATA_FILE_NAME);
         assertTrue(bionicFile.exists());
 
-        File icuFile = new File(currentTzDataDir, TimeZoneDistro.ICU_DATA_FILE_NAME);
+        File icuFile = new File(stagedTzDataDir, TimeZoneDistro.ICU_DATA_FILE_NAME);
         assertTrue(icuFile.exists());
 
-        // Assert getInstalledDistroVersion() is reporting correctly.
-        assertEquals(expectedDistro.getDistroVersion(), installer.getInstalledDistroVersion());
+        // Assert getStagedDistroState() is reporting correctly.
+        StagedDistroOperation stagedDistroOperation = installer.getStagedDistroOperation();
+        assertNotNull(stagedDistroOperation);
+        assertFalse(stagedDistroOperation.isUninstall);
+        assertEquals(expectedDistro.getDistroVersion(), stagedDistroOperation.distroVersion);
 
         try (ZipInputStream zis = new ZipInputStream(
                 new ByteArrayInputStream(expectedDistro.getBytes()))) {
@@ -398,23 +510,64 @@
             throws Exception {
         byte[] actualBytes = IoUtils.readFileAsByteArray(actual.getPath());
         byte[] expectedBytes = Streams.readFullyNoClose(expected);
-        assertTrue(Arrays.equals(expectedBytes, actualBytes));
+        assertArrayEquals(expectedBytes, actualBytes);
     }
 
-    private void assertNoContentInstalled() throws Exception {
-        assertNull(installer.getInstalledDistroVersion());
+    private void assertNoDistroOperationStaged() throws Exception {
+        assertNull(installer.getStagedDistroOperation());
 
-        File currentTzDataDir = installer.getCurrentTzDataDir();
-        assertFalse(currentTzDataDir.exists());
+        File stagedTzDataDir = installer.getStagedTzDataDir();
+        assertFalse(stagedTzDataDir.exists());
 
         // Also check no working directories are left lying around.
         File workingDir = installer.getWorkingDir();
         assertFalse(workingDir.exists());
 
-        File oldDataDir = installer.getOldTzDataDir();
+        File oldDataDir = installer.getOldStagedDataDir();
         assertFalse(oldDataDir.exists());
     }
 
+    private void assertDistroUninstallStaged() throws Exception {
+        assertEquals(StagedDistroOperation.uninstall(), installer.getStagedDistroOperation());
+
+        File stagedTzDataDir = installer.getStagedTzDataDir();
+        assertTrue(stagedTzDataDir.exists());
+        assertTrue(stagedTzDataDir.isDirectory());
+
+        File uninstallTombstone =
+                new File(stagedTzDataDir, TimeZoneDistroInstaller.UNINSTALL_TOMBSTONE_FILE_NAME);
+        assertTrue(uninstallTombstone.exists());
+        assertTrue(uninstallTombstone.isFile());
+
+        // Also check no working directories are left lying around.
+        File workingDir = installer.getWorkingDir();
+        assertFalse(workingDir.exists());
+
+        File oldDataDir = installer.getOldStagedDataDir();
+        assertFalse(oldDataDir.exists());
+    }
+
+    private void simulateInstalledDistro(TimeZoneDistro timeZoneDistro) throws Exception {
+        File currentTzDataDir = installer.getCurrentTzDataDir();
+        assertFalse(currentTzDataDir.exists());
+        assertTrue(currentTzDataDir.mkdir());
+        timeZoneDistro.extractTo(currentTzDataDir);
+    }
+
+    private void assertNoInstalledDistro() {
+        assertFalse(installer.getCurrentTzDataDir().exists());
+    }
+
+    private void assertInstalledDistro(TimeZoneDistro timeZoneDistro) throws Exception {
+        File currentTzDataDir = installer.getCurrentTzDataDir();
+        assertTrue(currentTzDataDir.exists());
+        File versionFile = new File(currentTzDataDir, TimeZoneDistro.DISTRO_VERSION_FILE_NAME);
+        assertTrue(versionFile.exists());
+        byte[] expectedVersionBytes = timeZoneDistro.getDistroVersion().toBytes();
+        byte[] actualVersionBytes = FileUtils.readBytes(versionFile, expectedVersionBytes.length);
+        assertArrayEquals(expectedVersionBytes, actualVersionBytes);
+    }
+
     private static byte[] createTzData(String rulesVersion) {
         return new ZoneInfoTestHelper.TzDataBuilder()
                 .initializeToValid()
diff --git a/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java b/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java
index 2348e43..2800037 100644
--- a/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java
+++ b/tzdata/update_test_app/src/libcore/tzdata/update_test_app/installupdatetestapp/MainActivity.java
@@ -39,6 +39,8 @@
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
+import libcore.icu.ICU;
+import libcore.util.ZoneInfoDB;
 
 public class MainActivity extends Activity implements View.OnClickListener {
 
@@ -67,6 +69,12 @@
         requiredHashEditText = (EditText) findViewById(R.id.required_hash);
         logView = (TextView) findViewById(R.id.log);
         executor = Executors.newFixedThreadPool(1);
+        logString("Active libcore version: "
+                + ZoneInfoDB.getInstance().getVersion());
+        logString("Active icu4c version: "
+                + ICU.getTZDataVersion());
+        logString("Active icu4j version: "
+                + android.icu.util.TimeZone.getTZDataVersion());
     }
 
     @Override
@@ -147,9 +155,12 @@
 
     private void logString(String value) {
         logView.append(new Date() + " " + value + "\n");
-        int scrollAmount =
-                logView.getLayout().getLineTop(logView.getLineCount()) - logView.getHeight();
-        logView.scrollTo(0, scrollAmount);
+        android.text.Layout layout = logView.getLayout();
+        if (layout != null) {
+            int scrollAmount =
+                    layout.getLineTop(logView.getLineCount()) - logView.getHeight();
+            logView.scrollTo(0, scrollAmount);
+        }
     }
 
     private static String exceptionToString(Exception e) {