diff --git a/core/java/android/util/Patterns.java b/core/java/android/util/Patterns.java
index 152827d..9522112 100644
--- a/core/java/android/util/Patterns.java
+++ b/core/java/android/util/Patterns.java
@@ -169,10 +169,10 @@
      * </ul>
      */
     public static final Pattern PHONE
-        = Pattern.compile(                                  // sdd = space, dot, or dash
-                "(\\+[0-9]+[\\- \\.]*)?"                    // +<digits><sdd>*
-                + "(\\([0-9]+\\)[\\- \\.]*)?"               // (<digits>)<sdd>*
-                + "([0-9][0-9\\- \\.][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit> 
+        = Pattern.compile(                      // sdd = space, dot, or dash
+                "(\\+[0-9]+[\\- \\.]*)?"        // +<digits><sdd>*
+                + "(\\([0-9]+\\)[\\- \\.]*)?"   // (<digits>)<sdd>*
+                + "([0-9][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit>
 
     /**
      *  Convenience method to take all of the non-null matching groups in a
diff --git a/core/java/android/webkit/WebViewClassic.java b/core/java/android/webkit/WebViewClassic.java
index ae56e6b..7154f95 100644
--- a/core/java/android/webkit/WebViewClassic.java
+++ b/core/java/android/webkit/WebViewClassic.java
@@ -1258,6 +1258,40 @@
 
         mAutoFillData = new WebViewCore.AutoFillData();
         mEditTextScroller = new Scroller(context);
+
+        // Calculate channel distance
+        calculateChannelDistance(context);
+    }
+
+    /**
+     * Calculate sChannelDistance based on the screen information.
+     * @param context A Context object used to access application assets.
+     */
+    private void calculateChannelDistance(Context context) {
+        // The channel distance is adjusted for density and screen size
+        final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
+        final double screenSize = Math.hypot((double)(metrics.widthPixels/metrics.densityDpi),
+                (double)(metrics.heightPixels/metrics.densityDpi));
+        if (screenSize < 3.0) {
+            sChannelDistance = 16;
+        } else if (screenSize < 5.0) {
+            sChannelDistance = 22;
+        } else if (screenSize < 7.0) {
+            sChannelDistance = 28;
+        } else {
+            sChannelDistance = 34;
+        }
+        sChannelDistance = (int)(sChannelDistance * metrics.density);
+        if (sChannelDistance < 16) sChannelDistance = 16;
+
+        if (DebugFlags.WEB_VIEW) {
+            Log.v(LOGTAG, "sChannelDistance : " + sChannelDistance
+                    + ", density : " + metrics.density
+                    + ", screenSize : " + screenSize
+                    + ", metrics.heightPixels : " + metrics.heightPixels
+                    + ", metrics.widthPixels : " + metrics.widthPixels
+                    + ", metrics.densityDpi : " + metrics.densityDpi);
+        }
     }
 
     // WebViewProvider bindings
@@ -5715,32 +5749,13 @@
         }
         return mWebViewPrivate.super_dispatchKeyEvent(event);
     }
-
-    /*
-     * Here is the snap align logic:
-     * 1. If it starts nearly horizontally or vertically, snap align;
-     * 2. If there is a dramitic direction change, let it go;
-     *
-     * Adjustable parameters. Angle is the radians on a unit circle, limited
-     * to quadrant 1. Values range from 0f (horizontal) to PI/2 (vertical)
-     */
-    private static final float HSLOPE_TO_START_SNAP = .25f;
-    private static final float HSLOPE_TO_BREAK_SNAP = .4f;
-    private static final float VSLOPE_TO_START_SNAP = 1.25f;
-    private static final float VSLOPE_TO_BREAK_SNAP = .95f;
-    /*
-     *  These values are used to influence the average angle when entering
-     *  snap mode. If is is the first movement entering snap, we set the average
-     *  to the appropriate ideal. If the user is entering into snap after the
-     *  first movement, then we average the average angle with these values.
-     */
-    private static final float ANGLE_VERT = 2f;
-    private static final float ANGLE_HORIZ = 0f;
-    /*
-     *  The modified moving average weight.
-     *  Formula: MAV[t]=MAV[t-1] + (P[t]-MAV[t-1])/n
-     */
-    private static final float MMA_WEIGHT_N = 5;
+    
+    private static final int SNAP_BOUND = 16;
+    private static int sChannelDistance = 16;
+    private int mFirstTouchX = -1; // the first touched point
+    private int mFirstTouchY = -1;
+    private int mDistanceX = 0;
+    private int mDistanceY = 0;
 
     private boolean inFullScreenMode() {
         return mFullScreenHolder != null;
@@ -5830,12 +5845,6 @@
         }
     }
 
