diff --git a/dalvik/src/main/java/dalvik/system/DexFile.java b/dalvik/src/main/java/dalvik/system/DexFile.java
index 1d33339..c30972b 100644
--- a/dalvik/src/main/java/dalvik/system/DexFile.java
+++ b/dalvik/src/main/java/dalvik/system/DexFile.java
@@ -452,6 +452,15 @@
     public native static boolean isProfileGuidedCompilerFilter(String filter);
 
     /**
+     * Returns the version of the compiler filter that is not based on profiles.
+     * If the input is not a valid filter, or the filter is already not based on
+     * profiles, this returns the input.
+     *
+     * @hide
+     */
+    public native static String getNonProfileGuidedCompilerFilter(String filter);
+
+    /**
      * Returns the VM's opinion of what kind of dexopt is needed to make the
      * apk/jar file up to date, where {@code targetMode} is used to indicate what
      * type of compilation the caller considers up-to-date, and {@code newProfile}
diff --git a/dex/src/main/java/com/android/dex/DexFormat.java b/dex/src/main/java/com/android/dex/DexFormat.java
index 9319bc2..c598eee 100644
--- a/dex/src/main/java/com/android/dex/DexFormat.java
+++ b/dex/src/main/java/com/android/dex/DexFormat.java
@@ -27,7 +27,7 @@
      * API level to target in order to produce the most modern file
      * format
      */
-    public static final int API_CURRENT = 14;
+    public static final int API_CURRENT = 24;
 
     /** API level to target in order to suppress extended opcode usage */
     public static final int API_NO_EXTENDED_OPCODES = 13;
@@ -44,8 +44,14 @@
     /** common suffix for all dex file "magic numbers" */
     public static final String MAGIC_SUFFIX = "\0";
 
-    /** dex file version number for the current format variant */
-    public static final String VERSION_CURRENT = "036";
+    /**
+     * 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 = "037";
 
     /** dex file version number for API level 13 and earlier */
     public static final String VERSION_FOR_API_13 = "035";
@@ -88,7 +94,7 @@
         if (version.equals(VERSION_CURRENT)) {
             return API_CURRENT;
         } else if (version.equals(VERSION_FOR_API_13)) {
-            return 13;
+            return API_NO_EXTENDED_OPCODES;
         }
 
         return -1;
@@ -108,4 +114,9 @@
 
         return MAGIC_PREFIX + version + MAGIC_SUFFIX;
     }
+
+    public static boolean isSupportedDexMagic(byte[] magic) {
+        int api = magicToApi(magic);
+        return api == API_NO_EXTENDED_OPCODES || api == API_CURRENT;
+    }
 }
diff --git a/dex/src/main/java/com/android/dex/TableOfContents.java b/dex/src/main/java/com/android/dex/TableOfContents.java
index d1b87ac..583f195 100644
--- a/dex/src/main/java/com/android/dex/TableOfContents.java
+++ b/dex/src/main/java/com/android/dex/TableOfContents.java
@@ -53,6 +53,7 @@
             debugInfos, annotations, encodedArrays, annotationsDirectories
     };
 
+    public int apiLevel;
     public int checksum;
     public byte[] signature;
     public int fileSize;
@@ -73,12 +74,12 @@
 
     private void readHeader(Dex.Section headerIn) throws UnsupportedEncodingException {
         byte[] magic = headerIn.readByteArray(8);
-        int apiTarget = DexFormat.magicToApi(magic);
 
-        if (apiTarget != DexFormat.API_NO_EXTENDED_OPCODES) {
+        if (!DexFormat.isSupportedDexMagic(magic)) {
             throw new DexException("Unexpected magic: " + Arrays.toString(magic));
         }
 
+        apiLevel = DexFormat.magicToApi(magic);
         checksum = headerIn.readInt();
         signature = headerIn.readByteArray(20);
         fileSize = headerIn.readInt();
@@ -163,8 +164,8 @@
         throw new IllegalArgumentException("No such map item: " + type);
     }
 
-    public void writeHeader(Dex.Section out) throws IOException {
-        out.write(DexFormat.apiToMagic(DexFormat.API_NO_EXTENDED_OPCODES).getBytes("UTF-8"));
+    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);
diff --git a/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java b/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java
index c7de1f6..e82e66d 100644
--- a/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java
+++ b/luni/src/test/java/libcore/java/util/LinkedHashMapTest.java
@@ -18,6 +18,8 @@
 
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
 
 public class LinkedHashMapTest extends junit.framework.TestCase {
 
@@ -205,4 +207,31 @@
         assertEquals("key1", newest.getKey());
         assertEquals("value3", newest.getValue());
     }
+
+    // http://b/27929722
+    // This tests the behaviour is consistent with earlier Android releases.
+    // This behaviour is NOT consistent with the RI. Future Android releases
+    // might change this.
+    public void test_removeEldestEntry() {
+        final AtomicBoolean removeEldestEntryReturnValue = new AtomicBoolean(false);
+        final AtomicInteger removeEldestEntryCallCount = new AtomicInteger(0);
+        LinkedHashMap<String, String> m = new LinkedHashMap<String, String>() {
+            @Override
+            protected boolean removeEldestEntry(Entry eldest) {
+                removeEldestEntryCallCount.incrementAndGet();
+                return removeEldestEntryReturnValue.get();
+            }
+        };
+
+        m.put("foo", "bar");
+        assertEquals(0, removeEldestEntryCallCount.get());
+        m.put("baz", "quux");
+        assertEquals(1, removeEldestEntryCallCount.get());
+
+        removeEldestEntryReturnValue.set(true);
+        m.put("foob", "faab");
+        assertEquals(2, removeEldestEntryCallCount.get());
+        assertEquals(2, m.size());
+        assertFalse(m.containsKey("foo"));
+    }
 }
diff --git a/ojluni/src/main/java/java/io/ObjectOutputStream.java b/ojluni/src/main/java/java/io/ObjectOutputStream.java
index 78678f4..93ccd0c 100755
--- a/ojluni/src/main/java/java/io/ObjectOutputStream.java
+++ b/ojluni/src/main/java/java/io/ObjectOutputStream.java
@@ -210,10 +210,7 @@
      * value of "sun.io.serialization.extendedDebugInfo" property,
      * as true or false for extended information about exception's place
      */
