Update java.util.jar to openJdk8u60

Attributes.java
- header change
- Use of generics
- Updated documentation links
- Deprecated:
 EXTENSION_INSTALLATION, IMPLEMENTATION_VENDOR_ID, IMPLEMENTATION_URL

JarEntry.java
- header change
- Updated javadoc

JarFile.java:
- Entry enumerator moved to seperate static inner class
- Streams implementation
- Non-crucial META-INF/* (not *.SF|*.DSA|*.RSA|*.EC|MANIFEST.MF) files are not
passed to JarVerifier in .intializeVerifier() call. Otherwise we could signal
the end of META-INF parsing (due to changes in JarVerifier).
- Refactoring of hasClassPathAttribute, divided into
many methods
- Android-changed: Commented out isKnownNotToHaveSpecialAttributes()
method that doesn't make sense on android

JarOutputStream.java
- Header change
- Replaced a use of "& 0xff" with a cleaner conversion to unsigned int

JarVerifier.java
- Use of generics
- beginEntry explicitly omits META-INF manifest and index signature
check (So they can be passed to beginEntry without side-effects)
- beginEntry process properly non-crucial META-INF/ entries (not
*.SF|*.DSA|*.RSA|*.EC|MANIFEST.MF) and checks their signatures
(added a test for that)
- Change from "Enhance signed jar verification": .entryNames
treats .findMatchingSigners(c) null result as empty array
(probably a bug fix).

Manifest.java
- Use of generics
- Replaced a use of "& 0xff" with a cleaner conversion to unsigned int

Pack200.java
- Copyright update
- javadoc formating changes
- addPropertyChangeListener & removePropertyChangeListener gained empty default
implementation and deprecated

SignatureFileVerifier.java:
- uncommented isSigningRelated (requried by JarFile)

Test: CtsLibcoreTestCases
Change-Id: I56c59fac628c97a8b7c6967a43c0e23c8b068120
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
index 958d9bc..3b914cb 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarFileTest.java
@@ -36,6 +36,7 @@
 import java.security.cert.Certificate;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
+import java.util.ArrayList;
 import java.util.Enumeration;
 import java.util.List;
 import java.util.Vector;
@@ -1124,4 +1125,45 @@
             }
         }
     }
+
+    /**
+     * java.util.jar.JarFile#stream()
+     */
+    public void test_stream() throws Exception {
+        /*
+         * Note only (and all of) the following should be contained in the file
+         * META-INF/ META-INF/MANIFEST.MF Blah.txt  foo/ foo/bar/ foo/bar/A.class
+         */
+        Support_Resources.copyFile(resources, null, jarName);
+        JarFile jarFile = new JarFile(new File(resources, jarName));
+
+        final List<String> names = new ArrayList<>();
+        jarFile.stream().forEach((ZipEntry entry) -> names.add(entry.getName()));
+        assertEquals(Arrays.asList("META-INF/", "META-INF/MANIFEST.MF", "Blah.txt", "foo/", "foo/bar/",
+                                   "foo/bar/A.class"), names);
+        jarFile.close();
+    }
+
+
+    /**
+     * hyts_metainf.jar contains an additional entry in META-INF (META-INF/bad_checksum.txt),
+     * that has been altered since jar signing - we expect to detect a mismatching digest.
+     */
+    public void test_metainf_verification() throws Exception {
+        String jarFilename = "hyts_metainf.jar";
+        Support_Resources.copyFile(resources, null, jarFilename);
+        try (JarFile jarFile = new JarFile(new File(resources, jarFilename))) {
+
+            JarEntry jre = new JarEntry("META-INF/bad_checksum.txt");
+            InputStream in = jarFile.getInputStream(jre);
+
+            byte[] buffer = new byte[1024];
+            try {
+                while (in.available() > 0) {
+                    in.read(buffer);
+                }
+                fail("SecurityException expected");
+            } catch (SecurityException expected) {}
+        }
+    }
 }
diff --git a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java
index 9d4224a..bd66bbe 100644
--- a/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java
+++ b/harmony-tests/src/test/java/org/apache/harmony/tests/java/util/jar/JarInputStreamTest.java
@@ -403,4 +403,35 @@
             // expected
         }
     }
+
+    /**
+     * hyts_metainf.jar contains an additional entry in META-INF (META-INF/bad_checksum.txt),
+     * that has been altered since jar signing - we expect to detect a mismatching digest.
+     */
+    public void test_metainf_verification() throws Exception {
+        String jarFilename = "hyts_metainf.jar";
+        File resources = Support_Resources.createTempFolder();
+        Support_Resources.copyFile(resources, null, jarFilename);
+        InputStream is = Support_Resources.getStream(jarFilename);
+
+        try (JarInputStream jis = new JarInputStream(is, true)) {
+            JarEntry je = jis.getNextJarEntry();
+            je = jis.getNextJarEntry();
+            je = jis.getNextJarEntry();
+            je = jis.getNextJarEntry();
+
+            if (!je.getName().equals("META-INF/bad_checksum.txt")) {
+                fail("Expected META-INF/bad_checksum.txt as a 4th entry, got:" + je.getName());
+            }
+            byte[] buffer = new byte[1024];
+            int length = 0;
+            try {
+                while (length >= 0) {
+                    length = jis.read(buffer);
+                }
+                fail("SecurityException expected");
+            } catch (SecurityException expected) {}
+        }
+    }
+
 }
diff --git a/ojluni/src/main/java/java/util/jar/Attributes.java b/ojluni/src/main/java/java/util/jar/Attributes.java
index 04b6ff7..9193542 100644
--- a/ojluni/src/main/java/java/util/jar/Attributes.java
+++ b/ojluni/src/main/java/java/util/jar/Attributes.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * 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
@@ -72,7 +72,7 @@
      * @param size the initial number of attributes
      */
     public Attributes(int size) {
-        map = new HashMap(size);
+        map = new HashMap<>(size);
     }
 
     /**
@@ -82,7 +82,7 @@
      * @param attr the specified Attributes
      */
     public Attributes(Attributes attr) {
-        map = new HashMap(attr);
+        map = new HashMap<>(attr);
     }
 
 