-    private float calculateDragAngle(int dx, int dy) {
-        dx = Math.abs(dx);
-        dy = Math.abs(dy);
-        return (float) Math.atan2(dy, dx);
-    }
-
     /*
     * Common code for single touch and multi-touch.
     * (x, y) denotes current focus point, which is the touch point for single touch
@@ -5861,6 +5870,12 @@
         switch (action) {
             case MotionEvent.ACTION_DOWN: {
                 mConfirmMove = false;
+
+                // Channel Scrolling
+                mFirstTouchX = x;
+                mFirstTouchY = y;
+                mDistanceX = mDistanceY = 0;
+
                 if (!mEditTextScroller.isFinished()) {
                     mEditTextScroller.abortAnimation();
                 }
@@ -5998,20 +6013,16 @@
                         break;
                     }
 
-                    // Only lock dragging to one axis if we don't have a scale in progress.
-                    // Scaling implies free-roaming movement. Note this is only ever a question
-                    // if mZoomManager.supportsPanDuringZoom() is true.
-                    mAverageAngle = calculateDragAngle(deltaX, deltaY);
-                    if (detector == null || !detector.isInProgress()) {
-                        // if it starts nearly horizontal or vertical, enforce it
-                        if (mAverageAngle < HSLOPE_TO_START_SNAP) {
-                            mSnapScrollMode = SNAP_X;
-                            mSnapPositive = deltaX > 0;
-                            mAverageAngle = ANGLE_HORIZ;
-                        } else if (mAverageAngle > VSLOPE_TO_START_SNAP) {
+                    if ((detector == null || !detector.isInProgress())
+                            && SNAP_NONE == mSnapScrollMode) {
+                        int ax = Math.abs(x - mFirstTouchX);
+                        int ay = Math.abs(y - mFirstTouchY);
+                        if (ax < SNAP_BOUND && ay < SNAP_BOUND) {
+                            break;
+                        } else if (ax < SNAP_BOUND) {
                             mSnapScrollMode = SNAP_Y;
-                            mSnapPositive = deltaY > 0;
-                            mAverageAngle = ANGLE_VERT;
+                        } else if (ay < SNAP_BOUND) {
+                            mSnapScrollMode = SNAP_X;
                         }
                     }
 
@@ -6030,31 +6041,21 @@
                 if (deltaX == 0 && deltaY == 0) {
                     keepScrollBarsVisible = true;
                 } else {
-                    mAverageAngle +=
-                        (calculateDragAngle(deltaX, deltaY) - mAverageAngle)
-                        / MMA_WEIGHT_N;
-                    if (mSnapScrollMode != SNAP_NONE) {
-                        if (mSnapScrollMode == SNAP_Y) {
-                            // radical change means getting out of snap mode
-                            if (mAverageAngle < VSLOPE_TO_BREAK_SNAP) {
-                                mSnapScrollMode = SNAP_NONE;
-                            }
-                        }
+                    if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
+                        mDistanceX += Math.abs(deltaX);
+                        mDistanceY += Math.abs(deltaY);
                         if (mSnapScrollMode == SNAP_X) {
-                            // radical change means getting out of snap mode
-                            if (mAverageAngle > HSLOPE_TO_BREAK_SNAP) {
+                            if (mDistanceY > sChannelDistance) {
                                 mSnapScrollMode = SNAP_NONE;
-                            }
+                            } else if (mDistanceX > sChannelDistance) {
+                                mDistanceX = mDistanceY = 0;
                         }
                     } else {
-                        if (mAverageAngle < HSLOPE_TO_START_SNAP) {
-                            mSnapScrollMode = SNAP_X;
-                            mSnapPositive = deltaX > 0;
-                            mAverageAngle = (mAverageAngle + ANGLE_HORIZ) / 2;
-                        } else if (mAverageAngle > VSLOPE_TO_START_SNAP) {
-                            mSnapScrollMode = SNAP_Y;
-                            mSnapPositive = deltaY > 0;
-                            mAverageAngle = (mAverageAngle + ANGLE_VERT) / 2;
+                            if (mDistanceX > sChannelDistance) {
+                                mSnapScrollMode = SNAP_NONE;
+                            } else if (mDistanceY > sChannelDistance) {
+                                mDistanceX = mDistanceY = 0;
+                            }
                         }
                     }
                     if (mSnapScrollMode != SNAP_NONE) {
@@ -6089,6 +6090,7 @@
                 break;
             }
             case MotionEvent.ACTION_UP: {
+                mFirstTouchX  = mFirstTouchY = -1;
                 if (mIsEditingText && mSelectionStarted) {
                     endScrollEdit();
                     mPrivateHandler.sendEmptyMessageDelayed(SCROLL_HANDLE_INTO_VIEW,
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
index a6057de..0461c0b 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/AccessPointParserHelper.java
@@ -28,6 +28,7 @@
 import android.net.wifi.WifiConfiguration.IpAssignment;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.ProxySettings;
+import android.net.wifi.WifiEnterpriseConfig;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.net.RouteInfo;
@@ -67,7 +68,6 @@
  *      networkprefixlength.
  */
 public class AccessPointParserHelper {
-    private static final String KEYSTORE_SPACE = "keystore://";
     private static final String TAG = "AccessPointParserHelper";
     static final int NONE = 0;
     static final int WEP = 1;
@@ -212,14 +212,11 @@
                         config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
                         config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
                         // Initialize other fields.
-                        config.phase2.setValue("");
-                        config.ca_cert.setValue("");
-                        config.client_cert.setValue("");
-                        config.engine.setValue("");
-                        config.engine_id.setValue("");
-                        config.key_id.setValue("");
-                        config.identity.setValue("");
-                        config.anonymous_identity.setValue("");
+                        config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.NONE);
+                        config.enterpriseConfig.setCaCertificateAlias("");
+                        config.enterpriseConfig.setClientCertificateAlias("");
+                        config.enterpriseConfig.setIdentity("");
+                        config.enterpriseConfig.setAnonymousIdentity("");
                         break;
                     default:
                         throw new SAXException();
@@ -246,7 +243,7 @@
                         config.preSharedKey = '"' + passwordStr + '"';
                     }
                 } else if (securityType == EAP) {
-                    config.password.setValue(passwordStr);
+                    config.enterpriseConfig.setPassword(passwordStr);
                 } else {
                     throw new SAXException();
                 }
@@ -257,33 +254,46 @@
                 if (!validateEapValue(eapValue)) {
                     throw new SAXException();
                 }