-    private static final boolean extendedDebugInfo =
-        java.security.AccessController.doPrivileged(
-            new sun.security.action.GetBooleanAction(
-                "sun.io.serialization.extendedDebugInfo")).booleanValue();
+    private static final boolean extendedDebugInfo = false;
 
     /**
      * Creates an ObjectOutputStream that writes to the specified OutputStream.
diff --git a/ojluni/src/main/java/java/security/Permission.java b/ojluni/src/main/java/java/security/Permission.java
index 1d8e7f5..9f04ac4 100755
--- a/ojluni/src/main/java/java/security/Permission.java
+++ b/ojluni/src/main/java/java/security/Permission.java
@@ -41,5 +41,5 @@
 
     public abstract String getActions();
 
-    public PermissionCollection newPermissionCollection() { return null; }
+    public PermissionCollection newPermissionCollection() { return new Permissions(); }
 }
diff --git a/ojluni/src/main/java/java/security/Provider.java b/ojluni/src/main/java/java/security/Provider.java
index a1c8cfa..6493f29 100755
--- a/ojluni/src/main/java/java/security/Provider.java
+++ b/ojluni/src/main/java/java/security/Provider.java
@@ -38,8 +38,6 @@
 import java.security.cert.CertStoreParameters;
 import java.util.function.BiConsumer;
 
-import javax.security.auth.login.Configuration;
-
 /**
  * This class represents a "provider" for the
  * Java Security API, where a provider implements some or all parts of
diff --git a/ojluni/src/main/java/java/util/LinkedHashMap.java b/ojluni/src/main/java/java/util/LinkedHashMap.java
index 81b8a7a..b5d8ff2 100755
--- a/ojluni/src/main/java/java/util/LinkedHashMap.java
+++ b/ojluni/src/main/java/java/util/LinkedHashMap.java
@@ -440,13 +440,18 @@
      * removes the eldest entry if appropriate.
      */
     void addEntry(int hash, K key, V value, int bucketIndex) {
-        super.addEntry(hash, key, value, bucketIndex);
+        // Previous Android releases called removeEldestEntry() before actually
+        // inserting a value, but the RI is documented to call it afterwards.
+        // For now, revert to the old Android behaviour.
+        // **** THIS CHANGE WILL BE REVERTED IN A FUTURE ANDROID RELEASE ****
 
         // Remove eldest entry if instructed
         LinkedHashMapEntry<K,V> eldest = header.after;
-        if (removeEldestEntry(eldest)) {
+        if (eldest != header && removeEldestEntry(eldest)) {
             removeEntryForKey(eldest.key);
         }
+
+        super.addEntry(hash, key, value, bucketIndex);
     }
 
     /**
@@ -473,7 +478,12 @@
         size++;
     }
 
-    /**
+    // Intentionally make this not JavaDoc, as the we don't conform to
+    // the behaviour documented here (we call removeEldestEntry before
+    // inserting the new value to be consistent with previous Android
+    // releases).
+    // **** THIS CHANGE WILL BE REVERTED IN A FUTURE ANDROID RELEASE ****
+    /*
      * Returns <tt>true</tt> if this map should remove its eldest entry.
      * This method is invoked by <tt>put</tt> and <tt>putAll</tt> after
      * inserting a new entry into the map.  It provides the implementor
diff --git a/ojluni/src/main/java/javax/security/auth/Policy.java b/ojluni/src/main/java/javax/security/auth/Policy.java
deleted file mode 100755
index 88264b3..0000000
--- a/ojluni/src/main/java/javax/security/auth/Policy.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.security.auth;
-
-import java.security.Security;
-import sun.security.util.Debug;
-
-/**
- * <p> This is an abstract class for representing the system policy for
- * Subject-based authorization.  A subclass implementation
- * of this class provides a means to specify a Subject-based
- * access control <code>Policy</code>.
- *
- * <p> A <code>Policy</code> object can be queried for the set of
- * Permissions granted to code running as a
- * <code>Principal</code> in the following manner:
- *
- * <pre>
- *      policy = Policy.getPolicy();
- *      PermissionCollection perms = policy.getPermissions(subject,
- *                                                      codeSource);
- * </pre>
- *
- * The <code>Policy</code> object consults the local policy and returns
- * and appropriate <code>Permissions</code> object with the
- * Permissions granted to the Principals associated with the
- * provided <i>subject</i>, and granted to the code specified
- * by the provided <i>codeSource</i>.
- *
- * <p> A <code>Policy</code> contains the following information.
- * Note that this example only represents the syntax for the default
- * <code>Policy</code> implementation. Subclass implementations of this class
- * may implement alternative syntaxes and may retrieve the
- * <code>Policy</code> from any source such as files, databases,
- * or servers.
- *
- * <p> Each entry in the <code>Policy</code> is represented as
- * a <b><i>grant</i></b> entry.  Each <b><i>grant</i></b> entry
- * specifies a codebase, code signers, and Principals triplet,
- * as well as the Permissions granted to that triplet.
- *
- * <pre>
- *      grant CodeBase ["URL"], Signedby ["signers"],
- *            Principal [Principal_Class] "Principal_Name" {
- *          Permission Permission_Class ["Target_Name"]
- *                                      [, "Permission_Actions"]
- *                                      [, signedBy "SignerName"];
- *      };
- * </pre>
- *
- * The CodeBase and Signedby components of the triplet name/value pairs
- * are optional.  If they are not present, then any any codebase will match,
- * and any signer (including unsigned code) will match.
- * For Example,
- *
- * <pre>
- *      grant CodeBase "foo.com", Signedby "foo",
- *            Principal com.sun.security.auth.SolarisPrincipal "duke" {
- *          permission java.io.FilePermission "/home/duke", "read, write";
- *      };
- * </pre>
- *
- * This <b><i>grant</i></b> entry specifies that code from "foo.com",
- * signed by "foo', and running as a <code>SolarisPrincipal</code> with the
- * name, duke, has one <code>Permission</code>.  This <code>Permission</code>
- * permits the executing code to read and write files in the directory,
- * "/home/duke".
- *
- * <p> To "run" as a particular <code>Principal</code>,
- * code invokes the <code>Subject.doAs(subject, ...)</code> method.
- * After invoking that method, the code runs as all the Principals
- * associated with the specified <code>Subject</code>.
- * Note that this <code>Policy</code> (and the Permissions
- * granted in this <code>Policy</code>) only become effective
- * after the call to <code>Subject.doAs</code> has occurred.
- *
- * <p> Multiple Principals may be listed within one <b><i>grant</i></b> entry.
- * All the Principals in the grant entry must be associated with
- * the <code>Subject</code> provided to <code>Subject.doAs</code>
- * for that <code>Subject</code> to be granted the specified Permissions.
- *
- * <pre>
- *      grant Principal com.sun.security.auth.SolarisPrincipal "duke",
- *            Principal com.sun.security.auth.SolarisNumericUserPrincipal "0" {
- *          permission java.io.FilePermission "/home/duke", "read, write";
- *          permission java.net.SocketPermission "duke.com", "connect";
- *      };
- * </pre>
- *
- * This entry grants any code running as both "duke" and "0"
- * permission to read and write files in duke's home directory,
- * as well as permission to make socket connections to "duke.com".
- *
- * <p> Note that non Principal-based grant entries are not permitted
- * in this <code>Policy</code>.  Therefore, grant entries such as:
- *
- * <pre>
- *      grant CodeBase "foo.com", Signedby "foo" {
- *          permission java.io.FilePermission "/tmp/scratch", "read, write";
- *      };
- * </pre>
- *
- * are rejected.  Such permission must be listed in the
- * <code>java.security.Policy</code>.
- *
- * <p> The default <code>Policy</code> implementation can be changed by
- * setting the value of the "auth.policy.provider" security property
- * (in the Java security properties file) to the fully qualified name of
- * the desired <code>Policy</code> implementation class.
- * The Java security properties file is located in the file named
- * &lt;JAVA_HOME&gt;/lib/security/java.security.
- * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
- * and specifies the directory where the JRE is installed.
- *
- * @deprecated  as of JDK version 1.4 -- Replaced by java.security.Policy.
- *              java.security.Policy has a method:
- * <pre>
- *      public PermissionCollection getPermissions
- *          (java.security.ProtectionDomain pd)
- *
- * </pre>
- * and ProtectionDomain has a constructor:
- * <pre>
- *      public ProtectionDomain
- *          (CodeSource cs,
- *           PermissionCollection permissions,
- *           ClassLoader loader,
- *           Principal[] principals)
- * </pre>
- *
- * These two APIs provide callers the means to query the
- * Policy for Principal-based Permission entries.
- *
- *
- */
-@Deprecated
-public abstract class Policy {
-
-    private static Policy policy;
-    private static ClassLoader contextClassLoader;
-
-    // true if a custom (not com.sun.security.auth.PolicyFile) system-wide
-    // policy object is set
-    private static boolean isCustomPolicy;
-
-    static {
-        contextClassLoader = java.security.AccessController.doPrivileged
-                (new java.security.PrivilegedAction<ClassLoader>() {
-                public ClassLoader run() {
-                    return Thread.currentThread().getContextClassLoader();
-                }
-        });
-    };
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected Policy() { }
-
-    /**
-     * Returns the installed Policy object.
-     * This method first calls
-     * <code>SecurityManager.checkPermission</code> with the
-     * <code>AuthPermission("getPolicy")</code> permission
-     * to ensure the caller has permission to get the Policy object.
-     *
-     * <p>
-     *
-     * @return the installed Policy.  The return value cannot be
-     *          <code>null</code>.
-     *
-     * @exception java.lang.SecurityException if the current thread does not
-     *      have permission to get the Policy object.
-     *
-     * @see #setPolicy
-     */
-    public static Policy getPolicy() {
-        java.lang.SecurityManager sm = System.getSecurityManager();
-        if (sm != null) sm.checkPermission(new AuthPermission("getPolicy"));
-        return getPolicyNoCheck();
-    }
-
-    /**
-     * Returns the installed Policy object, skipping the security check.
-     *
-     * @return the installed Policy.
-     *
-     */
-    static Policy getPolicyNoCheck() {
-        if (policy == null) {
-
-            synchronized(Policy.class) {
-
-                if (policy == null) {
-                    String policy_class = null;
-                    policy_class = java.security.AccessController.doPrivileged
-                        (new java.security.PrivilegedAction<String>() {
-                        public String run() {
-                            return java.security.Security.getProperty
-                                ("auth.policy.provider");
-                        }
-                    });
-                    if (policy_class == null) {
-                        policy_class = "com.sun.security.auth.PolicyFile";
-                    }
-
-                    try {
-                        final String finalClass = policy_class;
-                        policy = java.security.AccessController.doPrivileged
-                            (new java.security.PrivilegedExceptionAction<Policy>() {
-                            public Policy run() throws ClassNotFoundException,
-                                                InstantiationException,
-                                                IllegalAccessException {
-                                return (Policy) Class.forName
-                                        (finalClass,
-                                        true,
-                                        contextClassLoader).newInstance();
-                            }
-                        });
-                        isCustomPolicy =
-                            !finalClass.equals("com.sun.security.auth.PolicyFile");
-                    } catch (Exception e) {
-                        throw new SecurityException
-                                (sun.security.util.ResourcesMgr.getString
-                                ("unable.to.instantiate.Subject.based.policy"));
-                    }
-                }
-            }
-        }
-        return policy;
-    }
-
-
-    /**
-     * Sets the system-wide Policy object. This method first calls
-     * <code>SecurityManager.checkPermission</code> with the
-     * <code>AuthPermission("setPolicy")</code>
-     * permission to ensure the caller has permission to set the Policy.
-     *
-     * <p>
-     *
-     * @param policy the new system Policy object.
-     *
-     * @exception java.lang.SecurityException if the current thread does not
-     *          have permission to set the Policy.
-     *
-     * @see #getPolicy
-     */
-    public static void setPolicy(Policy policy) {
-        java.lang.SecurityManager sm = System.getSecurityManager();
-        if (sm != null) sm.checkPermission(new AuthPermission("setPolicy"));
-        Policy.policy = policy;
-        // all non-null policy objects are assumed to be custom
-        isCustomPolicy = policy != null ? true : false;
-    }
-
-    /**
-     * Returns true if a custom (not com.sun.security.auth.PolicyFile)
-     * system-wide policy object has been set or installed. This method is
-     * called by SubjectDomainCombiner to provide backwards compatibility for
-     * developers that provide their own javax.security.auth.Policy
-     * implementations.
-     *
-     * @return true if a custom (not com.sun.security.auth.PolicyFile)
-     * system-wide policy object has been set; false otherwise
-     */
-    static boolean isCustomPolicySet(Debug debug) {
-        if (policy != null) {
-            if (debug != null && isCustomPolicy) {
-                debug.println("Providing backwards compatibility for " +
-                              "javax.security.auth.policy implementation: " +
-                              policy.toString());
-            }
-            return isCustomPolicy;
-        }
-        // check if custom policy has been set using auth.policy.provider prop
-        String policyClass = java.security.AccessController.doPrivileged
-            (new java.security.PrivilegedAction<String>() {
-                public String run() {
-                    return Security.getProperty("auth.policy.provider");
-                }
-        });
-        if (policyClass != null
-            && !policyClass.equals("com.sun.security.auth.PolicyFile")) {
-            if (debug != null) {
-                debug.println("Providing backwards compatibility for " +
-                              "javax.security.auth.policy implementation: " +
-                              policyClass);
-            }
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Retrieve the Permissions granted to the Principals associated with
-     * the specified <code>CodeSource</code>.
-     *
-     * <p>
-     *
-     * @param subject the <code>Subject</code>
-     *                  whose associated Principals,
-     *                  in conjunction with the provided
-     *                  <code>CodeSource</code>, determines the Permissions
-     *                  returned by this method.  This parameter
-     *                  may be <code>null</code>. <p>
-     *
-     * @param cs the code specified by its <code>CodeSource</code>
-     *                  that determines, in conjunction with the provided
-     *                  <code>Subject</code>, the Permissions
-     *                  returned by this method.  This parameter may be
-     *                  <code>null</code>.
-     *
-     * @return the Collection of Permissions granted to all the
-     *                  <code>Subject</code> and code specified in
-     *                  the provided <i>subject</i> and <i>cs</i>
-     *                  parameters.
-     */
-    public abstract java.security.PermissionCollection getPermissions
-                                        (Subject subject,
-                                        java.security.CodeSource cs);
-
-    /**
-     * Refresh and reload the Policy.
-     *
-     * <p>This method causes this object to refresh/reload its current
-     * Policy. This is implementation-dependent.
-     * For example, if the Policy object is stored in
-     * a file, calling <code>refresh</code> will cause the file to be re-read.
-     *
-     * <p>
-     *
-     * @exception SecurityException if the caller does not have permission
-     *                          to refresh the Policy.
-     */
-    public abstract void refresh();
-}
diff --git a/ojluni/src/main/java/javax/security/auth/login/AppConfigurationEntry.java b/ojluni/src/main/java/javax/security/auth/login/AppConfigurationEntry.java
deleted file mode 100755
index 7c70d58..0000000
--- a/ojluni/src/main/java/javax/security/auth/login/AppConfigurationEntry.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.security.auth.login;
-
-import java.util.Map;
-import java.util.Collections;
-
-/**
- * This class represents a single <code>LoginModule</code> entry
- * configured for the application specified in the
- * <code>getAppConfigurationEntry(String appName)</code>
- * method in the <code>Configuration</code> class.  Each respective
- * <code>AppConfigurationEntry</code> contains a <code>LoginModule</code> name,
- * a control flag (specifying whether this <code>LoginModule</code> is
- * REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL), and LoginModule-specific
- * options.  Please refer to the <code>Configuration</code> class for
- * more information on the different control flags and their semantics.
- *
- * @see javax.security.auth.login.Configuration
- */
-public class AppConfigurationEntry {
-
-    private String loginModuleName;
-    private LoginModuleControlFlag controlFlag;
-    private Map<String,?> options;
-
-    /**
-     * Default constructor for this class.
-     *
-     * <p> This entry represents a single <code>LoginModule</code>
-     * entry configured for the application specified in the
-     * <code>getAppConfigurationEntry(String appName)</code>
-     * method from the <code>Configuration</code> class.
-     *
-     * @param loginModuleName String representing the class name of the
-     *                  <code>LoginModule</code> configured for the
-     *                  specified application. <p>
-     *
-     * @param controlFlag either REQUIRED, REQUISITE, SUFFICIENT,
-     *                  or OPTIONAL. <p>
-     *
-     * @param options the options configured for this <code>LoginModule</code>.
-     *
-     * @exception IllegalArgumentException if <code>loginModuleName</code>
-     *                  is null, if <code>LoginModuleName</code>
-     *                  has a length of 0, if <code>controlFlag</code>
-     *                  is not either REQUIRED, REQUISITE, SUFFICIENT
-     *                  or OPTIONAL, or if <code>options</code> is null.
-     */
-    public AppConfigurationEntry(String loginModuleName,
-                                LoginModuleControlFlag controlFlag,
-                                Map<String,?> options)
-    {
-        if (loginModuleName == null || loginModuleName.length() == 0 ||
-            (controlFlag != LoginModuleControlFlag.REQUIRED &&
-                controlFlag != LoginModuleControlFlag.REQUISITE &&
-                controlFlag != LoginModuleControlFlag.SUFFICIENT &&
-                controlFlag != LoginModuleControlFlag.OPTIONAL) ||
-            options == null)
-            throw new IllegalArgumentException();
-
-        this.loginModuleName = loginModuleName;
-        this.controlFlag = controlFlag;
-        this.options = Collections.unmodifiableMap(options);
-    }
-
-    /**
-     * Get the class name of the configured <code>LoginModule</code>.
-     *
-     * @return the class name of the configured <code>LoginModule</code> as
-     *          a String.
-     */
-    public String getLoginModuleName() {
-        return loginModuleName;
-    }
-
-    /**
-     * Return the controlFlag
-     * (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL)
-     * for this <code>LoginModule</code>.
-     *
-     * @return the controlFlag
-     *          (either REQUIRED, REQUISITE, SUFFICIENT, or OPTIONAL)
-     *          for this <code>LoginModule</code>.
-     */
-    public LoginModuleControlFlag getControlFlag() {
-        return controlFlag;
-    }
-
-    /**
-     * Get the options configured for this <code>LoginModule</code>.
-     *
-     * @return the options configured for this <code>LoginModule</code>
-     *          as an unmodifiable <code>Map</code>.
-     */
-    public Map<String,?> getOptions() {
-        return options;
-    }
-
-    /**
-     * This class represents whether or not a <code>LoginModule</code>
-     * is REQUIRED, REQUISITE, SUFFICIENT or OPTIONAL.
-     */
-    public static class LoginModuleControlFlag {
-
-        private String controlFlag;
-
-        /**
-         * Required <code>LoginModule</code>.
-         */
-        public static final LoginModuleControlFlag REQUIRED =
-                                new LoginModuleControlFlag("required");
-
-        /**
-         * Requisite <code>LoginModule</code>.
-         */
-        public static final LoginModuleControlFlag REQUISITE =
-                                new LoginModuleControlFlag("requisite");
-
-        /**
-         * Sufficient <code>LoginModule</code>.
-         */
-        public static final LoginModuleControlFlag SUFFICIENT =
-                                new LoginModuleControlFlag("sufficient");
-
-        /**
-         * Optional <code>LoginModule</code>.
-         */
-        public static final LoginModuleControlFlag OPTIONAL =
-                                new LoginModuleControlFlag("optional");
-
-        private LoginModuleControlFlag(String controlFlag) {
-            this.controlFlag = controlFlag;
-        }
-
-        /**
-         * Return a String representation of this controlFlag.
-         *
-         * <p> The String has the format, "LoginModuleControlFlag: <i>flag</i>",
-         * where <i>flag</i> is either <i>required</i>, <i>requisite</i>,
-         * <i>sufficient</i>, or <i>optional</i>.
-         *
-         * @return a String representation of this controlFlag.
-         */
-        public String toString() {
-            return (sun.security.util.ResourcesMgr.getString
-                ("LoginModuleControlFlag.") + controlFlag);
-        }
-    }
-}
diff --git a/ojluni/src/main/java/javax/security/auth/login/Configuration.java b/ojluni/src/main/java/javax/security/auth/login/Configuration.java
deleted file mode 100755
index 988dc1a..0000000
--- a/ojluni/src/main/java/javax/security/auth/login/Configuration.java
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.security.auth.login;
-
-import javax.security.auth.AuthPermission;
-
-import java.io.*;
-import java.util.*;
-import java.net.URI;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.Provider;
-import java.security.Security;
-import java.security.SecurityPermission;
-
-import sun.security.jca.GetInstance;
-
-/**
- * A Configuration object is responsible for specifying which LoginModules
- * should be used for a particular application, and in what order the
- * LoginModules should be invoked.
- *
- * <p> A login configuration contains the following information.
- * Note that this example only represents the default syntax for the
- * <code>Configuration</code>.  Subclass implementations of this class
- * may implement alternative syntaxes and may retrieve the
- * <code>Configuration</code> from any source such as files, databases,
- * or servers.
- *
- * <pre>
- *      Name {
- *            ModuleClass  Flag    ModuleOptions;
- *            ModuleClass  Flag    ModuleOptions;
- *            ModuleClass  Flag    ModuleOptions;
- *      };
- *      Name {
- *            ModuleClass  Flag    ModuleOptions;
- *            ModuleClass  Flag    ModuleOptions;
- *      };
- *      other {
- *            ModuleClass  Flag    ModuleOptions;
- *            ModuleClass  Flag    ModuleOptions;
- *      };
- * </pre>
- *
- * <p> Each entry in the <code>Configuration</code> is indexed via an
- * application name, <i>Name</i>, and contains a list of
- * LoginModules configured for that application.  Each <code>LoginModule</code>
- * is specified via its fully qualified class name.
- * Authentication proceeds down the module list in the exact order specified.
- * If an application does not have specific entry,
- * it defaults to the specific entry for "<i>other</i>".
- *
- * <p> The <i>Flag</i> value controls the overall behavior as authentication
- * proceeds down the stack.  The following represents a description of the
- * valid values for <i>Flag</i> and their respective semantics:
- *
- * <pre>
- *      1) Required     - The <code>LoginModule</code> is required to succeed.
- *                      If it succeeds or fails, authentication still continues
- *                      to proceed down the <code>LoginModule</code> list.
- *
- *      2) Requisite    - The <code>LoginModule</code> is required to succeed.
- *                      If it succeeds, authentication continues down the
- *                      <code>LoginModule</code> list.  If it fails,
- *                      control immediately returns to the application
- *                      (authentication does not proceed down the
- *                      <code>LoginModule</code> list).
- *
- *      3) Sufficient   - The <code>LoginModule</code> is not required to
- *                      succeed.  If it does succeed, control immediately
- *                      returns to the application (authentication does not
- *                      proceed down the <code>LoginModule</code> list).
- *                      If it fails, authentication continues down the
- *                      <code>LoginModule</code> list.
- *
- *      4) Optional     - The <code>LoginModule</code> is not required to
- *                      succeed.  If it succeeds or fails,
- *                      authentication still continues to proceed down the
- *                      <code>LoginModule</code> list.
- * </pre>
- *
- * <p> The overall authentication succeeds only if all <i>Required</i> and
- * <i>Requisite</i> LoginModules succeed.  If a <i>Sufficient</i>
- * <code>LoginModule</code> is configured and succeeds,
- * then only the <i>Required</i> and <i>Requisite</i> LoginModules prior to
- * that <i>Sufficient</i> <code>LoginModule</code> need to have succeeded for
- * the overall authentication to succeed. If no <i>Required</i> or
- * <i>Requisite</i> LoginModules are configured for an application,
- * then at least one <i>Sufficient</i> or <i>Optional</i>
- * <code>LoginModule</code> must succeed.
- *
- * <p> <i>ModuleOptions</i> is a space separated list of
- * <code>LoginModule</code>-specific values which are passed directly to
- * the underlying LoginModules.  Options are defined by the
- * <code>LoginModule</code> itself, and control the behavior within it.
- * For example, a <code>LoginModule</code> may define options to support
- * debugging/testing capabilities.  The correct way to specify options in the
- * <code>Configuration</code> is by using the following key-value pairing:
- * <i>debug="true"</i>.  The key and value should be separated by an
- * 'equals' symbol, and the value should be surrounded by double quotes.
- * If a String in the form, ${system.property}, occurs in the value,
- * it will be expanded to the value of the system property.
- * Note that there is no limit to the number of
- * options a <code>LoginModule</code> may define.
- *
- * <p> The following represents an example <code>Configuration</code> entry
- * based on the syntax above:
- *
- * <pre>
- * Login {
- *   com.sun.security.auth.module.UnixLoginModule required;
- *   com.sun.security.auth.module.Krb5LoginModule optional
- *                   useTicketCache="true"
- *                   ticketCache="${user.home}${/}tickets";
- * };
- * </pre>
- *
- * <p> This <code>Configuration</code> specifies that an application named,
- * "Login", requires users to first authenticate to the
- * <i>com.sun.security.auth.module.UnixLoginModule</i>, which is
- * required to succeed.  Even if the <i>UnixLoginModule</i>
- * authentication fails, the
- * <i>com.sun.security.auth.module.Krb5LoginModule</i>
- * still gets invoked.  This helps hide the source of failure.
- * Since the <i>Krb5LoginModule</i> is <i>Optional</i>, the overall
- * authentication succeeds only if the <i>UnixLoginModule</i>
- * (<i>Required</i>) succeeds.
- *
- * <p> Also note that the LoginModule-specific options,
- * <i>useTicketCache="true"</i> and
- * <i>ticketCache=${user.home}${/}tickets"</i>,
- * are passed to the <i>Krb5LoginModule</i>.
- * These options instruct the <i>Krb5LoginModule</i> to
- * use the ticket cache at the specified location.
- * The system properties, <i>user.home</i> and <i>/</i>
- * (file.separator), are expanded to their respective values.
- *
- * <p> There is only one Configuration object installed in the runtime at any
- * given time.  A Configuration object can be installed by calling the
- * <code>setConfiguration</code> method.  The installed Configuration object
- * can be obtained by calling the <code>getConfiguration</code> method.
- *
- * <p> If no Configuration object has been installed in the runtime, a call to
- * <code>getConfiguration</code> installs an instance of the default
- * Configuration implementation (a default subclass implementation of this
- * abstract class).
- * The default Configuration implementation can be changed by setting the value
- * of the "login.configuration.provider" security property (in the Java
- * security properties file) to the fully qualified name of the desired
- * Configuration subclass implementation.  The Java security properties file
- * is located in the file named &lt;JAVA_HOME&gt;/lib/security/java.security.
- * &lt;JAVA_HOME&gt; refers to the value of the java.home system property,
- * and specifies the directory where the JRE is installed.
- *
- * <p> Application code can directly subclass Configuration to provide a custom
- * implementation.  In addition, an instance of a Configuration object can be
- * constructed by invoking one of the <code>getInstance</code> factory methods
- * with a standard type.  The default policy type is "JavaLoginConfig".
- * See the Configuration section in the <a href=
- * "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
- * Java Cryptography Architecture Standard Algorithm Name Documentation</a>
- * for a list of standard Configuration types.
- *
- * @see javax.security.auth.login.LoginContext
- */
-public abstract class Configuration {
-
-    private static Configuration configuration;
-    private static ClassLoader contextClassLoader;
-
-    static {
-        contextClassLoader = AccessController.doPrivileged
-                (new PrivilegedAction<ClassLoader>() {
-                public ClassLoader run() {
-                    return Thread.currentThread().getContextClassLoader();
-                }
-        });
-    };
-
-    private static void checkPermission(String type) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(new AuthPermission
-                                ("createLoginConfiguration." + type));
-        }
-    }
-
-    /**
-     * Sole constructor.  (For invocation by subclass constructors, typically
-     * implicit.)
-     */
-    protected Configuration() { }
-
-    /**
-     * Get the installed login Configuration.
-     *
-     * <p>
-     *
-     * @return the login Configuration.  If a Configuration object was set
-     *          via the <code>Configuration.setConfiguration</code> method,
-     *          then that object is returned.  Otherwise, a default
-     *          Configuration object is returned.
-     *
-     * @exception SecurityException if the caller does not have permission
-     *                          to retrieve the Configuration.
-     *
-     * @see #setConfiguration
-     */
-    public static Configuration getConfiguration() {
-
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null)
-            sm.checkPermission(new AuthPermission("getLoginConfiguration"));
-
-        synchronized (Configuration.class) {
-            if (configuration == null) {
-                String config_class = null;
-                config_class = AccessController.doPrivileged
-                    (new PrivilegedAction<String>() {
-                    public String run() {
-                        return java.security.Security.getProperty
-                                    ("login.configuration.provider");
-                    }
-                });
-                if (config_class == null) {
-                    config_class = "com.sun.security.auth.login.ConfigFile";
-                }
-
-                try {
-                    final String finalClass = config_class;
-                    configuration = AccessController.doPrivileged
-                        (new PrivilegedExceptionAction<Configuration>() {
-                        public Configuration run() throws ClassNotFoundException,
-                                            InstantiationException,
-                                            IllegalAccessException {
-                            return (Configuration)Class.forName
-                                    (finalClass,
-                                    true,
-                                    contextClassLoader).newInstance();
-                        }
-                    });
-                } catch (PrivilegedActionException e) {
-                    Exception ee = e.getException();
-                    if (ee instanceof InstantiationException) {
-                        throw (SecurityException) new
-                            SecurityException
-                                    ("Configuration error:" +
-                                     ee.getCause().getMessage() +
-                                     "\n").initCause(ee.getCause());
-                    } else {
-                        throw (SecurityException) new
-                            SecurityException
-                                    ("Configuration error: " +
-                                     ee.toString() +
-                                     "\n").initCause(ee);
-                    }
-                }
-            }
-            return configuration;
-        }
-    }
-
-    /**
-     * Set the login <code>Configuration</code>.
-     *
-     * <p>
-     *
-     * @param configuration the new <code>Configuration</code>
-     *
-     * @exception SecurityException if the current thread does not have
-     *                  Permission to set the <code>Configuration</code>.
-     *
-     * @see #getConfiguration
-     */
-    public static void setConfiguration(Configuration configuration) {
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null)
-            sm.checkPermission(new AuthPermission("setLoginConfiguration"));
-        Configuration.configuration = configuration;
-    }
-
-    /**
-     * Returns a Configuration object of the specified type.
-     *
-     * <p> This method traverses the list of registered security providers,
-     * starting with the most preferred Provider.
-     * A new Configuration object encapsulating the
-     * ConfigurationSpi implementation from the first
-     * Provider that supports the specified type is returned.
-     *
-     * <p> Note that the list of registered providers may be retrieved via
-     * the {@link Security#getProviders() Security.getProviders()} method.
-     *
-     * @param type the specified Configuration type.  See the Configuration
-     *    section in the <a href=
-     *    "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
-     *    Java Cryptography Architecture Standard Algorithm Name
-     *    Documentation</a> for a list of standard Configuration types.
-     *
-     * @param params parameters for the Configuration, which may be null.
-     *
-     * @return the new Configuration object.
-     *
-     * @exception SecurityException if the caller does not have permission
-     *          to get a Configuration instance for the specified type.
-     *
-     * @exception NullPointerException if the specified type is null.
-     *
-     * @exception IllegalArgumentException if the specified parameters
-     *          are not understood by the ConfigurationSpi implementation
-     *          from the selected Provider.
-     *
-     * @exception NoSuchAlgorithmException if no Provider supports a
-     *          ConfigurationSpi implementation for the specified type.
-     *
-     * @see Provider
-     * @since 1.6
-     */
-    public static Configuration getInstance(String type,
-                                Configuration.Parameters params)
-                throws NoSuchAlgorithmException {
-
-        checkPermission(type);
-        try {
-            GetInstance.Instance instance = GetInstance.getInstance
-                                                        ("Configuration",
-                                                        ConfigurationSpi.class,
-                                                        type,
-                                                        params);
-            return new ConfigDelegate((ConfigurationSpi)instance.impl,
-                                                        instance.provider,
-                                                        type,
-                                                        params);
-        } catch (NoSuchAlgorithmException nsae) {
-            return handleException (nsae);
-        }
-    }
-
-    /**
-     * Returns a Configuration object of the specified type.
-     *
-     * <p> A new Configuration object encapsulating the
-     * ConfigurationSpi implementation from the specified provider
-     * is returned.   The specified provider must be registered
-     * in the provider list.
-     *
-     * <p> Note that the list of registered providers may be retrieved via
-     * the {@link Security#getProviders() Security.getProviders()} method.
-     *
-     * @param type the specified Configuration type.  See the Configuration
-     *    section in the <a href=
-     *    "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
-     *    Java Cryptography Architecture Standard Algorithm Name
-     *    Documentation</a> for a list of standard Configuration types.
-     *
-     * @param params parameters for the Configuration, which may be null.
-     *
-     * @param provider the provider.
-     *
-     * @return the new Configuration object.
-     *
-     * @exception SecurityException if the caller does not have permission
-     *          to get a Configuration instance for the specified type.
-     *
-     * @exception NullPointerException if the specified type is null.
-     *
-     * @exception IllegalArgumentException if the specified provider
-     *          is null or empty,
-     *          or if the specified parameters are not understood by
-     *          the ConfigurationSpi implementation from the specified provider.
-     *
-     * @exception NoSuchProviderException if the specified provider is not
-     *          registered in the security provider list.
-     *
-     * @exception NoSuchAlgorithmException if the specified provider does not
-     *          support a ConfigurationSpi implementation for the specified
-     *          type.
-     *
-     * @see Provider
-     * @since 1.6
-     */
-    public static Configuration getInstance(String type,
-                                Configuration.Parameters params,
-                                String provider)
-                throws NoSuchProviderException, NoSuchAlgorithmException {
-
-        if (provider == null || provider.length() == 0) {
-            throw new IllegalArgumentException("missing provider");
-        }
-
-        checkPermission(type);
-        try {
-            GetInstance.Instance instance = GetInstance.getInstance
-                                                        ("Configuration",
-                                                        ConfigurationSpi.class,
-                                                        type,
-                                                        params,
-                                                        provider);
-            return new ConfigDelegate((ConfigurationSpi)instance.impl,
-                                                        instance.provider,
-                                                        type,
-                                                        params);
-        } catch (NoSuchAlgorithmException nsae) {
-            return handleException (nsae);
-        }
-    }
-
-    /**
-     * Returns a Configuration object of the specified type.
-     *
-     * <p> A new Configuration object encapsulating the
-     * ConfigurationSpi implementation from the specified Provider
-     * object is returned.  Note that the specified Provider object
-     * does not have to be registered in the provider list.
-     *
-     * @param type the specified Configuration type.  See the Configuration
-     *    section in the <a href=
-     *    "{@docRoot}/../technotes/guides/security/StandardNames.html#Configuration">
-     *    Java Cryptography Architecture Standard Algorithm Name
-     *    Documentation</a> for a list of standard Configuration types.
-     *
-     * @param params parameters for the Configuration, which may be null.
-     *
-     * @param provider the Provider.
-     *
-     * @return the new Configuration object.
-     *
-     * @exception SecurityException if the caller does not have permission
-     *          to get a Configuration instance for the specified type.
-     *
-     * @exception NullPointerException if the specified type is null.
-     *
-     * @exception IllegalArgumentException if the specified Provider is null,
-     *          or if the specified parameters are not understood by
-     *          the ConfigurationSpi implementation from the specified Provider.
-     *
-     * @exception NoSuchAlgorithmException if the specified Provider does not
-     *          support a ConfigurationSpi implementation for the specified
-     *          type.
-     *
-     * @see Provider
-     * @since 1.6
-     */
-    public static Configuration getInstance(String type,
-                                Configuration.Parameters params,
-                                Provider provider)
-                throws NoSuchAlgorithmException {
-
-        if (provider == null) {
-            throw new IllegalArgumentException("missing provider");
-        }
-
-        checkPermission(type);
-        try {
-            GetInstance.Instance instance = GetInstance.getInstance
-                                                        ("Configuration",
-                                                        ConfigurationSpi.class,
-                                                        type,
-                                                        params,
-                                                        provider);
-            return new ConfigDelegate((ConfigurationSpi)instance.impl,
-                                                        instance.provider,
-                                                        type,
-                                                        params);
-        } catch (NoSuchAlgorithmException nsae) {
-            return handleException (nsae);
-        }
-    }
-
-    private static Configuration handleException(NoSuchAlgorithmException nsae)
-                throws NoSuchAlgorithmException {
-        Throwable cause = nsae.getCause();
-        if (cause instanceof IllegalArgumentException) {
-            throw (IllegalArgumentException)cause;
-        }
-        throw nsae;
-    }
-
-    /**
-     * Return the Provider of this Configuration.
-     *
-     * <p> This Configuration instance will only have a Provider if it
-     * was obtained via a call to <code>Configuration.getInstance</code>.
-     * Otherwise this method returns null.
-     *
-     * @return the Provider of this Configuration, or null.
-     *
-     * @since 1.6
-     */
-    public Provider getProvider() {
-        return null;
-    }
-
-    /**
-     * Return the type of this Configuration.
-     *
-     * <p> This Configuration instance will only have a type if it
-     * was obtained via a call to <code>Configuration.getInstance</code>.
-     * Otherwise this method returns null.
-     *
-     * @return the type of this Configuration, or null.
-     *
-     * @since 1.6
-     */
-    public String getType() {
-        return null;
-    }
-
-    /**
-     * Return Configuration parameters.
-     *
-     * <p> This Configuration instance will only have parameters if it
-     * was obtained via a call to <code>Configuration.getInstance</code>.
-     * Otherwise this method returns null.
-     *
-     * @return Configuration parameters, or null.
-     *
-     * @since 1.6
-     */
-    public Configuration.Parameters getParameters() {
-        return null;
-    }
-
-    /**
-     * Retrieve the AppConfigurationEntries for the specified <i>name</i>
-     * from this Configuration.
-     *
-     * <p>
-     *
-     * @param name the name used to index the Configuration.
-     *
-     * @return an array of AppConfigurationEntries for the specified <i>name</i>
-     *          from this Configuration, or null if there are no entries
-     *          for the specified <i>name</i>
-     */
-    public abstract AppConfigurationEntry[] getAppConfigurationEntry
-                                                        (String name);
-
-    /**
-     * Refresh and reload the Configuration.
-     *
-     * <p> This method causes this Configuration object to refresh/reload its
-     * contents in an implementation-dependent manner.
-     * For example, if this Configuration object stores its entries in a file,
-     * calling <code>refresh</code> may cause the file to be re-read.
-     *
-     * <p> The default implementation of this method does nothing.
-     * This method should be overridden if a refresh operation is supported
-     * by the implementation.
-     *
-     * @exception SecurityException if the caller does not have permission
-     *                          to refresh its Configuration.
-     */
-    public void refresh() { }
-
-    /**
-     * This subclass is returned by the getInstance calls.  All Configuration
-     * calls are delegated to the underlying ConfigurationSpi.
-     */
-    private static class ConfigDelegate extends Configuration {
-
-        private ConfigurationSpi spi;
-        private Provider p;
-        private String type;
-        private Configuration.Parameters params;
-
-        private ConfigDelegate(ConfigurationSpi spi, Provider p,
-                        String type, Configuration.Parameters params) {
-            this.spi = spi;
-            this.p = p;
-            this.type = type;
-            this.params = params;
-        }
-
-        public String getType() { return type; }
-
-        public Configuration.Parameters getParameters() { return params; }
-
-        public Provider getProvider() { return p; }
-
-        public AppConfigurationEntry[] getAppConfigurationEntry(String name) {
-            return spi.engineGetAppConfigurationEntry(name);
-        }
-
-        public void refresh() {
-            spi.engineRefresh();
-        }
-    }
-
-    /**
-     * This represents a marker interface for Configuration parameters.
-     *
-     * @since 1.6
-     */
-    public static interface Parameters { }
-}
diff --git a/ojluni/src/main/java/javax/security/auth/login/ConfigurationSpi.java b/ojluni/src/main/java/javax/security/auth/login/ConfigurationSpi.java
deleted file mode 100755
index d7047d9..0000000
--- a/ojluni/src/main/java/javax/security/auth/login/ConfigurationSpi.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2005, 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 javax.security.auth.login;
-
-/**
- * This class defines the <i>Service Provider Interface</i> (<b>SPI</b>)
- * for the <code>Configuration</code> class.
- * All the abstract methods in this class must be implemented by each
- * service provider who wishes to supply a Configuration implementation.
- *
- * <p> Subclass implementations of this abstract class must provide
- * a public constructor that takes a <code>Configuration.Parameters</code>
- * object as an input parameter.  This constructor also must throw
- * an IllegalArgumentException if it does not understand the
- * <code>Configuration.Parameters</code> input.
- *
- *
- * @since 1.6
- */
-
-public abstract class ConfigurationSpi {
-    /**
-     * Retrieve the AppConfigurationEntries for the specified <i>name</i>.
-     *
-     * <p>
-     *
-     * @param name the name used to index the Configuration.
-     *
-     * @return an array of AppConfigurationEntries for the specified
-     *          <i>name</i>, or null if there are no entries.
-     */
-    protected abstract AppConfigurationEntry[] engineGetAppConfigurationEntry
-                                                        (String name);
-
-    /**
-     * Refresh and reload the Configuration.
-     *
-     * <p> This method causes this Configuration object to refresh/reload its
-     * contents in an implementation-dependent manner.
-     * For example, if this Configuration object stores its entries in a file,
-     * calling <code>refresh</code> may cause the file to be re-read.
-     *
-     * <p> The default implementation of this method does nothing.
-     * This method should be overridden if a refresh operation is supported
-     * by the implementation.
-     *
-     * @exception SecurityException if the caller does not have permission
-     *          to refresh its Configuration.
-     */
-    protected void engineRefresh() { }
-}
diff --git a/ojluni/src/main/java/sun/security/util/Debug.java b/ojluni/src/main/java/sun/security/util/Debug.java
index 5701a80..f1d2bd0 100755
--- a/ojluni/src/main/java/sun/security/util/Debug.java
+++ b/ojluni/src/main/java/sun/security/util/Debug.java
@@ -26,9 +26,9 @@
 package sun.security.util;
 
 import java.math.BigInteger;