@@ -297,9 +297,9 @@
      * XXX Need to handle UTF8 values and break up lines longer than 72 bytes
      */
      void write(DataOutputStream os) throws IOException {
-        Iterator it = entrySet().iterator();
+        Iterator<Map.Entry<Object, Object>> it = entrySet().iterator();
         while (it.hasNext()) {
-            Map.Entry e = (Map.Entry)it.next();
+            Map.Entry<Object, Object> e = it.next();
             StringBuffer buffer = new StringBuffer(
                                         ((Name)e.getKey()).toString());
             buffer.append(": ");
@@ -341,9 +341,9 @@
 
         // write out all attributes except for the version
         // we wrote out earlier
-        Iterator it = entrySet().iterator();
+        Iterator<Map.Entry<Object, Object>> it = entrySet().iterator();
         while (it.hasNext()) {
-            Map.Entry e = (Map.Entry)it.next();
+            Map.Entry<Object, Object> e = it.next();
             String name = ((Name)e.getKey()).toString();
             if ((version != null) && ! (name.equalsIgnoreCase(vername))) {
 
@@ -500,7 +500,7 @@
          */
         public boolean equals(Object o) {
             if (o instanceof Name) {
-                Comparator c = ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER;
+                Comparator<String> c = ASCIICaseInsensitiveComparator.CASE_INSENSITIVE_ORDER;
                 return c.compare(name, ((Name)o).name) == 0;
             } else {
                 return false;
@@ -551,8 +551,8 @@
          * <code>Name</code> object for <code>Class-Path</code>
          * manifest attribute. Bundled extensions can use this attribute
          * to find other JAR files containing needed classes.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/spec.html#bundled">
-         *      Extensions Specification</a>
+         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#classpath">
+         *      JAR file specification</a>
          */
         public static final Name CLASS_PATH = new Name("Class-Path");
 
@@ -568,8 +568,8 @@
         /**
          * <code>Name</code> object for <code>Sealed</code> manifest attribute
          * used for sealing.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/spec.html#sealing">
-         *      Extension Sealing</a>
+         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/jar/jar.html#sealing">
+         *      Package Sealing</a>
          */
         public static final Name SEALED = new Name("Sealed");
 
@@ -592,9 +592,12 @@
         /**
          * <code>Name</code> object for <code>Extension-Name</code> manifest attribute
          * used for declaring dependencies on installed extensions.
+         * @deprecated Extension mechanism will be removed in a future release.
+         *             Use class path instead.
          * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/spec.html#dependency">
          *      Installed extension dependency</a>
          */
+        @Deprecated
         public static final Name EXTENSION_INSTALLATION = new Name("Extension-Installation");
 
         /**
@@ -624,17 +627,23 @@
         /**
          * <code>Name</code> object for <code>Implementation-Vendor-Id</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
-         *      Java Product Versioning Specification</a>
+         * @deprecated Extension mechanism will be removed in a future release.
+         *             Use class path instead.
+         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/versioning.html#applet">
+         *      Optional Package Versioning</a>
          */
+        @Deprecated
         public static final Name IMPLEMENTATION_VENDOR_ID = new Name("Implementation-Vendor-Id");
 
        /**
-         * <code>Name</code> object for <code>Implementation-Vendor-URL</code>
+         * <code>Name</code> object for <code>Implementation-URL</code>
          * manifest attribute used for package versioning.
-         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/versioning/spec/versioning2.html#wp90779">
-         *      Java Product Versioning Specification</a>
+         * @deprecated Extension mechanism will be removed in a future release.
+         *             Use class path instead.
+         * @see <a href="{@docRoot}openjdk-redirect.html?v=8&path=/technotes/guides/extensions/versioning.html#applet">
+         *      Optional Package Versioning</a>
          */
+        @Deprecated
         public static final Name IMPLEMENTATION_URL = new Name("Implementation-URL");
 
         /**
diff --git a/ojluni/src/main/java/java/util/jar/JarEntry.java b/ojluni/src/main/java/java/util/jar/JarEntry.java
index 0b49446..b0e6841 100644
--- a/ojluni/src/main/java/java/util/jar/JarEntry.java
+++ b/ojluni/src/main/java/java/util/jar/JarEntry.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
@@ -81,6 +81,7 @@
      *
      * @return the <code>Manifest</code> <code>Attributes</code> for this
      * entry, or <code>null</code> if none
+     * @throws IOException  if an I/O error has occurred
      */
     public Attributes getAttributes() throws IOException {
         return attr;
diff --git a/ojluni/src/main/java/java/util/jar/JarFile.java b/ojluni/src/main/java/java/util/jar/JarFile.java
index 68a6d85..cf8acd8 100644
--- a/ojluni/src/main/java/java/util/jar/JarFile.java
+++ b/ojluni/src/main/java/java/util/jar/JarFile.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * 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
@@ -29,6 +29,8 @@
 import java.io.*;
 import java.lang.ref.SoftReference;
 import java.util.*;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
 import java.util.zip.*;
 import java.security.CodeSigner;
 import java.security.cert.Certificate;
@@ -36,6 +38,7 @@
 import sun.misc.IOUtils;
 import sun.security.action.GetPropertyAction;
 import sun.security.util.ManifestEntryVerifier;
+import sun.security.util.SignatureFileVerifier;
 
 /**
  * The <code>JarFile</code> class is used to read the contents of a jar file
@@ -49,6 +52,13 @@
  * or method in this class will cause a {@link NullPointerException} to be
  * thrown.
  *
+ * If the verify flag is on when opening a signed jar file, the content of the
+ * file is verified against its signature embedded inside the file. Please note
+ * that the verification process does not include validating the signer's
+ * certificate. A caller should inspect the return value of
+ * {@link JarEntry#getCodeSigners()} to further determine if the signature
+ * can be trusted.
+ *
  * @author  David Connelly
  * @see     Manifest
  * @see     java.util.zip.ZipFile
@@ -63,8 +73,11 @@
     private JarVerifier jv;
     private boolean jvInitialized;
     private boolean verify;
-    private boolean computedHasClassPathAttribute;
+
+    // indicates if Class-Path attribute present (only valid if hasCheckedSpecialAttributes true)
     private boolean hasClassPathAttribute;
+    // true if manifest checked for special attributes
+    private volatile boolean hasCheckedSpecialAttributes;
 
     /**
      * The JAR manifest file name.
@@ -155,6 +168,7 @@
      *
      * @throws IllegalStateException
      *         may be thrown if the jar file has been closed
+     * @throws IOException  if an I/O error has occurred
      */
     public Manifest getManifest() throws IOException {
         return getManifestFromReference();
@@ -221,20 +235,42 @@
         return null;
     }
 
+    private class JarEntryIterator implements Enumeration<JarEntry>,
+            Iterator<JarEntry>
+    {
+        final Enumeration<? extends ZipEntry> e = JarFile.super.entries();
+
+        public boolean hasNext() {
+            return e.hasMoreElements();
+        }
+
+        public JarEntry next() {
+            ZipEntry ze = e.nextElement();
+            return new JarFileEntry(ze);
+        }
+
+        public boolean hasMoreElements() {
+            return hasNext();
+        }
+
+        public JarEntry nextElement() {
+            return next();
+        }
+    }
+
     /**
      * Returns an enumeration of the zip file entries.
      */
     public Enumeration<JarEntry> entries() {
-        final Enumeration enum_ = super.entries();
-        return new Enumeration<JarEntry>() {
-            public boolean hasMoreElements() {
-                return enum_.hasMoreElements();
-            }
-            public JarFileEntry nextElement() {
-                ZipEntry ze = (ZipEntry)enum_.nextElement();
-                return new JarFileEntry(ze);
-            }
-        };
+        return new JarEntryIterator();
+    }
+
+    @Override
+    public Stream<JarEntry> stream() {
+        return StreamSupport.stream(Spliterators.spliterator(
+                new JarEntryIterator(), size(),
+                Spliterator.ORDERED | Spliterator.DISTINCT |
+                        Spliterator.IMMUTABLE | Spliterator.NONNULL), false);
     }
 
     private class JarFileEntry extends JarEntry {
@@ -320,11 +356,13 @@
             String[] names = getMetaInfEntryNames();
             if (names != null) {
                 for (int i = 0; i < names.length; i++) {
-                    JarEntry e = getJarEntry(names[i]);
-                    if (e == null) {
-                        throw new JarException("corrupted jar file");
-                    }
-                    if (!e.isDirectory()) {
+                    String uname = names[i].toUpperCase(Locale.ENGLISH);
+                    if (MANIFEST_NAME.equals(uname)
+                            || SignatureFileVerifier.isBlockOrSF(uname)) {
+                        JarEntry e = getJarEntry(names[i]);
+                        if (e == null) {
+                            throw new JarException("corrupted jar file");
+                        }
                         if (mev == null) {
                             mev = new ManifestEntryVerifier
                                 (getManifestFromReference());
@@ -418,27 +456,27 @@
             jv);
     }
 
-    // Statics for hand-coded Boyer-Moore search in hasClassPathAttribute()
+    // Statics for hand-coded Boyer-Moore search
+    private static final char[] CLASSPATH_CHARS = {'c','l','a','s','s','-','p','a','t','h'};
     // The bad character shift for "class-path"
-    private static int[] lastOcc;
+    private static final int[] CLASSPATH_LASTOCC;
     // The good suffix shift for "class-path"
-    private static int[] optoSft;
-    // Initialize the shift arrays to search for "class-path"
-    private static char[] src = {'c','l','a','s','s','-','p','a','t','h'};
+    private static final int[] CLASSPATH_OPTOSFT;
+
     static {
-        lastOcc = new int[128];
-        optoSft = new int[10];
-        lastOcc[(int)'c']=1;
-        lastOcc[(int)'l']=2;
-        lastOcc[(int)'s']=5;
-        lastOcc[(int)'-']=6;
-        lastOcc[(int)'p']=7;
-        lastOcc[(int)'a']=8;
-        lastOcc[(int)'t']=9;
-        lastOcc[(int)'h']=10;
+        CLASSPATH_LASTOCC = new int[128];
+        CLASSPATH_OPTOSFT = new int[10];
+        CLASSPATH_LASTOCC[(int)'c'] = 1;
+        CLASSPATH_LASTOCC[(int)'l'] = 2;
+        CLASSPATH_LASTOCC[(int)'s'] = 5;
+        CLASSPATH_LASTOCC[(int)'-'] = 6;
+        CLASSPATH_LASTOCC[(int)'p'] = 7;
+        CLASSPATH_LASTOCC[(int)'a'] = 8;
+        CLASSPATH_LASTOCC[(int)'t'] = 9;
+        CLASSPATH_LASTOCC[(int)'h'] = 10;
         for (int i=0; i<9; i++)
-            optoSft[i]=10;
-        optoSft[9]=1;
+            CLASSPATH_OPTOSFT[i] = 10;
+        CLASSPATH_OPTOSFT[9]=1;
     }
 
     private synchronized JarEntry getManEntry() {
@@ -463,47 +501,64 @@
         return manEntry;
     }
 
-    // Returns true iff this jar file has a manifest with a class path
-    // attribute. Returns false if there is no manifest or the manifest
-    // does not contain a "Class-Path" attribute. Currently exported to
-    // core libraries via sun.misc.SharedSecrets.
     /**
+     * Returns {@code true} iff this JAR file has a manifest with the
+     * Class-Path attribute
      * @hide
      */
     public boolean hasClassPathAttribute() throws IOException {
-        if (computedHasClassPathAttribute) {
-            return hasClassPathAttribute;
-        }
-
-        hasClassPathAttribute = false;
-        if (!isKnownToNotHaveClassPathAttribute()) {
-            JarEntry manEntry = getManEntry();
-            if (manEntry != null) {
-                byte[] b = getBytes(manEntry);
-                int last = b.length - src.length;
-                int i = 0;
-                next:
-                while (i<=last) {
-                    for (int j=9; j>=0; j--) {
-                        char c = (char) b[i+j];
-                        c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c;
-                        if (c != src[j]) {
-                            i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]);
-                            continue next;
-                        }
-                    }
-                    hasClassPathAttribute = true;
-                    break;
-                }
-            }
-        }
-        computedHasClassPathAttribute = true;
+        checkForSpecialAttributes();
         return hasClassPathAttribute;
     }
 
-    private static String javaHome;
-    private static String[] jarNames;
-    private boolean isKnownToNotHaveClassPathAttribute() {
+    /**
+     * Returns true if the pattern {@code src} is found in {@code b}.
+     * The {@code lastOcc} and {@code optoSft} arrays are the precomputed
+     * bad character and good suffix shifts.
+     */
+    private boolean match(char[] src, byte[] b, int[] lastOcc, int[] optoSft) {
+        int len = src.length;
+        int last = b.length - len;
+        int i = 0;
+        next:
+        while (i<=last) {
+            for (int j=(len-1); j>=0; j--) {
+                char c = (char) b[i+j];
+                c = (((c-'A')|('Z'-c)) >= 0) ? (char)(c + 32) : c;
+                if (c != src[j]) {
+                    i += Math.max(j + 1 - lastOcc[c&0x7F], optoSft[j]);
+                    continue next;
+                 }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * On first invocation, check if the JAR file has the Class-Path
+     * attribute. A no-op on subsequent calls.
+     */
+    private void checkForSpecialAttributes() throws IOException {
+        if (hasCheckedSpecialAttributes) return;
+        // Android-changed: Doesn't make sense on android:
+        //if (!isKnownNotToHaveSpecialAttributes()) {
+        {
+            JarEntry manEntry = getManEntry();
+            if (manEntry != null) {
+                byte[] b = getBytes(manEntry);
+                if (match(CLASSPATH_CHARS, b, CLASSPATH_LASTOCC, CLASSPATH_OPTOSFT))
+                    hasClassPathAttribute = true;
+            }
+        }
+        hasCheckedSpecialAttributes = true;
+    }
+
+
+    // Android-changed: Doesn't make sense on android:
+    /*private static String javaHome;
+    private static volatile String[] jarNames;
+    private boolean isKnownNotToHaveSpecialAttributes() {
         // Optimize away even scanning of manifest for jar files we
         // deliver which don't have a class-path attribute. If one of
         // these jars is changed to include such an attribute this code
@@ -513,19 +568,20 @@
                 new GetPropertyAction("java.home"));
         }
         if (jarNames == null) {
-            String[] names = new String[10];
+            String[] names = new String[11];
             String fileSep = File.separator;
             int i = 0;
             names[i++] = fileSep + "rt.jar";
-            names[i++] = fileSep + "sunrsasign.jar";
             names[i++] = fileSep + "jsse.jar";
             names[i++] = fileSep + "jce.jar";
             names[i++] = fileSep + "charsets.jar";
             names[i++] = fileSep + "dnsns.jar";
-            names[i++] = fileSep + "ldapsec.jar";
+            names[i++] = fileSep + "zipfs.jar";
             names[i++] = fileSep + "localedata.jar";
+            names[i++] = fileSep = "cldrdata.jar";
             names[i++] = fileSep + "sunjce_provider.jar";
             names[i++] = fileSep + "sunpkcs11.jar";
+            names[i++] = fileSep + "sunec.jar";
             jarNames = names;
         }
 
@@ -540,7 +596,7 @@
             }
         }
         return false;
-    }
+    }*/
 
     JarEntry newEntry(ZipEntry ze) {
         return new JarFileEntry(ze);
diff --git a/ojluni/src/main/java/java/util/jar/JarOutputStream.java b/ojluni/src/main/java/java/util/jar/JarOutputStream.java
index 843b16a..3694277 100644
--- a/ojluni/src/main/java/java/util/jar/JarOutputStream.java
+++ b/ojluni/src/main/java/java/util/jar/JarOutputStream.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
@@ -135,7 +135,7 @@
      * The bytes are assumed to be in Intel (little-endian) byte order.
      */
     private static int get16(byte[] b, int off) {
-        return (b[off] & 0xff) | ((b[off+1] & 0xff) << 8);
+        return Byte.toUnsignedInt(b[off]) | ( Byte.toUnsignedInt(b[off+1]) << 8);
     }
 
     /*
diff --git a/ojluni/src/main/java/java/util/jar/JarVerifier.java b/ojluni/src/main/java/java/util/jar/JarVerifier.java
index c95df11..a868802 100644
--- a/ojluni/src/main/java/java/util/jar/JarVerifier.java
+++ b/ojluni/src/main/java/java/util/jar/JarVerifier.java
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2014 The Android Open Source Project
- * 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
@@ -33,6 +33,7 @@
 import java.security.cert.CertificateException;
 import java.util.zip.ZipEntry;
 
+import sun.misc.JarIndex;
 import sun.security.util.ManifestDigester;
 import sun.security.util.ManifestEntryVerifier;
 import sun.security.util.SignatureFileVerifier;
@@ -49,21 +50,21 @@
 
     /* a table mapping names to code signers, for jar entries that have
        had their actual hashes verified */
-    private Hashtable verifiedSigners;
+    private Hashtable<String, CodeSigner[]> verifiedSigners;
 
     /* a table mapping names to code signers, for jar entries that have
        passed the .SF/.DSA/.EC -> MANIFEST check */
-    private Hashtable sigFileSigners;
+    private Hashtable<String, CodeSigner[]> sigFileSigners;
 
     /* a hash table to hold .SF bytes */
-    private Hashtable sigFileData;
+    private Hashtable<String, byte[]> sigFileData;
 
     /** "queue" of pending PKCS7 blocks that we couldn't parse
      *  until we parsed the .SF file */
-    private ArrayList pendingBlocks;
+    private ArrayList<SignatureFileVerifier> pendingBlocks;
 
     /* cache of CodeSigner objects */
-    private ArrayList signerCache;
+    private ArrayList<CodeSigner[]> signerCache;
 
     /* Are we parsing a block? */
     private boolean parsingBlockOrSF = false;
@@ -91,16 +92,16 @@
     private Object csdomain = new Object();
 
     /** collect -DIGEST-MANIFEST values for blacklist */
-    private List manifestDigests;
+    private List<Object> manifestDigests;
 
     public JarVerifier(byte rawBytes[]) {
         manifestRawBytes = rawBytes;
-        sigFileSigners = new Hashtable();
-        verifiedSigners = new Hashtable();
-        sigFileData = new Hashtable(11);
-        pendingBlocks = new ArrayList();
+        sigFileSigners = new Hashtable<>();
+        verifiedSigners = new Hashtable<>();
+        sigFileData = new Hashtable<>(11);
+        pendingBlocks = new ArrayList<>();
         baos = new ByteArrayOutputStream();
-        manifestDigests = new ArrayList();
+        manifestDigests = new ArrayList<>();
     }
 
     /**
@@ -140,13 +141,22 @@
                     return;
                 }
 
+                if (uname.equals(JarFile.MANIFEST_NAME) ||
+                        uname.equals(JarIndex.INDEX_NAME)) {
+                    return;
+                }
+
                 if (SignatureFileVerifier.isBlockOrSF(uname)) {
                     /* We parse only DSA, RSA or EC PKCS7 blocks. */
                     parsingBlockOrSF = true;
                     baos.reset();
                     mev.setEntry(null, je);
+                    return;
                 }
-                return;
+
+                // If a META-INF entry is not MF or block or SF, they should
+                // be normal entries. According to 2 above, no more block or
+                // SF will appear. Let's doneWithMeta.
             }
         }
 
@@ -170,7 +180,9 @@
             name = name.substring(1);
 
         // only set the jev object for entries that have a signature
-        if (sigFileSigners.get(name) != null) {
+        // (either verified or not)
+        if (sigFileSigners.get(name) != null ||
+                verifiedSigners.get(name) != null) {
             mev.setEntry(name, je);
             return;
         }
@@ -249,10 +261,9 @@
                     sigFileData.put(key, bytes);
                     // check pending blocks, we can now process
                     // anyone waiting for this .SF file
-                    Iterator it = pendingBlocks.iterator();
+                    Iterator<SignatureFileVerifier> it = pendingBlocks.iterator();
                     while (it.hasNext()) {
-                        SignatureFileVerifier sfv =
-                            (SignatureFileVerifier) it.next();
+                        SignatureFileVerifier sfv = it.next();
                         if (sfv.needSignatureFile(key)) {
                             if (debug != null) {
                                 debug.println(
@@ -271,7 +282,7 @@
                 String key = uname.substring(0, uname.lastIndexOf("."));
 
                 if (signerCache == null)
-                    signerCache = new ArrayList();
+                    signerCache = new ArrayList<>();
 
                 if (manDig == null) {
                     synchronized(manifestRawBytes) {
@@ -288,7 +299,7 @@
 
                 if (sfv.needSignatureFileBytes()) {
                     // see if we have already parsed an external .SF file
-                    byte[] bytes = (byte[]) sigFileData.get(key);
+                    byte[] bytes = sigFileData.get(key);
 
                     if (bytes == null) {
                         // put this block on queue for later processing
@@ -327,7 +338,7 @@
      * the given file in the jar.
      * @deprecated Deprecated.
      */
-    @Deprecated // Android-changed added "Deprecated."
+    @Deprecated
     public java.security.cert.Certificate[] getCerts(String name)
     {
         return mapSignersToCertArray(getCodeSigners(name));
@@ -345,7 +356,7 @@
      */
     public CodeSigner[] getCodeSigners(String name)
     {
-        return (CodeSigner[])verifiedSigners.get(name);
+        return verifiedSigners.get(name);
     }
 
     public CodeSigner[] getCodeSigners(JarFile jar, JarEntry entry)
@@ -378,15 +389,14 @@
         CodeSigner[] signers) {
 
         if (signers != null) {
-            ArrayList certChains = new ArrayList();
+            ArrayList<java.security.cert.Certificate> certChains = new ArrayList<>();
             for (int i = 0; i < signers.length; i++) {
                 certChains.addAll(
                     signers[i].getSignerCertPath().getCertificates());
             }
 
             // Convert into a Certificate[]
-            return (java.security.cert.Certificate[])
-                certChains.toArray(
+            return certChains.toArray(
                     new java.security.cert.Certificate[certChains.size()]);
         }
         return null;
@@ -420,8 +430,8 @@
         // MANIFEST.MF is always treated as signed and verified,
         // move its signers from sigFileSigners to verifiedSigners.
         if (sigFileSigners.containsKey(JarFile.MANIFEST_NAME)) {
-            verifiedSigners.put(JarFile.MANIFEST_NAME,
-                    sigFileSigners.remove(JarFile.MANIFEST_NAME));
+            CodeSigner[] codeSigners = sigFileSigners.remove(JarFile.MANIFEST_NAME);
+            verifiedSigners.put(JarFile.MANIFEST_NAME, codeSigners);
         }
     }
 
@@ -515,10 +525,10 @@
 
     // Extended JavaUtilJarAccess CodeSource API Support
 
-    private Map urlToCodeSourceMap = new HashMap();
-    private Map signerToCodeSource = new HashMap();
+    private Map<URL, Map<CodeSigner[], CodeSource>> urlToCodeSourceMap = new HashMap<>();
+    private Map<CodeSigner[], CodeSource> signerToCodeSource = new HashMap<>();
     private URL lastURL;
-    private Map lastURLMap;
+    private Map<CodeSigner[], CodeSource> lastURLMap;
 
     /*
      * Create a unique mapping from codeSigner cache entries to CodeSource.
@@ -526,19 +536,19 @@
      * and shared JAR file although in practice there will be a single URL in use.
      */
     private synchronized CodeSource mapSignersToCodeSource(URL url, CodeSigner[] signers) {
-        Map map;
+        Map<CodeSigner[], CodeSource> map;
         if (url == lastURL) {
             map = lastURLMap;
         } else {
-            map = (Map) urlToCodeSourceMap.get(url);
+            map = urlToCodeSourceMap.get(url);
             if (map == null) {
-                map = new HashMap();
+                map = new HashMap<>();
                 urlToCodeSourceMap.put(url, map);
             }
             lastURLMap = map;
             lastURL = url;
         }
-        CodeSource cs = (CodeSource) map.get(signers);
+        CodeSource cs = map.get(signers);
         if (cs == null) {
             cs = new VerifierCodeSource(csdomain, url, signers);
             signerToCodeSource.put(signers, cs);
@@ -546,16 +556,16 @@
         return cs;
     }
 
-    private CodeSource[] mapSignersToCodeSources(URL url, List signers, boolean unsigned) {
-        List sources = new ArrayList();
+    private CodeSource[] mapSignersToCodeSources(URL url, List<CodeSigner[]> signers, boolean unsigned) {
+        List<CodeSource> sources = new ArrayList<>();
 
         for (int i = 0; i < signers.size(); i++) {
-            sources.add(mapSignersToCodeSource(url, (CodeSigner[]) signers.get(i)));
+            sources.add(mapSignersToCodeSource(url, signers.get(i)));
         }
         if (unsigned) {
             sources.add(mapSignersToCodeSource(url, null));
         }
-        return (CodeSource[]) sources.toArray(new CodeSource[sources.size()]);
+        return sources.toArray(new CodeSource[sources.size()]);
     }
     private CodeSigner[] emptySigner = new CodeSigner[0];
 
@@ -575,7 +585,7 @@
          * but this handles a CodeSource of any type, just in case.
          */
         CodeSource[] sources = mapSignersToCodeSources(cs.getLocation(), getJarCodeSigners(), true);
-        List sourceList = new ArrayList();
+        List<CodeSource> sourceList = new ArrayList<>();
         for (int i = 0; i < sources.length; i++) {
             sourceList.add(sources[i]);
         }
@@ -596,6 +606,7 @@
      * signing data that can be compared by object reference identity.
      */
     private static class VerifierCodeSource extends CodeSource {
+        private static final long serialVersionUID = -9047366145967768825L;
 
         URL vlocation;
         CodeSigner[] vsigners;
@@ -663,16 +674,16 @@
             return vcerts;
         }
     }
-    private Map signerMap;
+    private Map<String, CodeSigner[]> signerMap;
 
-    private synchronized Map signerMap() {
+    private synchronized Map<String, CodeSigner[]> signerMap() {
         if (signerMap == null) {
             /*
              * Snapshot signer state so it doesn't change on us. We care
              * only about the asserted signatures. Verification of
              * signature validity happens via the JarEntry apis.
              */
-            signerMap = new HashMap(verifiedSigners.size() + sigFileSigners.size());
+            signerMap = new HashMap<>(verifiedSigners.size() + sigFileSigners.size());
             signerMap.putAll(verifiedSigners);
             signerMap.putAll(sigFileSigners);
         }
@@ -680,15 +691,15 @@
     }
 
     public synchronized Enumeration<String> entryNames(JarFile jar, final CodeSource[] cs) {
-        final Map map = signerMap();
-        final Iterator itor = map.entrySet().iterator();
+        final Map<String, CodeSigner[]> map = signerMap();
+        final Iterator<Map.Entry<String, CodeSigner[]>> itor = map.entrySet().iterator();
         boolean matchUnsigned = false;
 
         /*
          * Grab a single copy of the CodeSigner arrays. Check
          * to see if we can optimize CodeSigner equality test.
          */
-        List req = new ArrayList(cs.length);
+        List<CodeSigner[]> req = new ArrayList<>(cs.length);
         for (int i = 0; i < cs.length; i++) {
             CodeSigner[] match = findMatchingSigners(cs[i]);
             if (match != null) {
@@ -697,11 +708,13 @@
                 } else {
                     matchUnsigned = true;
                 }
+            } else {
+                matchUnsigned = true;
             }
         }
 
-        final List signersReq = req;
-        final Enumeration enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
+        final List<CodeSigner[]> signersReq = req;
+        final Enumeration<String> enum2 = (matchUnsigned) ? unsignedEntryNames(jar) : emptyEnumeration;
 
         return new Enumeration<String>() {
 
@@ -713,14 +726,14 @@
                 }
 
                 while (itor.hasNext()) {
-                    Map.Entry e = (Map.Entry) itor.next();
-                    if (signersReq.contains((CodeSigner[]) e.getValue())) {
-                        name = (String) e.getKey();
+                    Map.Entry<String, CodeSigner[]> e = itor.next();
+                    if (signersReq.contains(e.getValue())) {
+                        name = e.getKey();
                         return true;
                     }
                 }
                 while (enum2.hasMoreElements()) {
-                    name = (String) enum2.nextElement();
+                    name = enum2.nextElement();
                     return true;
                 }
                 return false;
@@ -741,13 +754,13 @@
      * Like entries() but screens out internal JAR mechanism entries
      * and includes signed entries with no ZIP data.
      */
-    public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration e) {
-        final Map map = new HashMap();
+    public Enumeration<JarEntry> entries2(final JarFile jar, Enumeration<? extends ZipEntry> e) {
+        final Map<String, CodeSigner[]> map = new HashMap<>();
         map.putAll(signerMap());
-        final Enumeration enum_ = e;
+        final Enumeration<? extends ZipEntry> enum_ = e;
         return new Enumeration<JarEntry>() {
 
-            Enumeration signers = null;
+            Enumeration<String> signers = null;
             JarEntry entry;
 
             public boolean hasMoreElements() {
@@ -755,7 +768,7 @@
                     return true;
                 }
                 while (enum_.hasMoreElements()) {
-                    ZipEntry ze = (ZipEntry) enum_.nextElement();
+                    ZipEntry ze = enum_.nextElement();
                     if (JarVerifier.isSigningRelated(ze.getName())) {
                         continue;
                     }
@@ -766,7 +779,7 @@
                     signers = Collections.enumeration(map.keySet());
                 }
                 while (signers.hasMoreElements()) {
-                    String name = (String) signers.nextElement();
+                    String name = signers.nextElement();
                     entry = jar.newEntry(new ZipEntry(name));
                     return true;
                 }
@@ -786,7 +799,7 @@
             }
         };
     }
-    private Enumeration emptyEnumeration = new Enumeration<String>() {
+    private Enumeration<String> emptyEnumeration = new Enumeration<String>() {
 
         public boolean hasMoreElements() {
             return false;
@@ -799,28 +812,12 @@
 
     // true if file is part of the signature mechanism itself
     static boolean isSigningRelated(String name) {
-        name = name.toUpperCase(Locale.ENGLISH);
-        if (!name.startsWith("META-INF/")) {
-            return false;
-        }
-        name = name.substring(9);
-        if (name.indexOf('/') != -1) {
-            return false;
-        }
-        if (name.endsWith(".DSA")
-                || name.endsWith(".RSA")
-                || name.endsWith(".SF")
-                || name.endsWith(".EC")
-                || name.startsWith("SIG-")
-                || name.equals("MANIFEST.MF")) {
-            return true;
-        }
-        return false;
+        return SignatureFileVerifier.isSigningRelated(name);
     }
 
     private Enumeration<String> unsignedEntryNames(JarFile jar) {
-        final Map map = signerMap();
-        final Enumeration entries = jar.entries();
+        final Map<String, CodeSigner[]> map = signerMap();
+        final Enumeration<JarEntry> entries = jar.entries();
         return new Enumeration<String>() {
 
             String name;
@@ -835,7 +832,7 @@
                 }
                 while (entries.hasMoreElements()) {
                     String value;
-                    ZipEntry e = (ZipEntry) entries.nextElement();
+                    ZipEntry e = entries.nextElement();
                     value = e.getName();
                     if (e.isDirectory() || isSigningRelated(value)) {
                         continue;
@@ -858,14 +855,14 @@
             }
         };
     }
-    private List jarCodeSigners;
+    private List<CodeSigner[]> jarCodeSigners;
 
-    private synchronized List getJarCodeSigners() {
+    private synchronized List<CodeSigner[]> getJarCodeSigners() {
         CodeSigner[] signers;
         if (jarCodeSigners == null) {
-            HashSet set = new HashSet();
+            HashSet<CodeSigner[]> set = new HashSet<>();
             set.addAll(signerMap().values());
-            jarCodeSigners = new ArrayList();
+            jarCodeSigners = new ArrayList<>();
             jarCodeSigners.addAll(set);
         }
         return jarCodeSigners;
@@ -880,7 +877,7 @@
     public CodeSource getCodeSource(URL url, String name) {
         CodeSigner[] signers;
 
-        signers = (CodeSigner[]) signerMap().get(name);
+        signers = signerMap().get(name);
         return mapSignersToCodeSource(url, signers);
     }
 
@@ -894,7 +891,7 @@
         eagerValidation = eager;
     }
 
-    public synchronized List getManifestDigests() {
+    public synchronized List<Object> getManifestDigests() {
         return Collections.unmodifiableList(manifestDigests);
     }
 
diff --git a/ojluni/src/main/java/java/util/jar/Manifest.java b/ojluni/src/main/java/java/util/jar/Manifest.java
index 2bd4eb0..de842fc 100644
--- a/ojluni/src/main/java/java/util/jar/Manifest.java
+++ b/ojluni/src/main/java/java/util/jar/Manifest.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
@@ -51,7 +51,7 @@
     private Attributes attr = new Attributes();
 
     // manifest entries
-    private Map entries = new HashMap();
+    private Map<String, Attributes> entries = new HashMap<>();
 
     /**
      * Constructs a new, empty Manifest.
@@ -63,7 +63,7 @@
      * Constructs a new Manifest from the specified input stream.
      *
      * @param is the input stream containing manifest data
-     * @throws IOException if an I/O error has occured
+     * @throws IOException if an I/O error has occurred
      */
     public Manifest(InputStream is) throws IOException {
         read(is);
@@ -148,11 +148,11 @@
         // Write out the main attributes for the manifest
         attr.writeMain(dos);
         // Now write out the pre-entry attributes
-        Iterator it = entries.entrySet().iterator();
+        Iterator<Map.Entry<String, Attributes>> it = entries.entrySet().iterator();
         while (it.hasNext()) {
-            Map.Entry e = (Map.Entry)it.next();
+            Map.Entry<String, Attributes> e = it.next();
             StringBuffer buffer = new StringBuffer("Name: ");
-            String value = (String)e.getKey();
+            String value = e.getKey();
             if (value != null) {
                 byte[] vb = value.getBytes("UTF8");
                 value = new String(vb, 0, 0, vb.length);
@@ -161,7 +161,7 @@
             buffer.append("\r\n");
             make72Safe(buffer);
             dos.writeBytes(buffer.toString());
-            ((Attributes)e.getValue()).write(dos);
+            e.getValue().write(dos);
         }
         dos.flush();
     }
@@ -339,7 +339,7 @@
                     return -1;
                 }
             }
-            return buf[pos++] & 0xff;
+            return Byte.toUnsignedInt(buf[pos++]);
         }
 
         public int read(byte[] b, int off, int len) throws IOException {
diff --git a/ojluni/src/main/java/java/util/jar/Pack200.java b/ojluni/src/main/java/java/util/jar/Pack200.java
index cf97590..c58add9 100644
--- a/ojluni/src/main/java/java/util/jar/Pack200.java
+++ b/ojluni/src/main/java/java/util/jar/Pack200.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
@@ -44,8 +44,8 @@
  * The unpacker  engine is used by deployment applications to
  * transform the byte-stream back to JAR format.
  * <p>
- * Here is an example using  packer and unpacker:<p>
- * <blockquote><pre>
+ * Here is an example using  packer and unpacker:
+ * <pre>{@code
  *    import java.util.jar.Pack200;
  *    import java.util.jar.Pack200.*;
  *    ...
@@ -90,7 +90,7 @@
  *    } catch (IOException ioe) {
  *        ioe.printStackTrace();
  *    }
- * </pre></blockquote>
+ * }</pre>
  * <p>
  * A Pack200 file compressed with gzip can be hosted on HTTP/1.1 web servers.
  * The deployment applications can use "Accept-Encoding=pack200-gzip". This
@@ -112,7 +112,7 @@
     // Static methods of the Pack200 class.
     /**
      * Obtain new instance of a class that implements Packer.
-     *
+     * <ul>
      * <li><p>If the system property <tt>java.util.jar.Pack200.Packer</tt>
      * is defined, then the value is taken to be the fully-qualified name
      * of a concrete implementation class, which must implement Packer.
@@ -122,6 +122,7 @@
      * <li><p>If an implementation has not been specified with the system
      * property, then the system-default implementation class is instantiated,
      * and the result is returned.</p></li>
+     * </ul>
      *
      * <p>Note:  The returned object is not guaranteed to operate
      * correctly if multiple threads use it at the same time.
@@ -137,7 +138,7 @@
 
     /**
      * Obtain new instance of a class that implements Unpacker.
-     *
+     * <ul>
      * <li><p>If the system property <tt>java.util.jar.Pack200.Unpacker</tt>
      * is defined, then the value is taken to be the fully-qualified
      * name of a concrete implementation class, which must implement Unpacker.
@@ -147,6 +148,7 @@
      * <li><p>If an implementation has not been specified with the
      * system property, then the system-default implementation class
      * is instantiated, and the result is returned.</p></li>
+     * </ul>
      *
      * <p>Note:  The returned object is not guaranteed to operate
      * correctly if multiple threads use it at the same time.
@@ -350,14 +352,14 @@
          * directory will be passed also.
          * <p>
          * Examples:
-         * <pre><code>
+         * <pre>{@code
          *     Map p = packer.properties();
          *     p.put(PASS_FILE_PFX+0, "mutants/Rogue.class");
          *     p.put(PASS_FILE_PFX+1, "mutants/Wolverine.class");
          *     p.put(PASS_FILE_PFX+2, "mutants/Storm.class");
          *     # Pass all files in an entire directory hierarchy:
          *     p.put(PASS_FILE_PFX+3, "police/");
-         * </pre></code>.
+         * }</pre>
          */
         String PASS_FILE_PFX            = "pack.pass.file.";
 
@@ -378,12 +380,12 @@
          * This is the default value for this property.
          * <p>
          * Examples:
-         * <pre><code>
+         * <pre>{@code
          *     Map p = pack200.getProperties();
          *     p.put(UNKNOWN_ATTRIBUTE, ERROR);
          *     p.put(UNKNOWN_ATTRIBUTE, STRIP);
          *     p.put(UNKNOWN_ATTRIBUTE, PASS);
-         * </pre></code>
+         * }</pre>
          */
         String UNKNOWN_ATTRIBUTE        = "pack.unknown.attribute";
 
@@ -456,12 +458,12 @@
          * The unpacker's progress as a percentage, as periodically
          * updated by the unpacker.
          * Values of 0 - 100 are normal, and -1 indicates a stall.
-         * Observe this property with a {@link PropertyChangeListener}.
+         * Progress can be monitored by polling the value of this
+         * property.
          * <p>
          * At a minimum, the unpacker must set progress to 0
          * at the beginning of a packing operation, and to 100
          * at the end.
-         * @see  #addPropertyChangeListener
          */
         String PROGRESS                 = "pack.progress";
 
@@ -574,21 +576,49 @@
          * Registers a listener for PropertyChange events on the properties map.
          * This is typically used by applications to update a progress bar.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+
          * @see #properties
          * @see #PROGRESS
          * @param listener  An object to be invoked when a property is changed.
+         * @deprecated The dependency on {@code PropertyChangeListener} creates
+         *             a significant impediment to future modularization of the
+         *             Java platform. This method will be removed in a future
+         *             release.
+         *             Applications that need to monitor progress of the packer
+         *             can poll the value of the {@link #PROGRESS PROGRESS}
+         *             property instead.
          */
-        void addPropertyChangeListener(PropertyChangeListener listener) ;
+        @Deprecated
+        default void addPropertyChangeListener(PropertyChangeListener listener) {
+        }
 
         /**
          * Remove a listener for PropertyChange events, added by
          * the {@link #addPropertyChangeListener}.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+         *
          * @see #addPropertyChangeListener
          * @param listener  The PropertyChange listener to be removed.
+         * @deprecated The dependency on {@code PropertyChangeListener} creates
+         *             a significant impediment to future modularization of the
+         *             Java platform. This method will be removed in a future
+         *             release.
          */
-        void removePropertyChangeListener(PropertyChangeListener listener);
-
+        @Deprecated
+        default void removePropertyChangeListener(PropertyChangeListener listener) {
+        }
     }
 
     /**
@@ -640,12 +670,12 @@
          * The unpacker's progress as a percentage, as periodically
          * updated by the unpacker.
          * Values of 0 - 100 are normal, and -1 indicates a stall.
-         * Observe this property with a {@link PropertyChangeListener}.
+         * Progress can be monitored by polling the value of this
+         * property.
          * <p>
          * At a minimum, the unpacker must set progress to 0
          * at the beginning of a packing operation, and to 100
          * at the end.
-         * @see #addPropertyChangeListener
          */
         String PROGRESS         = "unpack.progress";
 
@@ -705,20 +735,49 @@
          * Registers a listener for PropertyChange events on the properties map.
          * This is typically used by applications to update a progress bar.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+         *
          * @see #properties
          * @see #PROGRESS
          * @param listener  An object to be invoked when a property is changed.
+         * @deprecated The dependency on {@code PropertyChangeListener} creates
+         *             a significant impediment to future modularization of the
+         *             Java platform. This method will be removed in a future
+         *             release.
+         *             Applications that need to monitor progress of the
+         *             unpacker can poll the value of the {@link #PROGRESS
+         *             PROGRESS} property instead.
          */
-        void addPropertyChangeListener(PropertyChangeListener listener) ;
+        @Deprecated
+        default void addPropertyChangeListener(PropertyChangeListener listener) {
+        }
 
         /**
          * Remove a listener for PropertyChange events, added by
          * the {@link #addPropertyChangeListener}.
          *
+         * <p> The default implementation of this method does nothing and has
+         * no side-effects.</p>
+         *
+         * <p><b>WARNING:</b> This method is omitted from the interface
+         * declaration in all subset Profiles of Java SE that do not include
+         * the {@code java.beans} package. </p>
+         *
          * @see #addPropertyChangeListener
          * @param listener  The PropertyChange listener to be removed.
+         * @deprecated The dependency on {@code PropertyChangeListener} creates
+         *             a significant impediment to future modularization of the
+         *             Java platform. This method will be removed in a future
+         *             release.
          */
-        void removePropertyChangeListener(PropertyChangeListener listener);
+        @Deprecated
+        default void removePropertyChangeListener(PropertyChangeListener listener) {
+        }
     }
 
     // Private stuff....
@@ -726,13 +785,13 @@
     private static final String PACK_PROVIDER = "java.util.jar.Pack200.Packer";
     private static final String UNPACK_PROVIDER = "java.util.jar.Pack200.Unpacker";
 
-    private static Class packerImpl;
-    private static Class unpackerImpl;
+    private static Class<?> packerImpl;
+    private static Class<?> unpackerImpl;
 
     private synchronized static Object newInstance(String prop) {
         String implName = "(unknown)";
         try {
-            Class impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
+            Class<?> impl = (PACK_PROVIDER.equals(prop))? packerImpl: unpackerImpl;
             if (impl == null) {
                 // The first time, we must decide which class to use.
                 implName = java.security.AccessController.doPrivileged(
diff --git a/ojluni/src/main/java/sun/security/util/SignatureFileVerifier.java b/ojluni/src/main/java/sun/security/util/SignatureFileVerifier.java
index fc379a4..fa0f530 100644
--- a/ojluni/src/main/java/sun/security/util/SignatureFileVerifier.java
+++ b/ojluni/src/main/java/sun/security/util/SignatureFileVerifier.java
@@ -152,7 +152,6 @@
         return false;
     }
 
-    /* BEGIN android-removed
     /**
      * Yet another utility method used by JarVerifier and JarSigner
      * to determine what files are signature related, which includes
@@ -162,7 +161,7 @@
      *
      * @param s file name
      * @return true if the input file name is signature related
-     *
+     */
     public static boolean isSigningRelated(String name) {
         name = name.toUpperCase(Locale.ENGLISH);
         if (!name.startsWith("META-INF/")) {
@@ -198,7 +197,6 @@
         }
         return false;
     }
-     * END android-removed*/
 
     /** get digest from cache */
 
@@ -268,6 +266,7 @@
                                         name);
         }
 
+
         CodeSigner[] newSigners = getSigners(infos, block);
 
         // make sure we have something to do all this work for...
@@ -459,6 +458,7 @@
 
                     if (digest != null) {
                         boolean ok = false;
+
                         byte[] expected =
                             Base64.getMimeDecoder().decode((String)se.getValue());
                         byte[] computed;
diff --git a/support/src/test/java/tests/resources/hyts_metainf.jar b/support/src/test/java/tests/resources/hyts_metainf.jar
new file mode 100644
index 0000000..ff92bed
--- /dev/null
+++ b/support/src/test/java/tests/resources/hyts_metainf.jar
Binary files differ