-                config.eap.setValue(eapValue);
+		if (eapValue.equals("TLS")) {
+		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+		} else if (eapValue.equals("TTLS")) {
+		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TTLS);
+		} else if (eapValue.equals("PEAP")) {
+		    config.enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.PEAP);
+		}
                 eap = false;
             }
             if (phase2) {
                 String phase2Value = new String(ch, start, length);
-                config.phase2.setValue("auth=" + phase2Value);
+		if (phase2Value.equals("PAP")) {
+                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.PAP);
+		} else if (phase2Value.equals("MSCHAP")) {
+                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAP);
+		} else if (phase2Value.equals("MSCHAPV2")) {
+                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.MSCHAPV2);
+		} else if (phase2Value.equals("GTC")) {
+                    config.enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+		}
                 phase2 = false;
             }
             if (identity) {
                 String identityValue = new String(ch, start, length);
-                config.identity.setValue(identityValue);
+                config.enterpriseConfig.setIdentity(identityValue);
                 identity = false;
             }
             if (anonymousidentity) {
                 String anonyId = new String(ch, start, length);
-                config.anonymous_identity.setValue(anonyId);
+                config.enterpriseConfig.setAnonymousIdentity(anonyId);
                 anonymousidentity = false;
             }
             if (cacert) {
                 String cacertValue = new String(ch, start, length);
-                // need to install the credentail to "keystore://"
-                config.ca_cert.setValue(KEYSTORE_SPACE);
+                config.enterpriseConfig.setCaCertificateAlias(cacertValue);
                 cacert = false;
             }
             if (usercert) {
                 String usercertValue = new String(ch, start, length);
-                config.client_cert.setValue(KEYSTORE_SPACE);
+                config.enterpriseConfig.setClientCertificateAlias(usercertValue);
                 usercert = false;
             }
             if (ip) {
diff --git a/core/tests/coretests/src/android/util/PatternsTest.java b/core/tests/coretests/src/android/util/PatternsTest.java
index 9519b9f..ebdbb0e 100644
--- a/core/tests/coretests/src/android/util/PatternsTest.java
+++ b/core/tests/coretests/src/android/util/PatternsTest.java
@@ -156,6 +156,8 @@
                 "Me: 16505551212 this\n",
                 "Me: 6505551212 this\n",
                 "Me: 5551212 this\n",
+                "Me: 2211 this\n",
+                "Me: 112 this\n",
 
                 "Me: 1-650-555-1212 this\n",
                 "Me: (650) 555-1212 this\n",
diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java
index 84506b6..f119a4b 100644
--- a/wifi/java/android/net/wifi/WifiConfigStore.java
+++ b/wifi/java/android/net/wifi/WifiConfigStore.java
@@ -25,7 +25,6 @@
 import android.net.NetworkInfo.DetailedState;
 import android.net.ProxyProperties;
 import android.net.RouteInfo;
-import android.net.wifi.WifiConfiguration.EnterpriseField;
 import android.net.wifi.WifiConfiguration.IpAssignment;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiConfiguration.ProxySettings;
@@ -37,6 +36,7 @@
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.UserHandle;
+import android.security.KeyStore;
 import android.text.TextUtils;
 import android.util.Log;
 
@@ -144,6 +144,7 @@
     private static final String EOS = "eos";
 
     private WifiNative mWifiNative;
+    private final KeyStore mKeyStore = KeyStore.getInstance();
 
     WifiConfigStore(Context c, WifiNative wn) {
         mContext = c;
@@ -295,16 +296,7 @@
     boolean forgetNetwork(int netId) {
         if (mWifiNative.removeNetwork(netId)) {
             mWifiNative.saveConfig();
-            WifiConfiguration target = null;
-            WifiConfiguration config = mConfiguredNetworks.get(netId);
-            if (config != null) {
-                target = mConfiguredNetworks.remove(netId);
-                mNetworkIds.remove(configKey(config));
-            }
-            if (target != null) {
-                writeIpAndProxyConfigurations();
-                sendConfiguredNetworksChangedBroadcast(target, WifiManager.CHANGE_REASON_REMOVED);
-            }
+            removeConfigAndSendBroadcastIfNeeded(netId);
             return true;
         } else {
             loge("Failed to remove network " + netId);
@@ -342,20 +334,27 @@
      */
     boolean removeNetwork(int netId) {
         boolean ret = mWifiNative.removeNetwork(netId);
-        WifiConfiguration config = null;
         if (ret) {
-            config = mConfiguredNetworks.get(netId);
-            if (config != null) {
-                config = mConfiguredNetworks.remove(netId);
-                mNetworkIds.remove(configKey(config));
-            }
-        }
-        if (config != null) {
-            sendConfiguredNetworksChangedBroadcast(config, WifiManager.CHANGE_REASON_REMOVED);
+            removeConfigAndSendBroadcastIfNeeded(netId);
         }
         return ret;
     }
 
+    private void removeConfigAndSendBroadcastIfNeeded(int netId) {
+        WifiConfiguration config = mConfiguredNetworks.get(netId);
+        if (config != null) {
+            // Remove any associated keys
+            if (config.enterpriseConfig != null) {
+                config.enterpriseConfig.removeKeys(mKeyStore);
+            }
+            mConfiguredNetworks.remove(netId);
+            mNetworkIds.remove(configKey(config));
+
+            writeIpAndProxyConfigurations();
+            sendConfiguredNetworksChangedBroadcast(config, WifiManager.CHANGE_REASON_REMOVED);
+        }
+    }
+
     /**
      * Enable a network. Note that there is no saveConfig operation.
      * This function is retained for compatibility with the public
@@ -1122,34 +1121,57 @@
                 break setVariables;
             }
 
-            for (WifiConfiguration.EnterpriseField field
-                    : config.enterpriseFields) {
-                String varName = field.varName();
-                String value = field.value();
-                if (value != null) {
-                    if (field == config.engine) {
-                        /*
-                         * If the field is declared as an integer, it must not
-                         * be null
-                         */
-                        if (value.length() == 0) {
-                            value = "0";
-                        }
-                    } else if (field != config.eap) {
-                        value = (value.length() == 0) ? "NULL" : convertToQuotedString(value);
+            if (config.enterpriseConfig != null) {
+
+                WifiEnterpriseConfig enterpriseConfig = config.enterpriseConfig;
+
+                if (enterpriseConfig.needsKeyStore()) {
+                    /**
+                     * Keyguard settings may eventually be controlled by device policy.
+                     * We check here if keystore is unlocked before installing
+                     * credentials.
+                     * TODO: Figure a way to store these credentials for wifi alone
+                     * TODO: Do we need a dialog here ?
+                     */
+                    if (mKeyStore.state() != KeyStore.State.UNLOCKED) {
+                        loge(config.SSID + ": key store is locked");
+                        break setVariables;
                     }
-                    if (!mWifiNative.setNetworkVariable(
-                                netId,
-                                varName,
-                                value)) {
-                        loge(config.SSID + ": failed to set " + varName +
-                                ": " + value);
+
+                    try {
+                        /* config passed may include only fields being updated.
+                         * In order to generate the key id, fetch uninitialized
+                         * fields from the currently tracked configuration
+                         */
+                        WifiConfiguration currentConfig = mConfiguredNetworks.get(netId);
+                        String keyId = config.getKeyIdForCredentials(currentConfig);
+
+                        if (!enterpriseConfig.installKeys(mKeyStore, keyId)) {
+                            loge(config.SSID + ": failed to install keys");
+                            break setVariables;
+                        }
+                    } catch (IllegalStateException e) {
+                        loge(config.SSID + " invalid config for key installation");
                         break setVariables;
                     }
                 }
+
+                HashMap<String, String> enterpriseFields = enterpriseConfig.getFields();
+                for (String key : enterpriseFields.keySet()) {
+                        String value = enterpriseFields.get(key);
+                        if (!mWifiNative.setNetworkVariable(
+                                    netId,
+                                    key,
+                                    value)) {
+                            enterpriseConfig.removeKeys(mKeyStore);
+                            loge(config.SSID + ": failed to set " + key +
+                                    ": " + value);
+                            break setVariables;
+                        }
+                }
             }
             updateFailed = false;
-        }
+        } //end of setVariables
 
         if (updateFailed) {
             if (newNetwork) {
@@ -1445,78 +1467,31 @@
             }
         }
 
-        for (WifiConfiguration.EnterpriseField field :
-                config.enterpriseFields) {
-            value = mWifiNative.getNetworkVariable(netId,
-                    field.varName());
+        if (config.enterpriseConfig == null) {
+            config.enterpriseConfig = new WifiEnterpriseConfig();
+        }
+        HashMap<String, String> enterpriseFields = config.enterpriseConfig.getFields();
+        for (String key : WifiEnterpriseConfig.getSupplicantKeys()) {
+            value = mWifiNative.getNetworkVariable(netId, key);
             if (!TextUtils.isEmpty(value)) {
-                if (field != config.eap && field != config.engine) {
-                    value = removeDoubleQuotes(value);
-                }
-                field.setValue(value);
+                enterpriseFields.put(key, removeDoubleQuotes(value));
+            } else {
+                enterpriseFields.put(key, WifiEnterpriseConfig.EMPTY_VALUE);
             }
         }
 
-        migrateOldEapTlsIfNecessary(config, netId);
-    }
-
-    /**
-     * Migration code for old EAP-TLS configurations. This should only be used
-     * when restoring an old wpa_supplicant.conf or upgrading from a previous
-     * platform version.
-     *
-     * @param config the configuration to be migrated
-     * @param netId the wpa_supplicant's net ID
-     * @param value the old private_key value
-     */
-    private void migrateOldEapTlsIfNecessary(WifiConfiguration config, int netId) {
-        String value = mWifiNative.getNetworkVariable(netId,
-                WifiConfiguration.OLD_PRIVATE_KEY_NAME);
-        /*
-         * If the old configuration value is not present, then there is nothing
-         * to do.
-         */
-        if (TextUtils.isEmpty(value)) {
-            return;
-        } else {
-            // Also ignore it if it's empty quotes.
-            value = removeDoubleQuotes(value);
-            if (TextUtils.isEmpty(value)) {
-                return;
-            }
+        if (config.enterpriseConfig.migrateOldEapTlsNative(mWifiNative, netId)) {
+            saveConfig();
         }
-
-        config.engine.setValue(WifiConfiguration.ENGINE_ENABLE);
-        config.engine_id.setValue(convertToQuotedString(WifiConfiguration.KEYSTORE_ENGINE_ID));
-
-        /*
-         * The old key started with the keystore:// URI prefix, but we don't
-         * need that anymore. Trim it off if it exists.
-         */
-        final String keyName;
-        if (value.startsWith(WifiConfiguration.KEYSTORE_URI)) {
-            keyName = new String(value.substring(WifiConfiguration.KEYSTORE_URI.length()));
-        } else {
-            keyName = value;
-        }
-        config.key_id.setValue(convertToQuotedString(keyName));
-
-        // Now tell the wpa_supplicant the new configuration values.
-        final EnterpriseField needsUpdate[] = { config.engine, config.engine_id, config.key_id };
-        for (EnterpriseField field : needsUpdate) {
-            mWifiNative.setNetworkVariable(netId, field.varName(), field.value());
-        }
-
-        // Remove old private_key string so we don't run this again.
-        mWifiNative.setNetworkVariable(netId, WifiConfiguration.OLD_PRIVATE_KEY_NAME,
-                convertToQuotedString(""));
-
-        saveConfig();
     }
 
     private String removeDoubleQuotes(String string) {
-        if (string.length() <= 2) return "";
-        return string.substring(1, string.length() - 1);
+        int length = string.length();
+        if ((length > 1) && (string.charAt(0) == '"')
+                && (string.charAt(length - 1) == '"')) {
+            return string.substring(1, length - 1);
+        }
+        return string;
     }
 
     private String convertToQuotedString(String string) {
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index c4fe1b4..bf82792 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -19,49 +19,16 @@
 import android.net.LinkProperties;
 import android.os.Parcelable;
 import android.os.Parcel;
+import android.text.TextUtils;
 
 import java.util.BitSet;
 
 /**
  * A class representing a configured Wi-Fi network, including the
- * security configuration. Android will not necessarily support
- * all of these security schemes initially.
+ * security configuration.
  */
 public class WifiConfiguration implements Parcelable {
-
-    /**
-     * In old configurations, the "private_key" field was used. However, newer
-     * configurations use the key_id field with the engine_id set to "keystore".
-     * If this field is found in the configuration, the migration code is
-     * triggered.
-     * @hide
-     */
-    public static final String OLD_PRIVATE_KEY_NAME = "private_key";
-
-    /**
-     * String representing the keystore OpenSSL ENGINE's ID.
-     * @hide
-     */
-    public static final String KEYSTORE_ENGINE_ID = "keystore";
-
-    /**
-     * String representing the keystore URI used for wpa_supplicant.
-     * @hide
-     */
-    public static final String KEYSTORE_URI = "keystore://";
-
-    /**
-     * String to set the engine value to when it should be enabled.
-     * @hide
-     */
-    public static final String ENGINE_ENABLE = "1";
-
-    /**
-     * String to set the engine value to when it should be disabled.
-     * @hide
-     */
-    public static final String ENGINE_DISABLE = "0";
-
+    private static final String TAG = "WifiConfiguration";
     /** {@hide} */
     public static final String ssidVarName = "ssid";
     /** {@hide} */
@@ -78,56 +45,6 @@
     public static final String hiddenSSIDVarName = "scan_ssid";
     /** {@hide} */
     public static final int INVALID_NETWORK_ID = -1;
-
-    /** {@hide} */
-    public class EnterpriseField {
-        private String varName;
-        private String value;
-
-        private EnterpriseField(String varName) {
-            this.varName = varName;
-            this.value = null;
-        }
-
-        public void setValue(String value) {
-            this.value = value;
-        }
-
-        public String varName() {
-            return varName;
-        }
-
-        public String value() {
-            return value;
-        }
-    }
-
-    /** {@hide} */
-    public EnterpriseField eap = new EnterpriseField("eap");
-    /** {@hide} */
-    public EnterpriseField phase2 = new EnterpriseField("phase2");
-    /** {@hide} */
-    public EnterpriseField identity = new EnterpriseField("identity");
-    /** {@hide} */
-    public EnterpriseField anonymous_identity = new EnterpriseField("anonymous_identity");
-    /** {@hide} */
-    public EnterpriseField password = new EnterpriseField("password");
-    /** {@hide} */
-    public EnterpriseField client_cert = new EnterpriseField("client_cert");
-    /** {@hide} */
-    public EnterpriseField engine = new EnterpriseField("engine");
-    /** {@hide} */
-    public EnterpriseField engine_id = new EnterpriseField("engine_id");
-    /** {@hide} */
-    public EnterpriseField key_id = new EnterpriseField("key_id");
-    /** {@hide} */
-    public EnterpriseField ca_cert = new EnterpriseField("ca_cert");
-
-    /** {@hide} */
-    public EnterpriseField[] enterpriseFields = {
-            eap, phase2, identity, anonymous_identity, password, client_cert,
-            engine, engine_id, key_id, ca_cert };
-
     /**
      * Recognized key management schemes.
      */
@@ -357,6 +274,12 @@
      * Defaults to CCMP TKIP WEP104 WEP40.
      */
     public BitSet allowedGroupCiphers;
+    /**
+     * The enterprise configuration details specifying the EAP method,
+     * certificates and other settings associated with the EAP.
+     * @hide
+     */
+    public WifiEnterpriseConfig enterpriseConfig;
 
     /**
      * @hide
@@ -412,11 +335,10 @@
         allowedPairwiseCiphers = new BitSet();
         allowedGroupCiphers = new BitSet();
         wepKeys = new String[4];
-        for (int i = 0; i < wepKeys.length; i++)
+        for (int i = 0; i < wepKeys.length; i++) {
             wepKeys[i] = null;
-        for (EnterpriseField field : enterpriseFields) {
-            field.setValue(null);
         }
+        enterpriseConfig = new WifiEnterpriseConfig();
         ipAssignment = IpAssignment.UNASSIGNED;
         proxySettings = ProxySettings.UNASSIGNED;
         linkProperties = new LinkProperties();
@@ -496,12 +418,9 @@
             sbuf.append('*');
         }
 
-        for (EnterpriseField field : enterpriseFields) {
-            sbuf.append('\n').append(" " + field.varName() + ": ");
-            String value = field.value();
-            if (value != null) sbuf.append(value);
-        }
+        sbuf.append(enterpriseConfig);
         sbuf.append('\n');
+
         sbuf.append("IP assignment: " + ipAssignment.toString());
         sbuf.append("\n");
         sbuf.append("Proxy settings: " + proxySettings.toString());
@@ -545,12 +464,54 @@
         return SSID;
     }
 
+    /**
+     * Get an identifier for associating credentials with this config
+     * @param current configuration contains values for additional fields
+     *                that are not part of this configuration. Used
+     *                when a config with some fields is passed by an application.
+     * @throws IllegalStateException if config is invalid for key id generation
+     * @hide
+     */
+    String getKeyIdForCredentials(WifiConfiguration current) {
+        String keyMgmt = null;
+
+        try {
+            // Get current config details for fields that are not initialized
+            if (TextUtils.isEmpty(SSID)) SSID = current.SSID;
+            if (allowedKeyManagement.cardinality() == 0) {
+                allowedKeyManagement = current.allowedKeyManagement;
+            }
+            if (allowedKeyManagement.get(KeyMgmt.WPA_EAP)) {
+                keyMgmt = KeyMgmt.strings[KeyMgmt.WPA_EAP];
+            }
+            if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
+                keyMgmt += KeyMgmt.strings[KeyMgmt.IEEE8021X];
+            }
+
+            if (TextUtils.isEmpty(keyMgmt)) {
+                throw new IllegalStateException("Not an EAP network");
+            }
+
+            return trimStringForKeyId(SSID) + "_" + keyMgmt + "_" +
+                    trimStringForKeyId(enterpriseConfig.getKeyId(current != null ?
+                            current.enterpriseConfig : null));
+        } catch (NullPointerException e) {
+            throw new IllegalStateException("Invalid config details");
+        }
+    }
+
+    private String trimStringForKeyId(String string) {
+        // Remove quotes and spaces
+        return string.replace("\"", "").replace(" ", "");
+    }
+
     private static BitSet readBitSet(Parcel src) {
         int cardinality = src.readInt();
 
         BitSet set = new BitSet();
-        for (int i = 0; i < cardinality; i++)
+        for (int i = 0; i < cardinality; i++) {
             set.set(src.readInt());
+        }
 
         return set;
     }
@@ -560,12 +521,16 @@
 
         dest.writeInt(set.cardinality());
 
-        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1)
+        while ((nextSetBit = set.nextSetBit(nextSetBit + 1)) != -1) {
             dest.writeInt(nextSetBit);
+        }
     }
 
     /** @hide */
     public int getAuthType() {
+        if (allowedKeyManagement.cardinality() > 1) {
+            throw new IllegalStateException("More than one auth type set");
+        }
         if (allowedKeyManagement.get(KeyMgmt.WPA_PSK)) {
             return KeyMgmt.WPA_PSK;
         } else if (allowedKeyManagement.get(KeyMgmt.WPA2_PSK)) {
@@ -594,8 +559,9 @@
             preSharedKey = source.preSharedKey;
 
             wepKeys = new String[4];
-            for (int i = 0; i < wepKeys.length; i++)
+            for (int i = 0; i < wepKeys.length; i++) {
                 wepKeys[i] = source.wepKeys[i];
+            }
 
             wepTxKeyIndex = source.wepTxKeyIndex;
             priority = source.priority;
@@ -606,9 +572,8 @@
             allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
             allowedGroupCiphers    = (BitSet) source.allowedGroupCiphers.clone();
 
-            for (int i = 0; i < source.enterpriseFields.length; i++) {
-                enterpriseFields[i].setValue(source.enterpriseFields[i].value());
-            }
+            enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);
+
             ipAssignment = source.ipAssignment;
             proxySettings = source.proxySettings;
             linkProperties = new LinkProperties(source.linkProperties);
@@ -623,8 +588,9 @@
         dest.writeString(SSID);
         dest.writeString(BSSID);
         dest.writeString(preSharedKey);
-        for (String wepKey : wepKeys)
+        for (String wepKey : wepKeys) {
             dest.writeString(wepKey);
+        }
         dest.writeInt(wepTxKeyIndex);
         dest.writeInt(priority);
         dest.writeInt(hiddenSSID ? 1 : 0);
@@ -635,9 +601,8 @@
         writeBitSet(dest, allowedPairwiseCiphers);
         writeBitSet(dest, allowedGroupCiphers);
 
-        for (EnterpriseField field : enterpriseFields) {
-            dest.writeString(field.value());
-        }
+        dest.writeParcelable(enterpriseConfig, flags);
+
         dest.writeString(ipAssignment.name());
         dest.writeString(proxySettings.name());
         dest.writeParcelable(linkProperties, flags);
@@ -654,8 +619,9 @@
                 config.SSID = in.readString();
                 config.BSSID = in.readString();
                 config.preSharedKey = in.readString();
-                for (int i = 0; i < config.wepKeys.length; i++)
+                for (int i = 0; i < config.wepKeys.length; i++) {
                     config.wepKeys[i] = in.readString();
+                }
                 config.wepTxKeyIndex = in.readInt();
                 config.priority = in.readInt();
                 config.hiddenSSID = in.readInt() != 0;
@@ -665,13 +631,12 @@
                 config.allowedPairwiseCiphers = readBitSet(in);
                 config.allowedGroupCiphers    = readBitSet(in);
 
-                for (EnterpriseField field : config.enterpriseFields) {
-                    field.setValue(in.readString());
-                }
+                config.enterpriseConfig = in.readParcelable(null);
 
                 config.ipAssignment = IpAssignment.valueOf(in.readString());
                 config.proxySettings = ProxySettings.valueOf(in.readString());
                 config.linkProperties = in.readParcelable(null);
+
                 return config;
             }
 
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl b/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl
new file mode 100644
index 0000000..b0f5f84
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2013, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+parcelable WifiEnterpriseConfig;
diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
new file mode 100644
index 0000000..7313e7e
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java
@@ -0,0 +1,666 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.net.wifi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.security.Credentials;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.org.bouncycastle.asn1.ASN1InputStream;
+import com.android.org.bouncycastle.asn1.ASN1Sequence;
+import com.android.org.bouncycastle.asn1.DEROctetString;
+import com.android.org.bouncycastle.asn1.x509.BasicConstraints;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.KeyFactory;
+import java.security.KeyStore;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.util.HashMap;
+import java.util.Map;
+
+/** Enterprise configuration details for Wi-Fi @hide */
+public class WifiEnterpriseConfig implements Parcelable {
+    private static final String TAG = "WifiEnterpriseConfig";
+    /**
+     * In old configurations, the "private_key" field was used. However, newer
+     * configurations use the key_id field with the engine_id set to "keystore".
+     * If this field is found in the configuration, the migration code is
+     * triggered.
+     */
+    private static final String OLD_PRIVATE_KEY_NAME = "private_key";
+
+    /**
+     * String representing the keystore OpenSSL ENGINE's ID.
+     */
+    private static final String ENGINE_ID_KEYSTORE = "keystore";
+
+    /**
+     * String representing the keystore URI used for wpa_supplicant.
+     */
+    private static final String KEYSTORE_URI = "keystore://";
+
+    /**
+     * String to set the engine value to when it should be enabled.
+     */
+    private static final String ENGINE_ENABLE = "1";
+
+    /**
+     * String to set the engine value to when it should be disabled.
+     */
+    private static final String ENGINE_DISABLE = "0";
+
+    private static final String CA_CERT_PREFIX = KEYSTORE_URI + Credentials.CA_CERTIFICATE;
+    private static final String CLIENT_CERT_PREFIX = KEYSTORE_URI + Credentials.USER_CERTIFICATE;
+
+    private static final String EAP_KEY             = "eap";
+    private static final String PHASE2_KEY          = "phase2";
+    private static final String IDENTITY_KEY        = "identity";
+    private static final String ANON_IDENTITY_KEY   = "anonymous_identity";
+    private static final String PASSWORD_KEY        = "password";
+    private static final String CLIENT_CERT_KEY     = "client_cert";
+    private static final String CA_CERT_KEY         = "ca_cert";
+    private static final String SUBJECT_MATCH_KEY   = "subject_match";
+    private static final String ENGINE_KEY          = "engine";
+    private static final String ENGINE_ID_KEY       = "engine_id";
+    private static final String PRIVATE_KEY_ID_KEY  = "key_id";
+
+    private HashMap<String, String> mFields = new HashMap<String, String>();
+    private X509Certificate mCaCert;
+    private PrivateKey mClientPrivateKey;
+    private X509Certificate mClientCertificate;
+
+    /** This represents an empty value of an enterprise field.
+     * NULL is used at wpa_supplicant to indicate an empty value
+     */
+    static final String EMPTY_VALUE = "NULL";
+
+    public WifiEnterpriseConfig() {
+        // Do not set defaults so that the enterprise fields that are not changed
+        // by API are not changed underneath
+        // This is essential because an app may not have all fields like password
+        // available. It allows modification of subset of fields.
+
+    }
+
+    /** Copy constructor */
+    public WifiEnterpriseConfig(WifiEnterpriseConfig source) {
+        for (String key : source.mFields.keySet()) {
+            mFields.put(key, source.mFields.get(key));
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mFields.size());
+        for (Map.Entry<String, String> entry : mFields.entrySet()) {
+            dest.writeString(entry.getKey());
+            dest.writeString(entry.getValue());
+        }
+
+        writeCertificate(dest, mCaCert);
+
+        if (mClientPrivateKey != null) {
+            String algorithm = mClientPrivateKey.getAlgorithm();
+            byte[] userKeyBytes = mClientPrivateKey.getEncoded();
+            dest.writeInt(userKeyBytes.length);
+            dest.writeByteArray(userKeyBytes);
+            dest.writeString(algorithm);
+        } else {
+            dest.writeInt(0);
+        }
+
+        writeCertificate(dest, mClientCertificate);
+    }
+
+    private void writeCertificate(Parcel dest, X509Certificate cert) {
+        if (cert != null) {
+            try {
+                byte[] certBytes = cert.getEncoded();
+                dest.writeInt(certBytes.length);
+                dest.writeByteArray(certBytes);
+            } catch (CertificateEncodingException e) {
+                dest.writeInt(0);
+            }
+        } else {
+            dest.writeInt(0);
+        }
+    }
+
+    public static final Creator<WifiEnterpriseConfig> CREATOR =
+            new Creator<WifiEnterpriseConfig>() {
+                public WifiEnterpriseConfig createFromParcel(Parcel in) {
+                    WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+                    int count = in.readInt();
+                    for (int i = 0; i < count; i++) {
+                        String key = in.readString();
+                        String value = in.readString();
+                        enterpriseConfig.mFields.put(key, value);
+                    }
+
+                    enterpriseConfig.mCaCert = readCertificate(in);
+
+                    PrivateKey userKey = null;
+                    int len = in.readInt();
+                    if (len > 0) {
+                        try {
+                            byte[] bytes = new byte[len];
+                            in.readByteArray(bytes);
+                            String algorithm = in.readString();
+                            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
+                            userKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(bytes));
+                        } catch (NoSuchAlgorithmException e) {
+                            userKey = null;
+                        } catch (InvalidKeySpecException e) {
+                            userKey = null;
+                        }
+                    }
+
+                    enterpriseConfig.mClientPrivateKey = userKey;
+                    enterpriseConfig.mClientCertificate = readCertificate(in);
+                    return enterpriseConfig;
+                }
+
+                private X509Certificate readCertificate(Parcel in) {
+                    X509Certificate cert = null;
+                    int len = in.readInt();
+                    if (len > 0) {
+                        try {
+                            byte[] bytes = new byte[len];
+                            in.readByteArray(bytes);
+                            CertificateFactory cFactory = CertificateFactory.getInstance("X.509");
+                            cert = (X509Certificate) cFactory
+                                    .generateCertificate(new ByteArrayInputStream(bytes));
+                        } catch (CertificateException e) {
+                            cert = null;
+                        }
+                    }
+                    return cert;
+                }
+
+                public WifiEnterpriseConfig[] newArray(int size) {
+                    return new WifiEnterpriseConfig[size];
+                }
+            };
+
+    public static final class Eap {
+        /* NONE represents an empty enterprise config */
+        public static final int NONE    = -1;
+        public static final int PEAP    = 0;
+        public static final int TLS     = 1;
+        public static final int TTLS    = 2;
+        public static final int PWD     = 3;
+        /** @hide */
+        public static final String[] strings = { "PEAP", "TLS", "TTLS", "PWD" };
+    }
+
+    public static final class Phase2 {
+        public static final int NONE        = 0;
+        public static final int PAP         = 1;
+        public static final int MSCHAP      = 2;
+        public static final int MSCHAPV2    = 3;
+        public static final int GTC         = 4;
+        private static final String PREFIX = "auth=";
+        /** @hide */
+        public static final String[] strings = {EMPTY_VALUE, "PAP", "MSCHAP", "MSCHAPV2", "GTC" };
+    }
+
+    /** Internal use only */
+    HashMap<String, String> getFields() {
+        return mFields;
+    }
+
+    /** Internal use only */
+    static String[] getSupplicantKeys() {
+        return new String[] { EAP_KEY, PHASE2_KEY, IDENTITY_KEY, ANON_IDENTITY_KEY, PASSWORD_KEY,
+                CLIENT_CERT_KEY, CA_CERT_KEY, SUBJECT_MATCH_KEY, ENGINE_KEY, ENGINE_ID_KEY,
+                PRIVATE_KEY_ID_KEY };
+    }
+
+    /**
+     * Set the EAP authentication method.
+     * @param  eapMethod is one {@link Eap#PEAP}, {@link Eap#TLS}, {@link Eap#TTLS} or
+     *                   {@link Eap#PWD}
+     */
+    public void setEapMethod(int eapMethod) {
+        switch (eapMethod) {
+            /** Valid methods */
+            case Eap.PEAP:
+            case Eap.PWD:
+            case Eap.TLS:
+            case Eap.TTLS:
+                mFields.put(EAP_KEY, Eap.strings[eapMethod]);
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown EAP method");
+        }
+    }
+
+    /**
+     * Get the eap method.
+     * @return eap method configured
+     */
+    public int getEapMethod() {
+        String eapMethod  = mFields.get(EAP_KEY);
+        return getStringIndex(Eap.strings, eapMethod, Eap.NONE);
+    }
+
+    /**
+     * Set Phase 2 authentication method. Sets the inner authentication method to be used in
+     * phase 2 after setting up a secure channel
+     * @param phase2Method is the inner authentication method and can be one of {@link Phase2#NONE},
+     *                     {@link Phase2#PAP}, {@link Phase2#MSCHAP}, {@link Phase2#MSCHAPV2},
+     *                     {@link Phase2#GTC}
+     *
+     */
+    public void setPhase2Method(int phase2Method) {
+        switch (phase2Method) {
+            case Phase2.NONE:
+                mFields.put(PHASE2_KEY, EMPTY_VALUE);
+                break;
+            /** Valid methods */
+            case Phase2.PAP:
+            case Phase2.MSCHAP:
+            case Phase2.MSCHAPV2:
+            case Phase2.GTC:
+                mFields.put(PHASE2_KEY, convertToQuotedString(
+                        Phase2.PREFIX + Phase2.strings[phase2Method]));
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown Phase 2 method");
+        }
+    }
+
+    /**
+     * Get the phase 2 authentication method.
+     * @return a phase 2 method defined at {@link Phase2}
+     * */
+    public int getPhase2Method() {
+        String phase2Method = removeDoubleQuotes(mFields.get(PHASE2_KEY));
+        // Remove auth= prefix
+        if (phase2Method.startsWith(Phase2.PREFIX)) {
+            phase2Method = phase2Method.substring(Phase2.PREFIX.length());
+        }
+        return getStringIndex(Phase2.strings, phase2Method, Phase2.NONE);
+    }
+
+    /**
+     * Set the identity
+     * @param identity
+     */
+    public void setIdentity(String identity) {
+        setFieldValue(IDENTITY_KEY, identity, "");
+    }
+
+    /**
+     * Get the identity
+     * @return the identity
+     */
+    public String getIdentity() {
+        return getFieldValue(IDENTITY_KEY, "");
+    }
+
+    /**
+     * Set anonymous identity. This is used as the unencrypted identity with
+     * certain EAP types
+     * @param anonymousIdentity the anonymous identity
+     */
+    public void setAnonymousIdentity(String anonymousIdentity) {
+        setFieldValue(ANON_IDENTITY_KEY, anonymousIdentity, "");
+    }
+
+    /** Get the anonymous identity
+     * @return anonymous identity
+     */
+    public String getAnonymousIdentity() {
+        return getFieldValue(ANON_IDENTITY_KEY, "");
+    }
+
+    /**
+     * Set the password.
+     * @param password the password
+     */
+    public void setPassword(String password) {
+        setFieldValue(PASSWORD_KEY, password, "");
+    }
+
+    /**
+     * Set CA certificate alias.
+     *
+     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
+     * a certificate
+     * </p>
+     * @param alias identifies the certificate
+     * @hide
+     */
+    public void setCaCertificateAlias(String alias) {
+        setFieldValue(CA_CERT_KEY, alias, CA_CERT_PREFIX);
+    }
+
+    /**
+     * Get CA certificate alias
+     * @return alias to the CA certificate
+     * @hide
+     */
+    public String getCaCertificateAlias() {
+        return getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
+    }
+
+    /**
+     * Specify a X.509 certificate that identifies the server.
+     *
+     * <p>A default name is automatically assigned to the certificate and used
+     * with this configuration.
+     * @param cert X.509 CA certificate
+     * @throws IllegalArgumentException if not a CA certificate
+     */
+    public void setCaCertificate(X509Certificate cert) {
+        if (cert.getBasicConstraints() >= 0) {
+            mCaCert = cert;
+        } else {
+            throw new IllegalArgumentException("Not a CA certificate");
+        }
+    }
+
+    /**
+     * Set Client certificate alias.
+     *
+     * <p> See the {@link android.security.KeyChain} for details on installing or choosing
+     * a certificate
+     * </p>
+     * @param alias identifies the certificate
+     * @hide
+     */
+    public void setClientCertificateAlias(String alias) {
+        setFieldValue(CLIENT_CERT_KEY, alias, CLIENT_CERT_PREFIX);
+        setFieldValue(PRIVATE_KEY_ID_KEY, alias, Credentials.USER_PRIVATE_KEY);
+        // Also, set engine parameters
+        if (TextUtils.isEmpty(alias)) {
+            mFields.put(ENGINE_KEY, ENGINE_DISABLE);
+            mFields.put(ENGINE_ID_KEY, EMPTY_VALUE);
+        } else {
+            mFields.put(ENGINE_KEY, ENGINE_ENABLE);
+            mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE));
+        }
+    }
+
+    /**
+     * Get client certificate alias
+     * @return alias to the client certificate
+     * @hide
+     */
+    public String getClientCertificateAlias() {
+        return getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
+    }
+
+    /**
+     * Specify a private key and client certificate for client authorization.
+     *
+     * <p>A default name is automatically assigned to the key entry and used
+     * with this configuration.
+     * @param privateKey
+     * @param clientCertificate
+     */
+    public void setClientKeyEntry(PrivateKey privateKey, X509Certificate clientCertificate) {
+        if (clientCertificate != null) {
+            if (clientCertificate.getBasicConstraints() != -1) {
+                throw new IllegalArgumentException("Cannot be a CA certificate");
+            }
+            if (privateKey == null) {
+                throw new IllegalArgumentException("Client cert without a private key");
+            }
+            if (privateKey.getEncoded() == null) {
+                throw new IllegalArgumentException("Private key cannot be encoded");
+            }
+        }
+
+        mClientPrivateKey = privateKey;
+        mClientCertificate = clientCertificate;
+    }
+
+    boolean needsKeyStore() {
+        // Has no keys to be installed
+        if (mClientCertificate == null && mCaCert == null) return false;
+        return true;
+    }
+
+    boolean installKeys(android.security.KeyStore keyStore, String name) {
+        boolean ret = true;
+        String privKeyName = Credentials.USER_PRIVATE_KEY + name;
+        String userCertName = Credentials.USER_CERTIFICATE + name;
+        String caCertName = Credentials.CA_CERTIFICATE + name;
+        if (mClientCertificate != null) {
+            byte[] privKeyData = mClientPrivateKey.getEncoded();
+            ret = keyStore.importKey(privKeyName, privKeyData);
+            if (ret == false) {
+                return ret;
+            }
+
+            ret = putCertInKeyStore(keyStore, userCertName, mClientCertificate);
+            if (ret == false) {
+                // Remove private key installed
+                keyStore.delKey(privKeyName);
+                return ret;
+            }
+        }
+
+        if (mCaCert != null) {
+            ret = putCertInKeyStore(keyStore, caCertName, mCaCert);
+            if (ret == false) {
+                if (mClientCertificate != null) {
+                    // Remove client key+cert
+                    keyStore.delKey(privKeyName);
+                    keyStore.delete(userCertName);
+                }
+                return ret;
+            }
+        }
+
+        // Set alias names
+        if (mClientCertificate != null) {
+            setClientCertificateAlias(name);
+            mClientPrivateKey = null;
+            mClientCertificate = null;
+        }
+
+        if (mCaCert != null) {
+            setCaCertificateAlias(name);
+            mCaCert = null;
+        }
+
+        return ret;
+    }
+
+    private boolean putCertInKeyStore(android.security.KeyStore keyStore, String name,
+            Certificate cert) {
+        try {
+            byte[] certData = Credentials.convertToPem(cert);
+            return keyStore.put(name, certData);
+        } catch (IOException e1) {
+            return false;
+        } catch (CertificateException e2) {
+            return false;
+        }
+    }
+
+    void removeKeys(android.security.KeyStore keyStore) {
+        String client = getFieldValue(CLIENT_CERT_KEY, CLIENT_CERT_PREFIX);
+        // a valid client certificate is configured
+        if (!TextUtils.isEmpty(client)) {
+            keyStore.delKey(Credentials.USER_PRIVATE_KEY + client);
+            keyStore.delete(Credentials.USER_CERTIFICATE + client);
+        }
+
+        String ca = getFieldValue(CA_CERT_KEY, CA_CERT_PREFIX);
+        // a valid ca certificate is configured
+        if (!TextUtils.isEmpty(ca)) {
+            keyStore.delete(Credentials.CA_CERTIFICATE + ca);
+        }
+    }
+
+    /**
+     * Set subject match. This is the substring to be matched against the subject of the
+     * authentication server certificate.
+     * @param subjectMatch substring to be matched
+     */
+    public void setSubjectMatch(String subjectMatch) {
+        setFieldValue(SUBJECT_MATCH_KEY, subjectMatch, "");
+    }
+
+    /**
+     * Get subject match
+     * @return the subject match string
+     */
+    public String getSubjectMatch() {
+        return getFieldValue(SUBJECT_MATCH_KEY, "");
+    }
+
+    /** See {@link WifiConfiguration#getKeyIdForCredentials} @hide */
+    String getKeyId(WifiEnterpriseConfig current) {
+        String eap = mFields.get(EAP_KEY);
+        String phase2 = mFields.get(PHASE2_KEY);
+
+        // If either eap or phase2 are not initialized, use current config details
+        if (TextUtils.isEmpty((eap))) {
+            eap = current.mFields.get(EAP_KEY);
+        }
+        if (TextUtils.isEmpty(phase2)) {
+            phase2 = current.mFields.get(PHASE2_KEY);
+        }
+        return eap + "_" + phase2;
+    }
+
+    /** Migrates the old style TLS config to the new config style. This should only be used
+     * when restoring an old wpa_supplicant.conf or upgrading from a previous
+     * platform version.
+     * @return true if the config was updated
+     * @hide
+     */
+    boolean migrateOldEapTlsNative(WifiNative wifiNative, int netId) {
+        String oldPrivateKey = wifiNative.getNetworkVariable(netId, OLD_PRIVATE_KEY_NAME);
+        /*
+         * If the old configuration value is not present, then there is nothing
+         * to do.
+         */
+        if (TextUtils.isEmpty(oldPrivateKey)) {
+            return false;
+        } else {
+            // Also ignore it if it's empty quotes.
+            oldPrivateKey = removeDoubleQuotes(oldPrivateKey);
+            if (TextUtils.isEmpty(oldPrivateKey)) {
+                return false;
+            }
+        }
+
+        mFields.put(ENGINE_KEY, ENGINE_ENABLE);
+        mFields.put(ENGINE_ID_KEY, convertToQuotedString(ENGINE_ID_KEYSTORE));
+
+        /*
+        * The old key started with the keystore:// URI prefix, but we don't
+        * need that anymore. Trim it off if it exists.
+        */
+        final String keyName;
+        if (oldPrivateKey.startsWith(KEYSTORE_URI)) {
+            keyName = new String(oldPrivateKey.substring(KEYSTORE_URI.length()));
+        } else {
+            keyName = oldPrivateKey;
+        }
+        mFields.put(PRIVATE_KEY_ID_KEY, convertToQuotedString(keyName));
+
+        wifiNative.setNetworkVariable(netId, ENGINE_KEY, mFields.get(ENGINE_KEY));
+        wifiNative.setNetworkVariable(netId, ENGINE_ID_KEY, mFields.get(ENGINE_ID_KEY));
+        wifiNative.setNetworkVariable(netId, PRIVATE_KEY_ID_KEY, mFields.get(PRIVATE_KEY_ID_KEY));
+        // Remove old private_key string so we don't run this again.
+        wifiNative.setNetworkVariable(netId, OLD_PRIVATE_KEY_NAME, EMPTY_VALUE);
+        return true;
+    }
+
+    private String removeDoubleQuotes(String string) {
+        int length = string.length();
+        if ((length > 1) && (string.charAt(0) == '"')
+                && (string.charAt(length - 1) == '"')) {
+            return string.substring(1, length - 1);
+        }
+        return string;
+    }
+
+    private String convertToQuotedString(String string) {
+        return "\"" + string + "\"";
+    }
+
+    /** Returns the index at which the toBeFound string is found in the array.
+     * @param arr array of strings
+     * @param toBeFound string to be found
+     * @param defaultIndex default index to be returned when string is not found
+     * @return the index into array
+     */
+    private int getStringIndex(String arr[], String toBeFound, int defaultIndex) {
+        if (TextUtils.isEmpty(toBeFound)) return defaultIndex;
+        for (int i = 0; i < arr.length; i++) {
+            if (toBeFound.equals(arr[i])) return i;
+        }
+        return defaultIndex;
+    }
+
+    /** Returns the field value for the key.
+     * @param key into the hash
+     * @param prefix is the prefix that the value may have
+     * @return value
+     */
+    private String getFieldValue(String key, String prefix) {
+        String value = mFields.get(key);
+        // Uninitialized or known to be empty after reading from supplicant
+        if (TextUtils.isEmpty(value) || EMPTY_VALUE.equals(value)) return "";
+        return removeDoubleQuotes(value).substring(prefix.length());
+    }
+
+    /** Set a value with an optional prefix at key
+     * @param key into the hash
+     * @param value to be set
+     * @param prefix an optional value to be prefixed to actual value
+     */
+    private void setFieldValue(String key, String value, String prefix) {
+        if (TextUtils.isEmpty(value)) {
+            mFields.put(key, EMPTY_VALUE);
+        } else {
+            mFields.put(key, convertToQuotedString(prefix + value));
+        }
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        for (String key : mFields.keySet()) {
+            sb.append(key).append(" ").append(mFields.get(key)).append("\n");
+        }
+        return sb.toString();
+    }
+}