-import java.util.regex.Pattern;
-import java.util.regex.Matcher;
 import java.util.Locale;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * A utility class for debuging.
@@ -37,36 +37,18 @@
  */
 public class Debug {
 
-    private String prefix;
+    private static final String args = null;
 
-    private static String args;
+    private final String prefix;
 
-    static {
-        args = java.security.AccessController.doPrivileged
-                (new sun.security.action.GetPropertyAction
-                ("java.security.debug"));
-
-        String args2 = java.security.AccessController.doPrivileged
-                (new sun.security.action.GetPropertyAction
-                ("java.security.auth.debug"));
-
-        if (args == null) {
-            args = args2;
-        } else {
-            if (args2 != null)
-               args = args + "," + args2;
-        }
-
-        if (args != null) {
-            args = marshal(args);
-            if (args.equals("help")) {
-                Help();
-            }
-        }
+    private Debug(String prefix) {
+        this.prefix = prefix;
     }
 
-    public static void Help()
-    {
+    /*
+        From public static void Help() : Serves as a documentation of the
+        values that "args" accepts.
+
         System.err.println();
         System.err.println("all           turn on all debugging");
         System.err.println("access        print all checkPermission results");
@@ -100,8 +82,7 @@
         System.err.println();
         System.err.println("Note: Separate multiple options with a comma");
         System.exit(0);
-    }
-
+    */
 
     /**
      * Get a Debug object corresponding to whether or not the given
@@ -120,8 +101,7 @@
     public static Debug getInstance(String option, String prefix)
     {
         if (isOn(option)) {
-            Debug d = new Debug();
-            d.prefix = prefix;
+            Debug d = new Debug(prefix);
             return d;
         } else {
             return null;
@@ -163,14 +143,6 @@
         System.err.println(prefix + ":");
     }
 
-    /**
-     * print a message to stderr that is prefixed with the prefix.
-     */
-
-    public static void println(String prefix, String message)
-    {
-        System.err.println(prefix + ": "+message);
-    }
 
     /**
      * return a hexadecimal printed representation of the specified
diff --git a/openjdk_java_files.mk b/openjdk_java_files.mk
index d70ca30..e065270 100644
--- a/openjdk_java_files.mk
+++ b/openjdk_java_files.mk
@@ -1002,11 +1002,7 @@
     ojluni/src/main/java/javax/security/auth/callback/UnsupportedCallbackException.java \
     ojluni/src/main/java/javax/security/auth/Destroyable.java \
     ojluni/src/main/java/javax/security/auth/DestroyFailedException.java \
-    ojluni/src/main/java/javax/security/auth/login/AppConfigurationEntry.java \
-    ojluni/src/main/java/javax/security/auth/login/Configuration.java \
-    ojluni/src/main/java/javax/security/auth/login/ConfigurationSpi.java \
     ojluni/src/main/java/javax/security/auth/login/LoginException.java \
-    ojluni/src/main/java/javax/security/auth/Policy.java \
     ojluni/src/main/java/javax/security/auth/PrivateCredentialPermission.java \
     ojluni/src/main/java/javax/security/auth/SubjectDomainCombiner.java \
     ojluni/src/main/java/javax/security/auth/Subject.java \
