Snap for 6439596 from c0736f6c497f1682a654a8bc1d72ff506afea72e to qt-aml-tzdata-release

Change-Id: I9e05059edc6da35c519bdf4931a51c742d377b9e
diff --git a/Android.bp b/Android.bp
deleted file mode 100644
index 8d2d16f..0000000
--- a/Android.bp
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2018 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.
-
-java_library {
-    name: "ike",
-    installable: true,
-
-    aidl: {
-        local_include_dirs: ["src/java"],
-    },
-    srcs: ["src/java/**/*.java"],
-}
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..14e9e9e
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,30 @@
+# Copyright 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/src/java
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src/java)
+
+LOCAL_JAVA_LIBRARIES := bouncycastle NetworkStackBase
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := ike
+
+include $(BUILD_JAVA_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/OWNERS b/OWNERS
index c0dd63c..19fe35d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,5 +1,5 @@
 benedictwong@google.com
-ckesting@google.com
+ek@google.com
 evitayan@google.com
 jchalard@google.com
 lorenzo@google.com
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 71d96ff..6534d88 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,10 +3,5 @@
     {
       "name": "FrameworksIkeTests"
     }
-  ],
-  "postsubmit": [
-    {
-      "name": "FrameworksIkeTests"
-    }
   ]
 }
\ No newline at end of file
diff --git a/src/java/android/net/eap/EapSessionConfig.java b/src/java/android/net/eap/EapSessionConfig.java
deleted file mode 100644
index a31a0fd..0000000
--- a/src/java/android/net/eap/EapSessionConfig.java
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.eap;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-
-import android.telephony.TelephonyManager.UiccAppType;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * EapSessionConfig represents a container for EAP method configs to be used within an IKEv2
- * session.
- *
- * <p>The EAP authentication server decides which EAP method is used, so clients are encouraged to
- * provide configs for several EAP methods.
- */
-public final class EapSessionConfig {
-    @VisibleForTesting
-    static final byte[] DEFAULT_IDENTITY = new byte[0];
-
-    // IANA -> EapMethodConfig for that method
-    public final Map<Integer, EapMethodConfig> eapConfigs;
-    public final byte[] eapIdentity;
-
-    @VisibleForTesting
-    public EapSessionConfig(Map<Integer, EapMethodConfig> eapConfigs, byte[] eapIdentity) {
-        this.eapConfigs = Collections.unmodifiableMap(eapConfigs);
-        this.eapIdentity = eapIdentity;
-    }
-
-    /** This class can be used to incrementally construct an EapSessionConfig. */
-    public static final class Builder {
-        private final Map<Integer, EapMethodConfig> mEapConfigs;
-        private byte[] mEapIdentity;
-
-        /**
-         * Constructs and returns a new Builder for constructing an EapSessionConfig.
-         */
-        public Builder() {
-            mEapConfigs = new HashMap<>();
-            mEapIdentity = DEFAULT_IDENTITY;
-        }
-
-        /**
-         * Sets the client's EAP Identity.
-         *
-         * @param eapIdentity byte[] representing the client's EAP Identity
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setEapIdentity(byte[] eapIdentity) {
-            this.mEapIdentity = eapIdentity.clone();
-            return this;
-        }
-
-        /**
-         * Sets the configuration for EAP SIM.
-         *
-         * @param subId int the client's subId to be authenticated
-         * @param apptype the {@link UiccAppType} apptype to be used for authentication
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setEapSimConfig(int subId, @UiccAppType int apptype) {
-            mEapConfigs.put(EAP_TYPE_SIM, new EapSimConfig(subId, apptype));
-            return this;
-        }
-
-        /**
-         * Sets the configuration for EAP AKA.
-         *
-         * @param subId int the client's subId to be authenticated
-         * @param apptype the {@link UiccAppType} apptype to be used for authentication
-         * @return Builder this, to facilitate chaining
-         */
-        public Builder setEapAkaConfig(int subId, @UiccAppType int apptype) {
-            mEapConfigs.put(EAP_TYPE_AKA, new EapAkaConfig(subId, apptype));
-            return this;
-        }
-
-        /**
-         * Sets the configuration for EAP AKA'.
-         *
-         * @param subId int the client's subId to be authenticated
-         * @param apptype the {@link UiccAppType} apptype to be used for authentication
-         * @param networkName String the network name to be used for authentication. The String must
-         *     be a UTF-8 String value
-         * @param allowMismatchedNetworkNames indicates whether the EAP library can ignore potential
-         *     mismatches between the given network name and that received in an EAP-AKA' session.
-         *     If false, mismatched network names will be handled as an Authentication Reject
-         *     message.
-         * @return Builder this, to facilitate chaining
-         */
-        public Builder setEapAkaPrimeConfig(
-                int subId,
-                @UiccAppType int apptype,
-                String networkName,
-                boolean allowMismatchedNetworkNames) {
-            mEapConfigs.put(
-                    EAP_TYPE_AKA_PRIME,
-                    new EapAkaPrimeConfig(
-                            subId, apptype, networkName, allowMismatchedNetworkNames));
-            return this;
-        }
-
-        /**
-         * Sets the configuration for EAP MSCHAPv2.
-         *
-         * @param username String the client account's username to be authenticated
-         * @param password String the client account's password to be authenticated
-         * @return Builder this, to faciliate chaining
-         */
-        public Builder setEapMsChapV2Config(String username, String password) {
-            mEapConfigs.put(EAP_TYPE_MSCHAP_V2, new EapMsChapV2Config(username, password));
-            return this;
-        }
-
-        /**
-         * Constructs and returns an EapSessionConfig with the configurations applied to this
-         * Builder.
-         *
-         * @return the EapSessionConfig constructed by this Builder
-         * @throws IllegalStateException iff no EAP methods have been configured
-         */
-        public EapSessionConfig build() {
-            if (mEapConfigs.isEmpty()) {
-                throw new IllegalStateException("Must have at least one EAP method configured");
-            }
-
-            return new EapSessionConfig(mEapConfigs, mEapIdentity);
-        }
-    }
-
-    /** EapMethodConfig represents a generic EAP method configuration. */
-    public abstract static class EapMethodConfig {
-        @EapMethod public final int methodType;
-
-        protected EapMethodConfig(@EapMethod int methodType) {
-            this.methodType = methodType;
-        }
-    }
-
-    /**
-     * EapUiccConfig represents the configs needed for EAP methods that rely on UICC cards for
-     * authentication.
-     */
-    public abstract static class EapUiccConfig extends EapMethodConfig {
-        public final int subId;
-        public final int apptype;
-
-        private EapUiccConfig(@EapMethod int methodType, int subId, @UiccAppType int apptype) {
-            super(methodType);
-            this.subId = subId;
-            this.apptype = apptype;
-        }
-    }
-
-    /**
-     * EapSimConfig represents the configs needed for an EAP SIM session.
-     */
-    public static class EapSimConfig extends EapUiccConfig {
-        @VisibleForTesting
-        public EapSimConfig(int subId, @UiccAppType int apptype) {
-            super(EAP_TYPE_SIM, subId, apptype);
-        }
-    }
-
-    /**
-     * EapAkaConfig represents the configs needed for an EAP AKA session.
-     */
-    public static class EapAkaConfig extends EapUiccConfig {
-        @VisibleForTesting
-        public EapAkaConfig(int subId, @UiccAppType int apptype) {
-            super(EAP_TYPE_AKA, subId, apptype);
-        }
-    }
-
-    /**
-     * EapAkaPrimeConfig represents the configs needed for an EAP-AKA' session.
-     */
-    public static class EapAkaPrimeConfig extends EapAkaConfig {
-        public final String networkName;
-        public final boolean allowMismatchedNetworkNames;
-
-        @VisibleForTesting
-        public EapAkaPrimeConfig(
-                int subId,
-                @UiccAppType int apptype,
-                String networkName,
-                boolean allowMismatchedNetworkNames) {
-            super(subId, apptype);
-
-            this.networkName = networkName;
-            this.allowMismatchedNetworkNames = allowMismatchedNetworkNames;
-        }
-    }
-
-    /**
-     * EapMsChapV2Config represents the configs needed for an EAP MSCHAPv2 session.
-     */
-    public static class EapMsChapV2Config extends EapMethodConfig {
-        public final String username;
-        public final String password;
-
-        @VisibleForTesting
-        public EapMsChapV2Config(String username, String password) {
-            super(EAP_TYPE_MSCHAP_V2);
-
-            this.username = username;
-            this.password = password;
-        }
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/ChildSaProposal.java b/src/java/android/net/ipsec/ike/ChildSaProposal.java
deleted file mode 100644
index c8851a7..0000000
--- a/src/java/android/net/ipsec/ike/ChildSaProposal.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EsnTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
-
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * ChildSaProposal represents a user configured set contains cryptograhic algorithms and key
- * generating materials for negotiating an Child SA.
- *
- * <p>User must provide at least a valid ChildSaProposal when they are creating a new Child SA.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class ChildSaProposal extends SaProposal {
-    private final EsnTransform[] mEsns;
-
-    /**
-     * Construct an instance of ChildSaProposal.
-     *
-     * <p>This constructor is either called by ChildSaPayload for building an inbound proposal from
-     * a decoded packet, or called by the inner Builder to build an outbound proposal from user
-     * provided parameters
-     *
-     * @param encryptionAlgos encryption algorithms
-     * @param integrityAlgos integrity algorithms
-     * @param dhGroups Diffie-Hellman Groups
-     * @param esns ESN policies
-     */
-    public ChildSaProposal(
-            EncryptionTransform[] encryptionAlgos,
-            IntegrityTransform[] integrityAlgos,
-            DhGroupTransform[] dhGroups,
-            EsnTransform[] esns) {
-        super(IkePayload.PROTOCOL_ID_ESP, encryptionAlgos, integrityAlgos, dhGroups);
-        mEsns = esns;
-    }
-
-    /** Gets all ESN policies. */
-    public EsnTransform[] getEsnTransforms() {
-        return mEsns;
-    }
-
-    /**
-     * Gets a copy of proposal without all proposed DH groups.
-     *
-     * <p>This is used to avoid negotiating DH Group for negotiating first Child SA.
-     */
-    public ChildSaProposal getCopyWithoutDhTransform() {
-        return new ChildSaProposal(
-                getEncryptionTransforms(),
-                getIntegrityTransforms(),
-                new DhGroupTransform[0],
-                getEsnTransforms());
-    }
-
-    @Override
-    public Transform[] getAllTransforms() {
-        List<Transform> transformList = getAllTransformsAsList();
-        transformList.addAll(Arrays.asList(mEsns));
-
-        return transformList.toArray(new Transform[transformList.size()]);
-    }
-
-    @Override
-    public boolean isNegotiatedFrom(SaProposal reqProposal) {
-        return super.isNegotiatedFrom(reqProposal)
-                && isTransformSelectedFrom(mEsns, ((ChildSaProposal) reqProposal).mEsns);
-    }
-
-    /**
-     * This class can be used to incrementally construct a ChildSaProposal. ChildSaProposal
-     * instances are immutable once built.
-     *
-     * <p>TODO: Support users to add algorithms from most preferred to least preferred.
-     */
-    public static final class Builder extends SaProposal.Builder {
-        /**
-         * Adds an encryption algorithm with specific key length to SA proposal being built.
-         *
-         * @param algorithm encryption algorithm to add to ChildSaProposal.
-         * @param keyLength key length of algorithm. For algorithm that has fixed key length (e.g.
-         *     3DES) only KEY_LEN_UNUSED is allowed.
-         * @return Builder of ChildSaProposal.
-         * @throws IllegalArgumentException if AEAD and non-combined mode algorithms are mixed.
-         */
-        public Builder addEncryptionAlgorithm(@EncryptionAlgorithm int algorithm, int keyLength) {
-            validateAndAddEncryptAlgo(algorithm, keyLength);
-            return this;
-        }
-
-        /**
-         * Adds an integrity algorithm to SA proposal being built.
-         *
-         * @param algorithm integrity algorithm to add to ChildSaProposal.
-         * @return Builder of ChildSaProposal.
-         */
-        public Builder addIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) {
-            addIntegrityAlgo(algorithm);
-            return this;
-        }
-
-        /**
-         * Adds a Diffie-Hellman Group to SA proposal being built.
-         *
-         * @param dhGroup to add to ChildSaProposal.
-         * @return Builder of ChildSaProposal.
-         */
-        public Builder addDhGroup(@DhGroup int dhGroup) {
-            addDh(dhGroup);
-            return this;
-        }
-
-        private IntegrityTransform[] buildIntegAlgosOrThrow() {
-            // When building Child SA Proposal with normal-mode ciphers, there is no contraint on
-            // integrity algorithm. When building Child SA Proposal with combined-mode ciphers,
-            // mProposedIntegrityAlgos must be either empty or only have INTEGRITY_ALGORITHM_NONE.
-            for (IntegrityTransform transform : mProposedIntegrityAlgos) {
-                if (transform.id != INTEGRITY_ALGORITHM_NONE && mHasAead) {
-                    throw new IllegalArgumentException(
-                            ERROR_TAG
-                                    + "Only INTEGRITY_ALGORITHM_NONE can be"
-                                    + " proposed with combined-mode ciphers in any proposal.");
-                }
-            }
-
-            return mProposedIntegrityAlgos.toArray(
-                    new IntegrityTransform[mProposedIntegrityAlgos.size()]);
-        }
-
-        /**
-         * Validates, builds and returns the ChildSaProposal
-         *
-         * @return the validated ChildSaProposal.
-         * @throws IllegalArgumentException if ChildSaProposal is invalid.
-         */
-        public ChildSaProposal build() {
-            EncryptionTransform[] encryptionTransforms = buildEncryptAlgosOrThrow();
-            IntegrityTransform[] integrityTransforms = buildIntegAlgosOrThrow();
-
-            return new ChildSaProposal(
-                    encryptionTransforms,
-                    integrityTransforms,
-                    mProposedDhGroups.toArray(new DhGroupTransform[mProposedDhGroups.size()]),
-                    new EsnTransform[] {new EsnTransform()});
-        }
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/ChildSessionCallback.java b/src/java/android/net/ipsec/ike/ChildSessionCallback.java
deleted file mode 100644
index ec8722e..0000000
--- a/src/java/android/net/ipsec/ike/ChildSessionCallback.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.net.IpSecManager.PolicyDirection;
-import android.net.IpSecTransform;
-import android.net.ipsec.ike.exceptions.IkeException;
-
-/** Callback interface for receiving state changes of a Child Session. */
-public interface ChildSessionCallback {
-    /**
-     * Called when Child Session setup succeeds.
-     *
-     * @param sessionConfiguration the configuration information of Child Session negotiated during
-     *     Child creation.
-     */
-    void onOpened(ChildSessionConfiguration sessionConfiguration);
-
-    /**
-     * Called when either side has decided to close this Session and the deletion exchange
-     * finishes.
-     *
-     * <p>This method will not be fired if this deletion is caused by a fatal error.
-     */
-    void onClosed();
-
-    /**
-     * Called if Child Session setup fails or Child Session is closed because of a fatal error.
-     *
-     * @param exception the detailed error.
-     */
-    void onClosedExceptionally(IkeException exception);
-
-    /**
-     * Called when a new {@link IpSecTransform} is created for this Child Session.
-     *
-     * @param ipSecTransform the created {@link IpSecTransform}
-     * @param direction the direction of this {@link IpSecTransform}
-     */
-    void onIpSecTransformCreated(IpSecTransform ipSecTransform, @PolicyDirection int direction);
-
-    /**
-     * Called when a new {@link IpSecTransform} is deleted for this Child Session.
-     *
-     * <p>Users MUST remove the transform from the socket or interface. Otherwise the communication
-     * on that socket or interface will fail.
-     *
-     * @param ipSecTransform the deleted {@link IpSecTransform}
-     * @param direction the direction of this {@link IpSecTransform}
-     */
-    void onIpSecTransformDeleted(IpSecTransform ipSecTransform, @PolicyDirection int direction);
-}
diff --git a/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java b/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java
deleted file mode 100644
index 2ed9de2..0000000
--- a/src/java/android/net/ipsec/ike/ChildSessionConfiguration.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;
-
-import android.net.LinkAddress;
-
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-/** ChildSessionConfiguration represents the negotiated configuration for a Child Session. */
-public final class ChildSessionConfiguration {
-    private static final int IPv4_DEFAULT_PREFIX_LEN = 32;
-
-    private final List<IkeTrafficSelector> mInboundTs;
-    private final List<IkeTrafficSelector> mOutboundTs;
-    private final List<LinkAddress> mInternalAddressList;
-
-    /**
-     * Construct an instance of {@link ChildSessionConfiguration}.
-     *
-     * <p>It is only supported to build a {@link ChildSessionConfiguration} with a Configure(Reply)
-     * Payload.
-     */
-    public ChildSessionConfiguration(
-            List<IkeTrafficSelector> inTs,
-            List<IkeTrafficSelector> outTs,
-            IkeConfigPayload configPayload) {
-        this(inTs, outTs);
-
-        if (configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) {
-            throw new IllegalArgumentException(
-                    "Cannot build ChildSessionConfiguration with configuration type: "
-                            + configPayload.configType);
-        }
-
-        // It is validated in IkeConfigPayload that a config reply only has at most one non-empty
-        // netmask and netmask exists only when IPv4 internal address exists.
-        ConfigAttributeIpv4Netmask netmaskAttr = null;
-        for (ConfigAttribute att : configPayload.recognizedAttributeList) {
-            if (att.attributeType == CONFIG_ATTR_INTERNAL_IP4_NETMASK && !att.isEmptyValue()) {
-                netmaskAttr = (ConfigAttributeIpv4Netmask) att;
-            }
-        }
-
-        for (ConfigAttribute att : configPayload.recognizedAttributeList) {
-            if (att.isEmptyValue()) continue;
-            switch (att.attributeType) {
-                case CONFIG_ATTR_INTERNAL_IP4_ADDRESS:
-                    ConfigAttributeIpv4Address addressAttr = (ConfigAttributeIpv4Address) att;
-                    if (netmaskAttr != null) {
-                        mInternalAddressList.add(
-                                new LinkAddress(addressAttr.address, netmaskAttr.getPrefixLen()));
-                    } else {
-                        mInternalAddressList.add(
-                                new LinkAddress(addressAttr.address, IPv4_DEFAULT_PREFIX_LEN));
-                    }
-                    break;
-                case CONFIG_ATTR_INTERNAL_IP4_NETMASK:
-                    // No action.
-                    break;
-                case CONFIG_ATTR_INTERNAL_IP6_ADDRESS:
-                    mInternalAddressList.add(((ConfigAttributeIpv6Address) att).linkAddress);
-                    break;
-                default:
-                    // TODO: Support DNS,Subnet and Dhcp4 attributes
-            }
-        }
-    }
-
-    /** Construct an instance of {@link ChildSessionConfiguration}. */
-    public ChildSessionConfiguration(
-            List<IkeTrafficSelector> inTs, List<IkeTrafficSelector> outTs) {
-        mInboundTs = Collections.unmodifiableList(inTs);
-        mOutboundTs = Collections.unmodifiableList(outTs);
-        mInternalAddressList = new LinkedList<>();
-    }
-
-    /**
-     * Returns the negotiated inbound traffic selectors.
-     *
-     * @return the inbound traffic selector.
-     */
-    public List<IkeTrafficSelector> getInboundTrafficSelectors() {
-        return mInboundTs;
-    }
-
-    /**
-     * Returns the negotiated outbound traffic selectors.
-     *
-     * @return the outbound traffic selector.
-     */
-    public List<IkeTrafficSelector> getOutboundTrafficSelectors() {
-        return mOutboundTs;
-    }
-
-    /**
-     * Returns the assigned internal addresses.
-     *
-     * @return assigned internal addresses, or empty list when no addresses are assigned by the
-     *     remote IKE server.
-     */
-    public List<LinkAddress> getInternalAddressList() {
-        return mInternalAddressList;
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/ChildSessionOptions.java b/src/java/android/net/ipsec/ike/ChildSessionOptions.java
deleted file mode 100644
index 90a3005..0000000
--- a/src/java/android/net/ipsec/ike/ChildSessionOptions.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import libcore.net.InetAddressUtils;
-
-import java.net.InetAddress;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This abstract class is the superclass of all classes representing a set of user configurations
- * for Child Session negotiation.
- */
-public abstract class ChildSessionOptions {
-    private static final IkeTrafficSelector DEFAULT_TRAFFIC_SELECTOR_IPV4;
-    // TODO: b/130765172 Add TRAFFIC_SELECTOR_IPV6 and instantiate it.
-
-    static {
-        DEFAULT_TRAFFIC_SELECTOR_IPV4 =
-                buildDefaultTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE);
-    }
-
-    private final IkeTrafficSelector[] mLocalTrafficSelectors;
-    private final IkeTrafficSelector[] mRemoteTrafficSelectors;
-    private final ChildSaProposal[] mSaProposals;
-    private final boolean mIsTransport;
-
-    protected ChildSessionOptions(
-            IkeTrafficSelector[] localTs,
-            IkeTrafficSelector[] remoteTs,
-            ChildSaProposal[] proposals,
-            boolean isTransport) {
-        mLocalTrafficSelectors = localTs;
-        mRemoteTrafficSelectors = remoteTs;
-        mSaProposals = proposals;
-        mIsTransport = isTransport;
-    }
-
-    public IkeTrafficSelector[] getLocalTrafficSelectors() {
-        return mLocalTrafficSelectors;
-    }
-
-    public IkeTrafficSelector[] getRemoteTrafficSelectors() {
-        return mRemoteTrafficSelectors;
-    }
-
-    public ChildSaProposal[] getSaProposals() {
-        return mSaProposals;
-    }
-
-    public boolean isTransportMode() {
-        return mIsTransport;
-    }
-
-    /** This class represents common information for Child Sesison Options Builders. */
-    protected abstract static class Builder {
-        protected final List<IkeTrafficSelector> mLocalTsList = new LinkedList<>();
-        protected final List<IkeTrafficSelector> mRemoteTsList = new LinkedList<>();
-        protected final List<SaProposal> mSaProposalList = new LinkedList<>();
-
-        protected Builder() {
-            // Currently IKE library only accepts setting up Child SA that all ports and all
-            // addresses are allowed on both sides. The protected traffic range is determined by the
-            // socket or interface that the {@link IpSecTransform} is applied to.
-            // TODO: b/130756765 Validate the current TS negotiation strategy.
-            mLocalTsList.add(DEFAULT_TRAFFIC_SELECTOR_IPV4);
-            mRemoteTsList.add(DEFAULT_TRAFFIC_SELECTOR_IPV4);
-            // TODO: add IPv6 TS to ChildSessionOptions.
-        }
-
-        protected void validateAndAddSaProposal(ChildSaProposal proposal) {
-            mSaProposalList.add(proposal);
-        }
-
-        protected void validateOrThrow() {
-            if (mSaProposalList.isEmpty()) {
-                throw new IllegalArgumentException(
-                        "ChildSessionOptions requires at least one Child SA proposal.");
-            }
-        }
-    }
-
-    private static IkeTrafficSelector buildDefaultTrafficSelector(
-            @IkeTrafficSelector.TrafficSelectorType int tsType) {
-        int startPort = IkeTrafficSelector.PORT_NUMBER_MIN;
-        int endPort = IkeTrafficSelector.PORT_NUMBER_MAX;
-        InetAddress startAddress = null;
-        InetAddress endAddress = null;
-        switch (tsType) {
-            case IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE:
-                startAddress = InetAddressUtils.parseNumericAddress("0.0.0.0");
-                endAddress = InetAddressUtils.parseNumericAddress("255.255.255.255");
-                break;
-            case IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE:
-                // TODO: Support it.
-                throw new UnsupportedOperationException("Do not support IPv6.");
-            default:
-                throw new IllegalArgumentException("Invalid Traffic Selector type: " + tsType);
-        }
-
-        return new IkeTrafficSelector(tsType, startPort, endPort, startAddress, endAddress);
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeFqdnIdentification.java b/src/java/android/net/ipsec/ike/IkeFqdnIdentification.java
deleted file mode 100644
index 393a072..0000000
--- a/src/java/android/net/ipsec/ike/IkeFqdnIdentification.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-
-import java.nio.charset.Charset;
-import java.util.Objects;
-
-/** IkeFqdnIdentification represents ID information using a fully-qualified domain name (FQDN) */
-public class IkeFqdnIdentification extends IkeIdentification {
-    private static final Charset ASCII = Charset.forName("US-ASCII");
-
-    public final String fqdn;
-
-    /**
-     * Construct an instance of IkeFqdnIdentification from a decoded inbound packet.
-     *
-     * <p>All characters in the FQDN are ASCII.
-     *
-     * @param fqdnBytes FQDN in byte array.
-     */
-    public IkeFqdnIdentification(byte[] fqdnBytes) {
-        super(ID_TYPE_FQDN);
-        fqdn = new String(fqdnBytes, ASCII);
-    }
-
-    /**
-     * Construct an instance of IkeFqdnIdentification with user provided fully-qualified domain name
-     * (FQDN) for building outbound packet.
-     *
-     * <p>FQDN will be formatted as US-ASCII.
-     *
-     * @param fqdn user provided fully-qualified domain name (FQDN)
-     */
-    public IkeFqdnIdentification(@NonNull String fqdn) {
-        super(ID_TYPE_FQDN);
-        this.fqdn = fqdn;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(idType, fqdn);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IkeFqdnIdentification)) return false;
-
-        return fqdn.equals(((IkeFqdnIdentification) o).fqdn);
-    }
-
-    /**
-     * Retrieve the byte-representation of the FQDN.
-     *
-     * @return the byte-representation of the FQDN.
-     */
-    @Override
-    public byte[] getEncodedIdData() {
-        return fqdn.getBytes(ASCII);
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeIdentification.java b/src/java/android/net/ipsec/ike/IkeIdentification.java
deleted file mode 100644
index 737df82..0000000
--- a/src/java/android/net/ipsec/ike/IkeIdentification.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2018 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.ipsec.ike;
-
-import android.annotation.IntDef;
-import android.util.ArraySet;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Set;
-
-/**
- * IkeIdentification is abstract base class that represents the common information for all types of
- * IKE entity identification.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.5">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public abstract class IkeIdentification {
-    // Set of supported ID types.
-    private static final Set<Integer> SUPPORTED_ID_TYPES;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        ID_TYPE_IPV4_ADDR,
-        ID_TYPE_FQDN,
-        ID_TYPE_RFC822_ADDR,
-        ID_TYPE_IPV6_ADDR,
-        ID_TYPE_DER_ASN1_DN,
-        ID_TYPE_DER_ASN1_GN,
-        ID_TYPE_KEY_ID
-    })
-    public @interface IdType {}
-
-    public static final int ID_TYPE_IPV4_ADDR = 1;
-    public static final int ID_TYPE_FQDN = 2;
-    public static final int ID_TYPE_RFC822_ADDR = 3;
-    public static final int ID_TYPE_IPV6_ADDR = 5;
-    public static final int ID_TYPE_DER_ASN1_DN = 9;
-    public static final int ID_TYPE_DER_ASN1_GN = 10;
-    public static final int ID_TYPE_KEY_ID = 11;
-
-    static {
-        SUPPORTED_ID_TYPES = new ArraySet();
-        SUPPORTED_ID_TYPES.add(ID_TYPE_IPV4_ADDR);
-        SUPPORTED_ID_TYPES.add(ID_TYPE_FQDN);
-        SUPPORTED_ID_TYPES.add(ID_TYPE_RFC822_ADDR);
-        SUPPORTED_ID_TYPES.add(ID_TYPE_IPV6_ADDR);
-        SUPPORTED_ID_TYPES.add(ID_TYPE_DER_ASN1_DN);
-        SUPPORTED_ID_TYPES.add(ID_TYPE_DER_ASN1_GN);
-        SUPPORTED_ID_TYPES.add(ID_TYPE_KEY_ID);
-    }
-
-    public final int idType;
-
-    protected IkeIdentification(@IdType int type) {
-        idType = type;
-    }
-
-    /**
-     * Return the encoded identification data in a byte array.
-     *
-     * @return the encoded identification data.
-     */
-    public abstract byte[] getEncodedIdData();
-}
diff --git a/src/java/android/net/ipsec/ike/IkeIpv4AddrIdentification.java b/src/java/android/net/ipsec/ike/IkeIpv4AddrIdentification.java
deleted file mode 100644
index 350187e..0000000
--- a/src/java/android/net/ipsec/ike/IkeIpv4AddrIdentification.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-
-import java.net.Inet4Address;
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-/** IkeIpv4AddrIdentification represents ID information in IPv4 address ID type. */
-public final class IkeIpv4AddrIdentification extends IkeIdentification {
-    public final Inet4Address ipv4Address;
-
-    /**
-     * Construct an instance of IkeIpv4AddrIdentification from a decoded inbound packet.
-     *
-     * @param ipv4AddrBytes IPv4 address in byte array.
-     * @throws AuthenticationFailedException for decoding bytes error.
-     */
-    public IkeIpv4AddrIdentification(byte[] ipv4AddrBytes) throws AuthenticationFailedException {
-        super(ID_TYPE_IPV4_ADDR);
-        try {
-            ipv4Address = (Inet4Address) (Inet4Address.getByAddress(ipv4AddrBytes));
-        } catch (ClassCastException | UnknownHostException e) {
-            throw new AuthenticationFailedException(e);
-        }
-    }
-
-    /**
-     * Construct an instance of IkeIpv4AddrIdentification with user provided IPv4 address for
-     * building outbound packet.
-     *
-     * @param address user provided IPv4 address
-     */
-    public IkeIpv4AddrIdentification(@NonNull Inet4Address address) {
-        super(ID_TYPE_IPV4_ADDR);
-        ipv4Address = address;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(idType, ipv4Address);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IkeIpv4AddrIdentification)) return false;
-
-        return ipv4Address.equals(((IkeIpv4AddrIdentification) o).ipv4Address);
-    }
-
-    /**
-     * Retrieve the byte-representation of the IPv4 address.
-     *
-     * @return the byte-representation of the IPv4 address.
-     */
-    @Override
-    public byte[] getEncodedIdData() {
-        return ipv4Address.getAddress();
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeIpv6AddrIdentification.java b/src/java/android/net/ipsec/ike/IkeIpv6AddrIdentification.java
deleted file mode 100644
index dfc7d5e..0000000
--- a/src/java/android/net/ipsec/ike/IkeIpv6AddrIdentification.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-
-import java.net.Inet6Address;
-import java.net.UnknownHostException;
-import java.util.Objects;
-
-/** IkeIpv6AddrIdentification represents ID information in IPv6 address ID type. */
-public class IkeIpv6AddrIdentification extends IkeIdentification {
-    public final Inet6Address ipv6Address;
-
-    /**
-     * Construct an instance of IkeIpv6AddrIdentification from a decoded inbound packet.
-     *
-     * @param ipv6AddrBytes IPv6 address in byte array.
-     * @throws AuthenticationFailedException for decoding bytes error.
-     */
-    public IkeIpv6AddrIdentification(byte[] ipv6AddrBytes) throws AuthenticationFailedException {
-        super(ID_TYPE_IPV6_ADDR);
-        try {
-            ipv6Address = (Inet6Address) (Inet6Address.getByAddress(ipv6AddrBytes));
-        } catch (ClassCastException | UnknownHostException e) {
-            throw new AuthenticationFailedException(e);
-        }
-    }
-
-    /**
-     * Construct an instance of IkeIpv6AddrIdentification with user provided IPv6 address for
-     * building outbound packet.
-     *
-     * @param address user provided IPv6 address
-     */
-    public IkeIpv6AddrIdentification(@NonNull Inet6Address address) {
-        super(ID_TYPE_IPV6_ADDR);
-        ipv6Address = address;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(idType, ipv6Address);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IkeIpv6AddrIdentification)) return false;
-
-        return ipv6Address.equals(((IkeIpv6AddrIdentification) o).ipv6Address);
-    }
-
-    /**
-     * Retrieve the byte-representation of the IPv6 address.
-     *
-     * @return the byte-representation of the IPv6 address.
-     */
-    @Override
-    public byte[] getEncodedIdData() {
-        return ipv6Address.getAddress();
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeKeyIdIdentification.java b/src/java/android/net/ipsec/ike/IkeKeyIdIdentification.java
deleted file mode 100644
index c229b9d..0000000
--- a/src/java/android/net/ipsec/ike/IkeKeyIdIdentification.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-
-import java.util.Objects;
-
-/**
- * This class represents IKE ID information in Key ID type.
- *
- * <p>This is an octet stream that may be used to pass vendor-specific information necessary to do
- * certain proprietary types of identification.
- */
-public final class IkeKeyIdIdentification extends IkeIdentification {
-    public final byte[] keyId;
-
-    /**
-     * Construct an instance of IkeKeyIdIdentification with provided Key ID
-     *
-     * @param keyId Key ID in bytes
-     */
-    public IkeKeyIdIdentification(@NonNull byte[] keyId) {
-        super(ID_TYPE_KEY_ID);
-        this.keyId = keyId;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(idType, keyId);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IkeKeyIdIdentification)) return false;
-
-        return keyId.equals(((IkeKeyIdIdentification) o).keyId);
-    }
-
-    /**
-     * Retrieve the byte-representation of the FQDN.
-     *
-     * @return the byte-representation of the FQDN.
-     */
-    @Override
-    public byte[] getEncodedIdData() {
-        return keyId;
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeManager.java b/src/java/android/net/ipsec/ike/IkeManager.java
deleted file mode 100644
index ef8b893..0000000
--- a/src/java/android/net/ipsec/ike/IkeManager.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.ipsec.ike;
-
-import android.content.Context;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.utils.Log;
-
-import java.util.concurrent.Executor;
-
-/** This class contains methods for managing IKE sessions. */
-public final class IkeManager {
-    private static final String IKE_TAG = "IKE";
-    private static final boolean LOG_SENSITIVE = false;
-
-    private static Log sIkeLog = new Log(IKE_TAG, LOG_SENSITIVE);
-
-    private final Context mContext;
-
-    /**
-     * Construct an instance of {@link IkeManager}
-     *
-     * @param context the application context.
-     */
-    public IkeManager(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Construct an instance of {@link IkeSession} and start the IKE Session setup process.
-     *
-     * <p>This method will immediately return a management object {@link IkeSession} and
-     * asynchronously initiate the IKE Session setup process. Users will be notified of the IKE
-     * Session and Child Session negotiation results on the callback arguments.
-     *
-     * @param ikeSessionOptions the {@link IkeSessionOptions} that contains acceptable IKE Session
-     *     configurations.
-     * @param firstChildSessionOptions the {@link ChildSessionOptions} that contains acceptable
-     *     first Child Session configurations.
-     * @param userCbExecutor the {@link Executor} upon which all callbacks will be posted. For
-     *     security and consistency, the callbacks posted to this executor MUST be executed
-     *     serially, in the order they were posted.
-     * @param ikeSessionCallback the {@link IkeSessionCallback} interface to notify users the state
-     *     changes of the IKE Session.
-     * @param firstChildSessionCallback the {@link ChildSessionCallback} interface to notify users
-     *     the state changes of the Child Session.
-     * @return an instance of {@link IkeSession}
-     */
-    public IkeSession openIkeSession(
-            IkeSessionOptions ikeSessionOptions,
-            ChildSessionOptions firstChildSessionOptions,
-            Executor userCbExecutor,
-            IkeSessionCallback ikeSessionCallback,
-            ChildSessionCallback firstChildSessionCallback) {
-        return new IkeSession(
-                mContext,
-                ikeSessionOptions,
-                firstChildSessionOptions,
-                userCbExecutor,
-                ikeSessionCallback,
-                firstChildSessionCallback);
-    }
-
-    /** Returns IKE logger. */
-    public static Log getIkeLog() {
-        return sIkeLog;
-    }
-
-    /** Injects IKE logger for testing. */
-    @VisibleForTesting
-    public static void setIkeLog(Log log) {
-        sIkeLog = log;
-    }
-
-    /** Resets IKE logger. */
-    @VisibleForTesting
-    public static void resetIkeLog() {
-        sIkeLog = new Log(IKE_TAG, LOG_SENSITIVE);
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeRfc822AddrIdentification.java b/src/java/android/net/ipsec/ike/IkeRfc822AddrIdentification.java
deleted file mode 100644
index 2a93bea..0000000
--- a/src/java/android/net/ipsec/ike/IkeRfc822AddrIdentification.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-
-import java.nio.charset.Charset;
-import java.util.Objects;
-
-/** This class represents IKE ID information in fully-qualified RFC 822 email address ID type. */
-public final class IkeRfc822AddrIdentification extends IkeIdentification {
-    private static final Charset UTF8 = Charset.forName("UTF-8");
-
-    public final String rfc822Name;
-
-    /**
-     * Construct an instance of IkeRfc822AddrIdentification from a decoded inbound packet.
-     *
-     * <p>All characters in the RFC 822 email address are UTF-8.
-     *
-     * @param rfc822NameBytes fully-qualified RFC 822 email address in byte array.
-     */
-    public IkeRfc822AddrIdentification(byte[] rfc822NameBytes) {
-        super(ID_TYPE_RFC822_ADDR);
-        rfc822Name = new String(rfc822NameBytes, UTF8);
-    }
-
-    /**
-     * Construct an instance of IkeRfc822AddrIdentification with user provided fully-qualified RFC
-     * 822 email address for building outbound packet.
-     *
-     * <p>rfc822Name will be formatted as UTF-8.
-     *
-     * @param rfc822Name user provided fully-qualified RFC 822 email address.
-     */
-    public IkeRfc822AddrIdentification(@NonNull String rfc822Name) {
-        super(ID_TYPE_RFC822_ADDR);
-        this.rfc822Name = rfc822Name;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(idType, rfc822Name);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IkeRfc822AddrIdentification)) return false;
-
-        return rfc822Name.equals(((IkeRfc822AddrIdentification) o).rfc822Name);
-    }
-
-    /**
-     * Retrieve the byte-representation of the the RFC 822 email address.
-     *
-     * @return the byte-representation of the RFC 822 email address.
-     */
-    @Override
-    public byte[] getEncodedIdData() {
-        return rfc822Name.getBytes(UTF8);
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeSaProposal.java b/src/java/android/net/ipsec/ike/IkeSaProposal.java
deleted file mode 100644
index 1494f9d..0000000
--- a/src/java/android/net/ipsec/ike/IkeSaProposal.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.util.ArraySet;
-
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * IkeSaProposal represents a user configured set contains cryptograhic algorithms and key
- * generating materials for negotiating an IKE SA.
- *
- * <p>User must provide at least a valid IkeSaProposal when they are creating a new IKE SA.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeSaProposal extends SaProposal {
-    private final PrfTransform[] mPseudorandomFunctions;
-
-    /**
-     * Construct an instance of IkeSaProposal.
-     *
-     * <p>This constructor is either called by IkeSaPayload for building an inbound proposal from a
-     * decoded packet, or called by the inner Builder to build an outbound proposal from user
-     * provided parameters
-     *
-     * @param encryptionAlgos encryption algorithms
-     * @param prfs pseudorandom functions
-     * @param integrityAlgos integrity algorithms
-     * @param dhGroups Diffie-Hellman Groups
-     */
-    public IkeSaProposal(
-            EncryptionTransform[] encryptionAlgos,
-            PrfTransform[] prfs,
-            IntegrityTransform[] integrityAlgos,
-            DhGroupTransform[] dhGroups) {
-        super(IkePayload.PROTOCOL_ID_IKE, encryptionAlgos, integrityAlgos, dhGroups);
-        mPseudorandomFunctions = prfs;
-    }
-
-    /** Gets all PRFs. */
-    public PrfTransform[] getPrfTransforms() {
-        return mPseudorandomFunctions;
-    }
-
-    @Override
-    public Transform[] getAllTransforms() {
-        List<Transform> transformList = getAllTransformsAsList();
-        transformList.addAll(Arrays.asList(mPseudorandomFunctions));
-
-        return transformList.toArray(new Transform[transformList.size()]);
-    }
-
-    @Override
-    public boolean isNegotiatedFrom(SaProposal reqProposal) {
-        return super.isNegotiatedFrom(reqProposal)
-                && isTransformSelectedFrom(
-                        mPseudorandomFunctions,
-                        ((IkeSaProposal) reqProposal).mPseudorandomFunctions);
-    }
-
-    /**
-     * This class can be used to incrementally construct a IkeSaProposal. IkeSaProposal instances
-     * are immutable once built.
-     *
-     * <p>TODO: Support users to add algorithms from most preferred to least preferred.
-     */
-    public static final class Builder extends SaProposal.Builder {
-        // Use set to avoid adding repeated algorithms.
-        private final Set<PrfTransform> mProposedPrfs = new ArraySet<>();
-
-        /**
-         * Adds an encryption algorithm with specific key length to SA proposal being built.
-         *
-         * @param algorithm encryption algorithm to add to IkeSaProposal.
-         * @param keyLength key length of algorithm. For algorithm that has fixed key length (e.g.
-         *     3DES) only KEY_LEN_UNUSED is allowed.
-         * @return Builder of IkeSaProposal.
-         * @throws IllegalArgumentException if AEAD and non-combined mode algorithms are mixed.
-         */
-        public Builder addEncryptionAlgorithm(@EncryptionAlgorithm int algorithm, int keyLength) {
-            validateAndAddEncryptAlgo(algorithm, keyLength);
-            return this;
-        }
-
-        /**
-         * Adds an integrity algorithm to SA proposal being built.
-         *
-         * @param algorithm integrity algorithm to add to IkeSaProposal.
-         * @return Builder of IkeSaProposal.
-         */
-        public Builder addIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) {
-            addIntegrityAlgo(algorithm);
-            return this;
-        }
-
-        /**
-         * Adds a Diffie-Hellman Group to SA proposal being built.
-         *
-         * @param dhGroup to add to IkeSaProposal.
-         * @return Builder of IkeSaProposal.
-         */
-        public Builder addDhGroup(@DhGroup int dhGroup) {
-            addDh(dhGroup);
-            return this;
-        }
-
-        /**
-         * Adds a pseudorandom function to SA proposal being built.
-         *
-         * @param algorithm pseudorandom function to add to IkeSaProposal.
-         * @return Builder of IkeSaProposal.
-         */
-        public Builder addPseudorandomFunction(@PseudorandomFunction int algorithm) {
-            // Construct PrfTransform and validate proposed algorithm during construction.
-            mProposedPrfs.add(new PrfTransform(algorithm));
-            return this;
-        }
-
-        private IntegrityTransform[] buildIntegAlgosOrThrow() {
-            // When building IKE SA Proposal with normal-mode ciphers, mProposedIntegrityAlgos must
-            // not be empty and must not have INTEGRITY_ALGORITHM_NONE. When building IKE SA
-            // Proposal with combined-mode ciphers, mProposedIntegrityAlgos must be either empty or
-            // only have INTEGRITY_ALGORITHM_NONE.
-            if (mProposedIntegrityAlgos.isEmpty() && !mHasAead) {
-                throw new IllegalArgumentException(
-                        ERROR_TAG
-                                + "Integrity algorithm "
-                                + "must be proposed with normal ciphers in IKE proposal.");
-            }
-
-            for (IntegrityTransform transform : mProposedIntegrityAlgos) {
-                if ((transform.id == INTEGRITY_ALGORITHM_NONE) != mHasAead) {
-                    throw new IllegalArgumentException(
-                            ERROR_TAG
-                                    + "Invalid integrity algorithm configuration"
-                                    + " for this SA Proposal");
-                }
-            }
-
-            return mProposedIntegrityAlgos.toArray(
-                    new IntegrityTransform[mProposedIntegrityAlgos.size()]);
-        }
-
-        private DhGroupTransform[] buildDhGroupsOrThrow() {
-            if (mProposedDhGroups.isEmpty()) {
-                throw new IllegalArgumentException(
-                        ERROR_TAG + "DH group must be proposed in IKE SA proposal.");
-            }
-
-            for (DhGroupTransform transform : mProposedDhGroups) {
-                if (transform.id == DH_GROUP_NONE) {
-                    throw new IllegalArgumentException(
-                            ERROR_TAG + "None-value DH group invalid in IKE SA proposal");
-                }
-            }
-
-            return mProposedDhGroups.toArray(new DhGroupTransform[mProposedDhGroups.size()]);
-        }
-
-        private PrfTransform[] buildPrfsOrThrow() {
-            if (mProposedPrfs.isEmpty()) {
-                throw new IllegalArgumentException(
-                        ERROR_TAG + "PRF must be proposed in IKE SA proposal.");
-            }
-            return mProposedPrfs.toArray(new PrfTransform[mProposedPrfs.size()]);
-        }
-
-        /**
-         * Validates, builds and returns the IkeSaProposal
-         *
-         * @return the validated IkeSaProposal.
-         * @throws IllegalArgumentException if IkeSaProposal is invalid.
-         */
-        public IkeSaProposal build() {
-            EncryptionTransform[] encryptionTransforms = buildEncryptAlgosOrThrow();
-            PrfTransform[] prfTransforms = buildPrfsOrThrow();
-            IntegrityTransform[] integrityTransforms = buildIntegAlgosOrThrow();
-            DhGroupTransform[] dhGroupTransforms = buildDhGroupsOrThrow();
-
-            return new IkeSaProposal(
-                    encryptionTransforms, prfTransforms, integrityTransforms, dhGroupTransforms);
-        }
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeSession.java b/src/java/android/net/ipsec/ike/IkeSession.java
deleted file mode 100644
index 97fe061..0000000
--- a/src/java/android/net/ipsec/ike/IkeSession.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.ipsec.ike;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.os.HandlerThread;
-import android.os.Looper;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine;
-
-import dalvik.system.CloseGuard;
-
-import java.util.concurrent.Executor;
-
-/**
- * This class represents an IKE Session management object that allows for keying and management of
- * {@link IpSecTransform}s.
- *
- * <p>An IKE/Child Session represents an IKE/Child SA as well as its rekeyed successors. A Child
- * Session is bounded by the lifecycle of the IKE Session under which it is set up. Closing an IKE
- * Session implicitly closes any remaining Child Sessions under it.
- *
- * <p>An IKE procedure is one or multiple IKE message exchanges that are used to create, delete or
- * rekey an IKE Session or Child Session.
- *
- * <p>This class provides methods for user to initiate IKE procedures, such as the Creation and
- * Deletion of a Child Session, or the Deletion of the IKE session. All procedures (except for IKE
- * deletion) will be initiated sequentially after IKE Session is set up.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296">RFC 7296, Internet Key Exchange Protocol
- *     Version 2 (IKEv2)</a>
- */
-public final class IkeSession implements AutoCloseable {
-    private final CloseGuard mCloseGuard = CloseGuard.get();
-
-    @VisibleForTesting final IkeSessionStateMachine mIkeSessionStateMachine;
-
-    /** Package private */
-    IkeSession(
-            Context context,
-            IkeSessionOptions ikeSessionOptions,
-            ChildSessionOptions firstChildSessionOptions,
-            Executor userCbExecutor,
-            IkeSessionCallback ikeSessionCallback,
-            ChildSessionCallback firstChildSessionCallback) {
-        this(
-                IkeThreadHolder.IKE_WORKER_THREAD.getLooper(),
-                context,
-                (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE),
-                ikeSessionOptions,
-                firstChildSessionOptions,
-                userCbExecutor,
-                ikeSessionCallback,
-                firstChildSessionCallback);
-    }
-
-    /** Package private */
-    @VisibleForTesting
-    IkeSession(
-            Looper looper,
-            Context context,
-            IpSecManager ipSecManager,
-            IkeSessionOptions ikeSessionOptions,
-            ChildSessionOptions firstChildSessionOptions,
-            Executor userCbExecutor,
-            IkeSessionCallback ikeSessionCallback,
-            ChildSessionCallback firstChildSessionCallback) {
-        mIkeSessionStateMachine =
-                new IkeSessionStateMachine(
-                        looper,
-                        context,
-                        ipSecManager,
-                        ikeSessionOptions,
-                        firstChildSessionOptions,
-                        userCbExecutor,
-                        ikeSessionCallback,
-                        firstChildSessionCallback);
-        mIkeSessionStateMachine.openSession();
-
-        mCloseGuard.open("open");
-    }
-
-    @Override
-    public void finalize() {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
-    }
-
-    /** Initialization-on-demand holder */
-    private static class IkeThreadHolder {
-        static final HandlerThread IKE_WORKER_THREAD;
-
-        static {
-            IKE_WORKER_THREAD = new HandlerThread("IkeWorkerThread");
-            IKE_WORKER_THREAD.start();
-        }
-    }
-
-    // TODO: b/133340675 Destroy the worker thread when there is no more alive {@link IkeSession}.
-
-    /**
-     * Asynchronously request a new Child Session.
-     *
-     * <p>Users MUST provide a unique {@link ChildSessionCallback} instance for each new Child
-     * Session.
-     *
-     * <p>Upon setup, the {@link ChildSessionCallback#onOpened(ChildSessionConfiguration)} will be
-     * fired.
-     *
-     * @param childSessionOptions the {@link ChildSessionOptions} that contains the Child Session
-     *     configurations to negotiate.
-     * @param childSessionCallback the {@link ChildSessionCallback} interface to notify users the
-     *     state changes of the Child Session.
-     * @throws IllegalArgumentException if the ChildSessionCallback is already in use.
-     */
-    public void openChildSession(
-            ChildSessionOptions childSessionOptions, ChildSessionCallback childSessionCallback) {
-        mIkeSessionStateMachine.openChildSession(childSessionOptions, childSessionCallback);
-    }
-
-    /**
-     * Asynchronously delete a Child Session.
-     *
-     * <p>Upon closing, the {@link ChildSessionCallback#onClosed()} will be fired.
-     *
-     * @param childSessionCallback The {@link ChildSessionCallback} instance that uniquely identify
-     *     the Child Session.
-     * @throws IllegalArgumentException if no Child Session found bound with this callback.
-     */
-    public void closeChildSession(ChildSessionCallback childSessionCallback) {
-        mIkeSessionStateMachine.closeChildSession(childSessionCallback);
-    }
-
-    /**
-     * Close the IKE session gracefully.
-     *
-     * <p>Implements {@link AutoCloseable#close()}
-     *
-     * <p>Upon closing, the {@link IkeSessionCallback#onClosed()} will be fired.
-     *
-     * <p>Closing an IKE Session implicitly closes any remaining Child Sessions negotiated under it.
-     * Users SHOULD stop all outbound traffic that uses these Child Sessions({@link IpSecTransform}
-     * pairs) before calling this method. Otherwise IPsec packets will be dropped due to the lack of
-     * a valid {@link IpSecTransform}.
-     *
-     * <p>Closure of an IKE session will take priority over, and cancel other procedures waiting in
-     * the queue (but will wait for ongoing locally initiated procedures to complete). After sending
-     * the Delete request, the IKE library will wait until a Delete response is received or
-     * retransmission timeout occurs.
-     */
-    @Override
-    public void close() throws Exception {
-        mCloseGuard.close();
-        mIkeSessionStateMachine.closeSession();
-    }
-
-    /**
-     * Terminate (forcibly close) the IKE session.
-     *
-     * <p>Upon closing, the {@link IkeSessionCallback#onClosed()} will be fired.
-     *
-     * <p>Closing an IKE Session implicitly closes any remaining Child Sessions negotiated under it.
-     * Users SHOULD stop all outbound traffic that uses these Child Sessions({@link IpSecTransform}
-     * pairs) before calling this method. Otherwise IPsec packets will be dropped due to the lack of
-     * a valid {@link IpSecTransform}.
-     *
-     * <p>Forcible closure of an IKE session will take priority over, and cancel other procedures
-     * waiting in the queue. It will also interrupt any ongoing locally initiated procedure.
-     */
-    public void kill() throws Exception {
-        mCloseGuard.close();
-        mIkeSessionStateMachine.killSession();
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeSessionCallback.java b/src/java/android/net/ipsec/ike/IkeSessionCallback.java
deleted file mode 100644
index c2121e2..0000000
--- a/src/java/android/net/ipsec/ike/IkeSessionCallback.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-import android.net.ipsec.ike.exceptions.IkeException;
-
-/** Callback interface for receiving state changes of an IKE Session. */
-public interface IkeSessionCallback {
-    /**
-     * Called when negotiation and authentication for this new IKE Session succeeds.
-     *
-     * @param sessionConfiguration the configuration information of IKE Session negotiated during
-     *     IKE setup.
-     */
-    void onOpened(@NonNull IkeSessionConfiguration sessionConfiguration);
-
-    /**
-     * Called when either side has decided to close this Session and the deletion exchange
-     * finishes.
-     *
-     * <p>This method will not be fired if this deletion is caused by a fatal error.
-     */
-    void onClosed();
-
-    /**
-     * Called if IKE Session negotiation fails or IKE Session is closed because of a fatal error.
-     *
-     * @param exception the detailed error.
-     */
-    void onClosedExceptionally(IkeException exception);
-
-    /**
-     * Called if a recoverable error is encountered in an established IKE Session.
-     *
-     * <p>A potential risk is usually detected when IKE library receives a non-protected error
-     * notification (e.g. INVALID_IKE_SPI) or a non-fatal error notification (e.g.
-     * INVALID_MESSAGE_ID).
-     *
-     * @param exception the detailed error.
-     */
-    void onError(IkeException exception);
-}
diff --git a/src/java/android/net/ipsec/ike/IkeSessionConfiguration.java b/src/java/android/net/ipsec/ike/IkeSessionConfiguration.java
deleted file mode 100644
index 6bbef7d..0000000
--- a/src/java/android/net/ipsec/ike/IkeSessionConfiguration.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/** IkeSessionConfiguration represents the negotiated configuration for a IKE Session. */
-public final class IkeSessionConfiguration {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({EXTENSION_TYPE_FRAGMENTATION, EXTENSION_TYPE_MOBIKE})
-    public @interface ExtensionType {}
-
-    public static final int EXTENSION_TYPE_FRAGMENTATION = 1;
-    public static final int EXTENSION_TYPE_MOBIKE = 2;
-
-    /**
-     * Gets remote(server) version information.
-     *
-     * @return application version of the remote server, or empty string if the remote server did
-     *     not provide the application version
-     */
-    @NonNull
-    public String getRemoteApplicationVersion() {
-        return "";
-    }
-
-    /**
-     * Checks if an IKE extension is enabled.
-     *
-     * <p>An IKE extension is enabled when both sides can support it. This negotiation always
-     * happens in IKE initial changes(IKE INIT and IKE AUTH).
-     *
-     * @param extensionType the extension type
-     * @return {@code true} if this extension is enabled
-     */
-    public boolean isIkeExtensionEnabled(@ExtensionType int extensionType) {
-        return false;
-    }
-
-    // TODO: Implement IkeSessionConfiguration.
-}
diff --git a/src/java/android/net/ipsec/ike/IkeSessionOptions.java b/src/java/android/net/ipsec/ike/IkeSessionOptions.java
deleted file mode 100644
index 020a888..0000000
--- a/src/java/android/net/ipsec/ike/IkeSessionOptions.java
+++ /dev/null
@@ -1,416 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.eap.EapSessionConfig;
-
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.security.PrivateKey;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPrivateKey;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * IkeSessionOptions contains all user provided configurations for negotiating an IKE SA.
- *
- * <p>TODO: Make this doc more user-friendly.
- */
-public final class IkeSessionOptions {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({IKE_AUTH_METHOD_PSK, IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, IKE_AUTH_METHOD_EAP})
-    public @interface IkeAuthMethod {}
-
-    // Constants to describe user configured authentication methods.
-    public static final int IKE_AUTH_METHOD_PSK = 1;
-    public static final int IKE_AUTH_METHOD_PUB_KEY_SIGNATURE = 2;
-    public static final int IKE_AUTH_METHOD_EAP = 3;
-
-    private final InetAddress mServerAddress;
-    private final UdpEncapsulationSocket mUdpEncapSocket;
-    private final IkeSaProposal[] mSaProposals;
-
-    private final IkeIdentification mLocalIdentification;
-    private final IkeIdentification mRemoteIdentification;
-
-    private final IkeAuthConfig mLocalAuthConfig;
-    private final IkeAuthConfig mRemoteAuthConfig;
-
-    private final boolean mIsIkeFragmentationSupported;
-
-    private IkeSessionOptions(
-            InetAddress serverAddress,
-            UdpEncapsulationSocket udpEncapsulationSocket,
-            IkeSaProposal[] proposals,
-            IkeIdentification localIdentification,
-            IkeIdentification remoteIdentification,
-            IkeAuthConfig localAuthConfig,
-            IkeAuthConfig remoteAuthConfig,
-            boolean isIkeFragmentationSupported) {
-        mServerAddress = serverAddress;
-        mUdpEncapSocket = udpEncapsulationSocket;
-        mSaProposals = proposals;
-
-        mLocalIdentification = localIdentification;
-        mRemoteIdentification = remoteIdentification;
-
-        mLocalAuthConfig = localAuthConfig;
-        mRemoteAuthConfig = remoteAuthConfig;
-
-        mIsIkeFragmentationSupported = isIkeFragmentationSupported;
-    }
-
-    public InetAddress getServerAddress() {
-        return mServerAddress;
-    }
-
-    public UdpEncapsulationSocket getUdpEncapsulationSocket() {
-        return mUdpEncapSocket;
-    }
-
-    public IkeSaProposal[] getSaProposals() {
-        return mSaProposals;
-    }
-
-    public IkeIdentification getLocalIdentification() {
-        return mLocalIdentification;
-    }
-
-    public IkeIdentification getRemoteIdentification() {
-        return mRemoteIdentification;
-    }
-
-    public IkeAuthConfig getLocalAuthConfig() {
-        return mLocalAuthConfig;
-    }
-
-    public IkeAuthConfig getRemoteAuthConfig() {
-        return mRemoteAuthConfig;
-    }
-
-    public boolean isIkeFragmentationSupported() {
-        return mIsIkeFragmentationSupported;
-    }
-    /** This class contains common information of an IKEv2 authentication configuration. */
-    public abstract static class IkeAuthConfig {
-        @IkeAuthMethod public final int mAuthMethod;
-
-        protected IkeAuthConfig(@IkeAuthMethod int authMethod) {
-            mAuthMethod = authMethod;
-        }
-    }
-
-    /**
-     * This class represents the configuration to support IKEv2 pre-shared-key-based authentication
-     * of local or remote side.
-     */
-    public static class IkeAuthPskConfig extends IkeAuthConfig {
-        public final byte[] mPsk;
-
-        private IkeAuthPskConfig(byte[] psk) {
-            super(IKE_AUTH_METHOD_PSK);
-            mPsk = psk;
-        }
-    }
-
-    /**
-     * This class represents the configuration to support IKEv2 public-key-signature-based
-     * authentication of the remote side.
-     */
-    public static class IkeAuthDigitalSignRemoteConfig extends IkeAuthConfig {
-        public final TrustAnchor mTrustAnchor;
-
-        private IkeAuthDigitalSignRemoteConfig(TrustAnchor trustAnchor) {
-            super(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE);
-            mTrustAnchor = trustAnchor;
-        }
-    }
-
-    /**
-     * This class represents the configuration to support IKEv2 public-key-signature-based
-     * authentication of the local side.
-     */
-    public static class IkeAuthDigitalSignLocalConfig extends IkeAuthConfig {
-        public final X509Certificate mEndCert;
-        public final List<X509Certificate> mIntermediateCerts;
-        public final PrivateKey mPrivateKey;
-
-        private IkeAuthDigitalSignLocalConfig(
-                X509Certificate clientEndCert,
-                List<X509Certificate> clientIntermediateCerts,
-                PrivateKey privateKey) {
-            super(IKE_AUTH_METHOD_PUB_KEY_SIGNATURE);
-            mEndCert = clientEndCert;
-            mIntermediateCerts = clientIntermediateCerts;
-            mPrivateKey = privateKey;
-        }
-    }
-
-    /**
-     * This class represents the configuration to support EAP authentication of the local side.
-     *
-     * <p>EAP MUST be used with IKEv2 public-key-based authentication of the responder to the
-     * initiator. Currently IKE library does not support the IKEv2 protocol extension(RFC 5998)
-     * which allows EAP methods that provide mutual authentication and key agreement to be used to
-     * provide extensible responder authentication for IKEv2 based on methods other than public key
-     * signatures.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc5998">RFC 5998, An Extension for EAP-Only
-     *     Authentication in IKEv2</a>
-     */
-    public static class IkeAuthEapConfig extends IkeAuthConfig {
-        public final EapSessionConfig mEapConfig;
-
-        private IkeAuthEapConfig(EapSessionConfig eapConfig) {
-            super(IKE_AUTH_METHOD_EAP);
-
-            mEapConfig = eapConfig;
-        }
-    }
-
-    /** This class can be used to incrementally construct a IkeSessionOptions. */
-    public static final class Builder {
-        private final List<IkeSaProposal> mSaProposalList = new LinkedList<>();
-
-        private InetAddress mServerAddress;
-        private UdpEncapsulationSocket mUdpEncapSocket;
-
-        private IkeIdentification mLocalIdentification;
-        private IkeIdentification mRemoteIdentification;
-
-        private IkeAuthConfig mLocalAuthConfig;
-        private IkeAuthConfig mRemoteAuthConfig;
-
-        private boolean mIsIkeFragmentationSupported = false;
-
-        /**
-         * Sets server address
-         *
-         * @param serverAddress IP address of remote IKE server.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setServerAddress(@NonNull InetAddress serverAddress) {
-            mServerAddress = serverAddress;
-            return this;
-        }
-
-        /**
-         * Sets UDP-Encapsulated socket
-         *
-         * @param udpEncapsulationSocket {@link IpSecManager.UdpEncapsulationSocket} for sending and
-         *     receiving IKE message.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setUdpEncapsulationSocket(
-                @NonNull UdpEncapsulationSocket udpEncapsulationSocket) {
-            mUdpEncapSocket = udpEncapsulationSocket;
-            return this;
-        }
-
-        /**
-         * Sets local IKE identification.
-         *
-         * @param identification the local IKE identification.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setLocalIdentification(IkeIdentification identification) {
-            mLocalIdentification = identification;
-            return this;
-        }
-
-        /**
-         * Sets remote IKE identification.
-         *
-         * @param identification the remote IKE identification.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setRemoteIdentification(IkeIdentification identification) {
-            mRemoteIdentification = identification;
-            return this;
-        }
-
-        /**
-         * Adds an IKE SA proposal to IkeSessionOptions being built.
-         *
-         * @param proposal IKE SA proposal.
-         * @return Builder this, to facilitate chaining.
-         * @throws IllegalArgumentException if input proposal is not IKE SA proposal.
-         */
-        public Builder addSaProposal(IkeSaProposal proposal) {
-            if (proposal.getProtocolId() != IkePayload.PROTOCOL_ID_IKE) {
-                throw new IllegalArgumentException(
-                        "Expected IKE SA Proposal but received Child SA proposal");
-            }
-            mSaProposalList.add(proposal);
-            return this;
-        }
-
-        /**
-         * Uses pre-shared key to do IKE authentication.
-         *
-         * <p>Both client and server MUST be authenticated using the provided shared key. IKE
-         * authentication will fail if the remote peer tries to use other authentication methods.
-         *
-         * <p>Users MUST declare only one authentication method. Calling this function will override
-         * the previously set authentication configuration.
-         *
-         * @param sharedKey the shared key.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setAuthPsk(@NonNull byte[] sharedKey) {
-            mLocalAuthConfig = new IkeAuthPskConfig(sharedKey);
-            mRemoteAuthConfig = new IkeAuthPskConfig(sharedKey);
-            return this;
-        }
-
-        /**
-         * Uses EAP to do IKE authentication.
-         *
-         * <p>EAP are typically used to authenticate the IKE client to the server. It MUST be used
-         * in conjunction with a public-key-signature-based authentication of the server to the
-         * client.
-         *
-         * <p>Users MUST declare only one authentication method. Calling this function will override
-         * the previously set authentication configuration.
-         *
-         * @see <a href="https://tools.ietf.org/html/rfc5280">RFC 5280, Internet X.509 Public Key
-         *     Infrastructure Certificate and Certificate Revocation List (CRL) Profile</a>
-         * @param serverCaCert the CA certificate for validating the received server certificate(s).
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setAuthEap(
-                @NonNull X509Certificate serverCaCert, @NonNull EapSessionConfig eapConfig) {
-            mLocalAuthConfig = new IkeAuthEapConfig(eapConfig);
-
-            // The name constraints extension, defined in RFC 5280, indicates a name space within
-            // which all subject names in subsequent certificates in a certification path MUST be
-            // located.
-            mRemoteAuthConfig =
-                    new IkeAuthDigitalSignRemoteConfig(
-                            new TrustAnchor(serverCaCert, null /*nameConstraints*/));
-
-            // TODO: Investigate if we need to support the name constraints extension.
-
-            return this;
-        }
-
-        /**
-         * Uses certificate and digital signature to do IKE authentication.
-         *
-         * <p>The public key included by the client end certificate and the signature private key
-         * MUST come from the same key pair.
-         *
-         * <p>The IKE library will use the strongest signature algorithm supported by both sides.
-         *
-         * <p>Currenly only RSA digital signature is supported.
-         *
-         * @param serverCaCert the CA certificate for validating the received server certificate(s).
-         * @param clientEndCert the end certificate for remote server to verify the locally
-         *     generated signature.
-         * @param clientPrivateKey private key to generate outbound digital signature. Only {@link
-         *     RSAPrivateKey} is supported.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setAuthDigitalSignature(
-                @NonNull X509Certificate serverCaCert,
-                @NonNull X509Certificate clientEndCert,
-                @NonNull PrivateKey clientPrivateKey) {
-            return setAuthDigitalSignature(
-                    serverCaCert,
-                    clientEndCert,
-                    new LinkedList<X509Certificate>(),
-                    clientPrivateKey);
-        }
-
-        /**
-         * Uses certificate and digital signature to do IKE authentication.
-         *
-         * <p>The public key included by the client end certificate and the signature private key
-         * MUST come from the same key pair.
-         *
-         * <p>The IKE library will use the strongest signature algorithm supported by both sides.
-         *
-         * <p>Currenly only RSA digital signature is supported.
-         *
-         * @param serverCaCert the CA certificate for validating the received server certificate(s).
-         * @param clientEndCert the end certificate for remote server to verify locally generated
-         *     signature.
-         * @param clientIntermediateCerts intermediate certificates for the remote server to
-         *     validate the end certificate.
-         * @param clientPrivateKey private key to generate outbound digital signature. Only {@link
-         *     RSAPrivateKey} is supported.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder setAuthDigitalSignature(
-                @NonNull X509Certificate serverCaCert,
-                @NonNull X509Certificate clientEndCert,
-                @NonNull List<X509Certificate> clientIntermediateCerts,
-                @NonNull PrivateKey clientPrivateKey) {
-            if (!(clientPrivateKey instanceof RSAPrivateKey)) {
-                throw new IllegalArgumentException("Unsupported private key type");
-            }
-
-            mLocalAuthConfig =
-                    new IkeAuthDigitalSignLocalConfig(
-                            clientEndCert, clientIntermediateCerts, clientPrivateKey);
-            mRemoteAuthConfig =
-                    new IkeAuthDigitalSignRemoteConfig(
-                            new TrustAnchor(serverCaCert, null /*nameConstraints*/));
-            return this;
-        }
-
-        /**
-         * Validates, builds and returns the IkeSessionOptions
-         *
-         * @return IkeSessionOptions the validated IkeSessionOptions
-         * @throws IllegalArgumentException if no IKE SA proposal is provided
-         */
-        public IkeSessionOptions build() {
-            if (mSaProposalList.isEmpty()) {
-                throw new IllegalArgumentException("IKE SA proposal not found");
-            }
-            if (mServerAddress == null
-                    || mUdpEncapSocket == null
-                    || mLocalIdentification == null
-                    || mRemoteIdentification == null
-                    || mLocalAuthConfig == null
-                    || mRemoteAuthConfig == null) {
-                throw new IllegalArgumentException("Necessary parameter missing.");
-            }
-
-            return new IkeSessionOptions(
-                    mServerAddress,
-                    mUdpEncapSocket,
-                    mSaProposalList.toArray(new IkeSaProposal[mSaProposalList.size()]),
-                    mLocalIdentification,
-                    mRemoteIdentification,
-                    mLocalAuthConfig,
-                    mRemoteAuthConfig,
-                    mIsIkeFragmentationSupported);
-        }
-
-        // TODO: add methods for supporting IKE fragmentation.
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/IkeTrafficSelector.java b/src/java/android/net/ipsec/ike/IkeTrafficSelector.java
deleted file mode 100644
index 65154b9..0000000
--- a/src/java/android/net/ipsec/ike/IkeTrafficSelector.java
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.IntDef;
-import android.util.ArraySet;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.BufferOverflowException;
-import java.nio.ByteBuffer;
-import java.util.Objects;
-
-/**
- * IkeTrafficSelector represents a Traffic Selector of a Child SA.
- *
- * <p>IkeTrafficSelector can be constructed by users for initiating Create Child exchange or be
- * constructed from a decoded inbound Traffic Selector Payload.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.13">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeTrafficSelector {
-
-    // IpProtocolId consists of standard IP Protocol IDs.
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({IP_PROTOCOL_ID_UNSPEC, IP_PROTOCOL_ID_ICMP, IP_PROTOCOL_ID_TCP, IP_PROTOCOL_ID_UDP})
-    public @interface IpProtocolId {}
-
-    // Zero value is re-defined by IKE to indicate that all IP protocols are acceptable.
-    @VisibleForTesting static final int IP_PROTOCOL_ID_UNSPEC = 0;
-    @VisibleForTesting static final int IP_PROTOCOL_ID_ICMP = 1;
-    @VisibleForTesting static final int IP_PROTOCOL_ID_TCP = 6;
-    @VisibleForTesting static final int IP_PROTOCOL_ID_UDP = 17;
-
-    private static final ArraySet<Integer> IP_PROTOCOL_ID_SET = new ArraySet<>();
-
-    static {
-        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_UNSPEC);
-        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_ICMP);
-        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_TCP);
-        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_UDP);
-    }
-
-    /**
-     * TrafficSelectorType consists of IKE standard Traffic Selector Types.
-     *
-     * @see <a
-     *     href="https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml">Internet
-     *     Key Exchange Version 2 (IKEv2) Parameters</a>
-     */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE})
-    public @interface TrafficSelectorType {}
-
-    public static final int TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE = 7;
-    public static final int TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE = 8;
-
-    public static final int PORT_NUMBER_MIN = 0;
-    public static final int PORT_NUMBER_MAX = 65535;
-
-    // TODO: Consider defining these constants in a central place in Connectivity.
-    private static final int IPV4_ADDR_LEN = 4;
-    private static final int IPV6_ADDR_LEN = 16;
-
-    @VisibleForTesting static final int TRAFFIC_SELECTOR_IPV4_LEN = 16;
-    @VisibleForTesting static final int TRAFFIC_SELECTOR_IPV6_LEN = 40;
-
-    public final int tsType;
-    public final int ipProtocolId;
-    public final int selectorLength;
-    public final int startPort;
-    public final int endPort;
-    public final InetAddress startingAddress;
-    public final InetAddress endingAddress;
-
-    private IkeTrafficSelector(
-            int tsType,
-            int ipProtocolId,
-            int selectorLength,
-            int startPort,
-            int endPort,
-            InetAddress startingAddress,
-            InetAddress endingAddress) {
-        this.tsType = tsType;
-        this.ipProtocolId = ipProtocolId;
-        this.selectorLength = selectorLength;
-        this.startPort = startPort;
-        this.endPort = endPort;
-        this.startingAddress = startingAddress;
-        this.endingAddress = endingAddress;
-    }
-
-    /**
-     * Construct an instance of IkeTrafficSelector for building an outbound IKE message.
-     *
-     * @param tsType the Traffic Selector type.
-     * @param startPort the smallest port number allowed by this Traffic Selector.
-     * @param endPort the largest port number allowed by this Traffic Selector.
-     * @param startingAddress the smallest address included in this Traffic Selector.
-     * @param endingAddress the largest address included in this Traffic Selector.
-     */
-    public IkeTrafficSelector(
-            @TrafficSelectorType int tsType,
-            int startPort,
-            int endPort,
-            InetAddress startingAddress,
-            InetAddress endingAddress) {
-
-        this.tsType = tsType;
-        this.ipProtocolId = IP_PROTOCOL_ID_UNSPEC;
-
-        switch (tsType) {
-            case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE:
-                this.selectorLength = TRAFFIC_SELECTOR_IPV4_LEN;
-
-                if (!(startingAddress instanceof Inet4Address)
-                        || !(endingAddress instanceof Inet4Address)) {
-                    throw new IllegalArgumentException(
-                            "Invalid address range: TS_IPV4_ADDR_RANGE requires IPv4 addresses.");
-                }
-
-                break;
-            case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE:
-                throw new UnsupportedOperationException("Do not support IPv6 Traffic Selector.");
-                // TODO: Support IPv6 Traffic Selector.
-            default:
-                throw new IllegalArgumentException("Unrecognized Traffic Selector type.");
-        }
-
-        if (compareInetAddressTo(startingAddress, endingAddress) > 0) {
-            throw new IllegalArgumentException("Received invalid address range.");
-        }
-
-        if (!isPortRangeValid(startPort, endPort)) {
-            throw new IllegalArgumentException(
-                    "Invalid port range. startPort: " + startPort + " endPort: " + endPort);
-        }
-
-        this.startPort = startPort;
-        this.endPort = endPort;
-        this.startingAddress = startingAddress;
-        this.endingAddress = endingAddress;
-    }
-
-    /**
-     * Decode IkeTrafficSelectors from inbound Traffic Selector Payload.
-     *
-     * <p>This method is only called by IkeTsPayload when decoding inbound IKE message.
-     *
-     * @param numTs number or Traffic Selectors
-     * @param tsBytes encoded byte array of Traffic Selectors
-     * @return an array of decoded IkeTrafficSelectors
-     * @throws InvalidSyntaxException if received bytes are malformed.
-     */
-    public static IkeTrafficSelector[] decodeIkeTrafficSelectors(int numTs, byte[] tsBytes)
-            throws InvalidSyntaxException {
-        IkeTrafficSelector[] tsArray = new IkeTrafficSelector[numTs];
-        ByteBuffer inputBuffer = ByteBuffer.wrap(tsBytes);
-
-        try {
-            for (int i = 0; i < numTs; i++) {
-                int tsType = Byte.toUnsignedInt(inputBuffer.get());
-                switch (tsType) {
-                    case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE:
-                        tsArray[i] = decodeIpv4TrafficSelector(inputBuffer);
-                        break;
-                    case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE:
-                        // TODO: Support it.
-                        throw new UnsupportedOperationException("Cannot decode this type.");
-                    default:
-                        throw new InvalidSyntaxException(
-                                "Invalid Traffic Selector type: " + tsType);
-                }
-            }
-        } catch (BufferOverflowException e) {
-            // Throw exception if any Traffic Selector has invalid length.
-            throw new InvalidSyntaxException(e);
-        }
-
-        if (inputBuffer.remaining() != 0) {
-            throw new InvalidSyntaxException(
-                    "Unexpected trailing characters of Traffic Selectors.");
-        }
-
-        return tsArray;
-    }
-
-    // Decode Traffic Selector using IPv4 address range from a ByteBuffer. A BufferOverflowException
-    // will be thrown and caught by method caller if operation reaches the input ByteBuffer's limit.
-    private static IkeTrafficSelector decodeIpv4TrafficSelector(ByteBuffer inputBuffer)
-            throws InvalidSyntaxException {
-        // Decode and validate IP Protocol ID
-        int ipProtocolId = Byte.toUnsignedInt(inputBuffer.get());
-        if (!IP_PROTOCOL_ID_SET.contains(ipProtocolId)) {
-            throw new InvalidSyntaxException("Invalid IP Protocol ID.");
-        }
-
-        // Decode and validate Selector Length
-        int tsLength = Short.toUnsignedInt(inputBuffer.getShort());
-        if (TRAFFIC_SELECTOR_IPV4_LEN != tsLength) {
-            throw new InvalidSyntaxException("Invalid Traffic Selector Length.");
-        }
-
-        // Decode and validate ports
-        int startPort = Short.toUnsignedInt(inputBuffer.getShort());
-        int endPort = Short.toUnsignedInt(inputBuffer.getShort());
-        if (!isPortRangeValid(startPort, endPort)) {
-            throw new InvalidSyntaxException(
-                    "Received invalid port range. startPort: "
-                            + startPort
-                            + " endPort: "
-                            + endPort);
-        }
-
-        // Decode and validate IPv4 addresses
-        byte[] startAddressBytes = new byte[IPV4_ADDR_LEN];
-        byte[] endAddressBytes = new byte[IPV4_ADDR_LEN];
-        inputBuffer.get(startAddressBytes);
-        inputBuffer.get(endAddressBytes);
-        try {
-            Inet4Address startAddress =
-                    (Inet4Address) (Inet4Address.getByAddress(startAddressBytes));
-            Inet4Address endAddress = (Inet4Address) (Inet4Address.getByAddress(endAddressBytes));
-
-            // Validate address range.
-            if (compareInetAddressTo(startAddress, endAddress) > 0) {
-                throw new InvalidSyntaxException("Received invalid IPv4 address range.");
-            }
-
-            return new IkeTrafficSelector(
-                    TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                    ipProtocolId,
-                    TRAFFIC_SELECTOR_IPV4_LEN,
-                    startPort,
-                    endPort,
-                    startAddress,
-                    endAddress);
-        } catch (ClassCastException | UnknownHostException | IllegalArgumentException e) {
-            throw new InvalidSyntaxException(e);
-        }
-    }
-
-    // TODO: Add a method for decoding IPv6 traffic selector.
-
-    // Validate port range.
-    private static boolean isPortRangeValid(int startPort, int endPort) {
-        return (startPort >= PORT_NUMBER_MIN
-                && startPort <= PORT_NUMBER_MAX
-                && endPort >= PORT_NUMBER_MIN
-                && endPort <= PORT_NUMBER_MAX
-                && startPort <= endPort);
-    }
-
-    // Compare two InetAddresses. Return -1 if the first input is smaller; 1 if the second input is
-    // smaller; 0 if two addresses are equal.
-    // TODO: Consider moving it to the platform code in the future./
-    private static int compareInetAddressTo(InetAddress leftAddress, InetAddress rightAddress) {
-        byte[] leftAddrBytes = leftAddress.getAddress();
-        byte[] rightAddrBytes = rightAddress.getAddress();
-
-        if (leftAddrBytes.length != rightAddrBytes.length) {
-            throw new IllegalArgumentException("Two addresses are different types.");
-        }
-
-        for (int i = 0; i < leftAddrBytes.length; i++) {
-            int unsignedByteLeft = Byte.toUnsignedInt(leftAddrBytes[i]);
-            int unsignedByteRight = Byte.toUnsignedInt(rightAddrBytes[i]);
-
-            int result = Integer.compare(unsignedByteLeft, unsignedByteRight);
-            if (result != 0) return result;
-        }
-        return 0;
-    }
-
-    /**
-     * Check if the input IkeTrafficSelector is a subset of this instance.
-     *
-     * @param ts the provided IkeTrafficSelector to check.
-     * @return true if the input IkeTrafficSelector is a subset of this instance, otherwise false.
-     */
-    public boolean contains(IkeTrafficSelector ts) {
-        if (tsType == ts.tsType
-                && ipProtocolId == ts.ipProtocolId
-                && startPort <= ts.startPort
-                && endPort >= ts.endPort
-                && compareInetAddressTo(startingAddress, ts.startingAddress) <= 0
-                && compareInetAddressTo(endingAddress, ts.endingAddress) >= 0) {
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(
-                tsType,
-                ipProtocolId,
-                selectorLength,
-                startPort,
-                endPort,
-                startingAddress,
-                endingAddress);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof IkeTrafficSelector)) return false;
-
-        IkeTrafficSelector other = (IkeTrafficSelector) o;
-
-        if (tsType != other.tsType
-                || ipProtocolId != other.ipProtocolId
-                || startPort != other.startPort
-                || endPort != other.endPort) {
-            return false;
-        }
-
-        switch (tsType) {
-            case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE:
-                return (((Inet4Address) startingAddress)
-                                .equals((Inet4Address) other.startingAddress)
-                        && ((Inet4Address) endingAddress)
-                                .equals((Inet4Address) other.endingAddress));
-            case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE:
-                return (((Inet6Address) startingAddress)
-                                .equals((Inet6Address) other.startingAddress)
-                        && ((Inet6Address) endingAddress)
-                                .equals((Inet6Address) other.endingAddress));
-            default:
-                throw new UnsupportedOperationException("Unrecognized TS type");
-        }
-    }
-
-    /**
-     * Encode traffic selector to ByteBuffer.
-     *
-     * <p>This method will be only called by IkeTsPayload for building an outbound IKE message.
-     *
-     * @param byteBuffer destination ByteBuffer that stores encoded traffic selector.
-     */
-    public void encodeToByteBuffer(ByteBuffer byteBuffer) {
-        byteBuffer
-                .put((byte) tsType)
-                .put((byte) ipProtocolId)
-                .putShort((short) selectorLength)
-                .putShort((short) startPort)
-                .putShort((short) endPort)
-                .put(startingAddress.getAddress())
-                .put(endingAddress.getAddress());
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/SaProposal.java b/src/java/android/net/ipsec/ike/SaProposal.java
deleted file mode 100644
index 1e0b032..0000000
--- a/src/java/android/net/ipsec/ike/SaProposal.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2018 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.ipsec.ike;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.util.ArraySet;
-import android.util.SparseArray;
-
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * SaProposal represents a user configured set contains cryptograhic algorithms and key generating
- * materials for negotiating an IKE or Child SA.
- *
- * <p>User must provide at least a valid SaProposal when they are creating a new IKE SA or Child SA.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public abstract class SaProposal {
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        ENCRYPTION_ALGORITHM_3DES,
-        ENCRYPTION_ALGORITHM_AES_CBC,
-        ENCRYPTION_ALGORITHM_AES_GCM_8,
-        ENCRYPTION_ALGORITHM_AES_GCM_12,
-        ENCRYPTION_ALGORITHM_AES_GCM_16
-    })
-    public @interface EncryptionAlgorithm {}
-
-    public static final int ENCRYPTION_ALGORITHM_3DES = 3;
-    public static final int ENCRYPTION_ALGORITHM_AES_CBC = 12;
-    public static final int ENCRYPTION_ALGORITHM_AES_GCM_8 = 18;
-    public static final int ENCRYPTION_ALGORITHM_AES_GCM_12 = 19;
-    public static final int ENCRYPTION_ALGORITHM_AES_GCM_16 = 20;
-
-    private static final SparseArray<String> SUPPORTED_ENCRYPTION_ALGO_TO_STR;
-
-    static {
-        SUPPORTED_ENCRYPTION_ALGO_TO_STR = new SparseArray<>();
-        SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_3DES, "ENCR_3DES");
-        SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_CBC, "ENCR_AES_CBC");
-        SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_GCM_8, "ENCR_AES_GCM_8");
-        SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_GCM_12, "ENCR_AES_GCM_12");
-        SUPPORTED_ENCRYPTION_ALGO_TO_STR.put(ENCRYPTION_ALGORITHM_AES_GCM_16, "ENCR_AES_GCM_16");
-    }
-
-    public static final int KEY_LEN_UNUSED = 0;
-    public static final int KEY_LEN_AES_128 = 128;
-    public static final int KEY_LEN_AES_192 = 192;
-    public static final int KEY_LEN_AES_256 = 256;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({PSEUDORANDOM_FUNCTION_HMAC_SHA1, PSEUDORANDOM_FUNCTION_AES128_XCBC})
-    public @interface PseudorandomFunction {}
-
-    public static final int PSEUDORANDOM_FUNCTION_HMAC_SHA1 = 2;
-    public static final int PSEUDORANDOM_FUNCTION_AES128_XCBC = 4;
-
-    private static final SparseArray<String> SUPPORTED_PRF_TO_STR;
-
-    static {
-        SUPPORTED_PRF_TO_STR = new SparseArray<>();
-        SUPPORTED_PRF_TO_STR.put(PSEUDORANDOM_FUNCTION_HMAC_SHA1, "PRF_HMAC_SHA1");
-        SUPPORTED_PRF_TO_STR.put(PSEUDORANDOM_FUNCTION_AES128_XCBC, "PRF_AES128_XCBC");
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        INTEGRITY_ALGORITHM_NONE,
-        INTEGRITY_ALGORITHM_HMAC_SHA1_96,
-        INTEGRITY_ALGORITHM_AES_XCBC_96,
-        INTEGRITY_ALGORITHM_HMAC_SHA2_256_128,
-        INTEGRITY_ALGORITHM_HMAC_SHA2_384_192,
-        INTEGRITY_ALGORITHM_HMAC_SHA2_512_256
-    })
-    public @interface IntegrityAlgorithm {}
-
-    public static final int INTEGRITY_ALGORITHM_NONE = 0;
-    public static final int INTEGRITY_ALGORITHM_HMAC_SHA1_96 = 2;
-    public static final int INTEGRITY_ALGORITHM_AES_XCBC_96 = 5;
-    public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_256_128 = 12;
-    public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_384_192 = 13;
-    public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 = 14;
-
-    private static final SparseArray<String> SUPPORTED_INTEGRITY_ALGO_TO_STR;
-
-    static {
-        SUPPORTED_INTEGRITY_ALGO_TO_STR = new SparseArray<>();
-        SUPPORTED_INTEGRITY_ALGO_TO_STR.put(INTEGRITY_ALGORITHM_NONE, "AUTH_NONE");
-        SUPPORTED_INTEGRITY_ALGO_TO_STR.put(INTEGRITY_ALGORITHM_HMAC_SHA1_96, "AUTH_HMAC_SHA1_96");
-        SUPPORTED_INTEGRITY_ALGO_TO_STR.put(INTEGRITY_ALGORITHM_AES_XCBC_96, "AUTH_AES_XCBC_96");
-        SUPPORTED_INTEGRITY_ALGO_TO_STR.put(
-                INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, "AUTH_HMAC_SHA2_256_128");
-        SUPPORTED_INTEGRITY_ALGO_TO_STR.put(
-                INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, "AUTH_HMAC_SHA2_384_192");
-        SUPPORTED_INTEGRITY_ALGO_TO_STR.put(
-                INTEGRITY_ALGORITHM_HMAC_SHA2_512_256, "AUTH_HMAC_SHA2_512_256");
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({DH_GROUP_NONE, DH_GROUP_1024_BIT_MODP, DH_GROUP_2048_BIT_MODP})
-    public @interface DhGroup {}
-
-    public static final int DH_GROUP_NONE = 0;
-    public static final int DH_GROUP_1024_BIT_MODP = 2;
-    public static final int DH_GROUP_2048_BIT_MODP = 14;
-
-    private static final SparseArray<String> SUPPORTED_DH_GROUP_TO_STR;
-
-    static {
-        SUPPORTED_DH_GROUP_TO_STR = new SparseArray<>();
-        SUPPORTED_DH_GROUP_TO_STR.put(DH_GROUP_NONE, "DH_NONE");
-        SUPPORTED_DH_GROUP_TO_STR.put(DH_GROUP_1024_BIT_MODP, "DH_1024_BIT_MODP");
-        SUPPORTED_DH_GROUP_TO_STR.put(DH_GROUP_2048_BIT_MODP, "DH_2048_BIT_MODP");
-    }
-
-    @IkePayload.ProtocolId private final int mProtocolId;
-    private final EncryptionTransform[] mEncryptionAlgorithms;
-    private final IntegrityTransform[] mIntegrityAlgorithms;
-    private final DhGroupTransform[] mDhGroups;
-
-    protected SaProposal(
-            @IkePayload.ProtocolId int protocol,
-            EncryptionTransform[] encryptionAlgos,
-            IntegrityTransform[] integrityAlgos,
-            DhGroupTransform[] dhGroups) {
-        mProtocolId = protocol;
-        mEncryptionAlgorithms = encryptionAlgos;
-        mIntegrityAlgorithms = integrityAlgos;
-        mDhGroups = dhGroups;
-    }
-
-    /**
-     * Check if the current SaProposal from the SA responder is consistent with the selected
-     * reqProposal from the SA initiator.
-     *
-     * @param reqProposal selected SaProposal from SA initiator
-     * @return if current SaProposal from SA responder is consistent with the selected reqProposal
-     *     from SA initiator.
-     */
-    public boolean isNegotiatedFrom(SaProposal reqProposal) {
-        return this.mProtocolId == reqProposal.mProtocolId
-                && isTransformSelectedFrom(mEncryptionAlgorithms, reqProposal.mEncryptionAlgorithms)
-                && isTransformSelectedFrom(mIntegrityAlgorithms, reqProposal.mIntegrityAlgorithms)
-                && isTransformSelectedFrom(mDhGroups, reqProposal.mDhGroups);
-    }
-
-    /** Package private */
-    static boolean isTransformSelectedFrom(Transform[] selected, Transform[] selectFrom) {
-        // If the selected proposal has multiple transforms with the same type, the responder MUST
-        // choose a single one.
-        if ((selected.length > 1) || (selected.length == 0) != (selectFrom.length == 0)) {
-            return false;
-        }
-
-        if (selected.length == 0) return true;
-
-        return Arrays.asList(selectFrom).contains(selected[0]);
-    }
-
-    @IkePayload.ProtocolId
-    public int getProtocolId() {
-        return mProtocolId;
-    }
-
-    public EncryptionTransform[] getEncryptionTransforms() {
-        return mEncryptionAlgorithms;
-    }
-
-    public IntegrityTransform[] getIntegrityTransforms() {
-        return mIntegrityAlgorithms;
-    }
-
-    public DhGroupTransform[] getDhGroupTransforms() {
-        return mDhGroups;
-    }
-
-    protected List<Transform> getAllTransformsAsList() {
-        List<Transform> transformList = new LinkedList<>();
-
-        transformList.addAll(Arrays.asList(mEncryptionAlgorithms));
-        transformList.addAll(Arrays.asList(mIntegrityAlgorithms));
-        transformList.addAll(Arrays.asList(mDhGroups));
-
-        return transformList;
-    }
-
-    /**
-     * Return all SA Transforms in this SaProposal to be encoded for building an outbound IKE
-     * message.
-     *
-     * <p>This method should be called by only IKE library.
-     *
-     * @return Array of Transforms to be encoded.
-     */
-    public abstract Transform[] getAllTransforms();
-
-    /** This class is an abstract Builder for building a SaProposal */
-    protected abstract static class Builder {
-        protected static final String ERROR_TAG = "Invalid SA Proposal: ";
-
-        // Use set to avoid adding repeated algorithms.
-        protected final Set<EncryptionTransform> mProposedEncryptAlgos = new ArraySet<>();
-        protected final Set<PrfTransform> mProposedPrfs = new ArraySet<>();
-        protected final Set<IntegrityTransform> mProposedIntegrityAlgos = new ArraySet<>();
-        protected final Set<DhGroupTransform> mProposedDhGroups = new ArraySet<>();
-
-        protected boolean mHasAead = false;
-
-        protected static boolean isAead(@EncryptionAlgorithm int algorithm) {
-            switch (algorithm) {
-                case ENCRYPTION_ALGORITHM_3DES:
-                    // Fall through
-                case ENCRYPTION_ALGORITHM_AES_CBC:
-                    return false;
-                case ENCRYPTION_ALGORITHM_AES_GCM_8:
-                    // Fall through
-                case ENCRYPTION_ALGORITHM_AES_GCM_12:
-                    // Fall through
-                case ENCRYPTION_ALGORITHM_AES_GCM_16:
-                    return true;
-                default:
-                    // Won't hit here.
-                    throw new IllegalArgumentException("Unsupported Encryption Algorithm.");
-            }
-        }
-
-        protected EncryptionTransform[] buildEncryptAlgosOrThrow() {
-            if (mProposedEncryptAlgos.isEmpty()) {
-                throw new IllegalArgumentException(
-                        ERROR_TAG + "Encryption algorithm must be proposed.");
-            }
-
-            return mProposedEncryptAlgos.toArray(
-                    new EncryptionTransform[mProposedEncryptAlgos.size()]);
-        }
-
-        protected void validateAndAddEncryptAlgo(
-                @EncryptionAlgorithm int algorithm, int keyLength) {
-            // Construct EncryptionTransform and validate proposed algorithm during
-            // construction.
-            EncryptionTransform encryptionTransform = new EncryptionTransform(algorithm, keyLength);
-
-            // Validate that only one mode encryption algorithm has been proposed.
-            boolean isCurrentAead = isAead(algorithm);
-            if (!mProposedEncryptAlgos.isEmpty() && (mHasAead ^ isCurrentAead)) {
-                throw new IllegalArgumentException(
-                        ERROR_TAG
-                                + "Proposal cannot has both normal ciphers "
-                                + "and combined-mode ciphers.");
-            }
-            if (isCurrentAead) mHasAead = true;
-
-            mProposedEncryptAlgos.add(encryptionTransform);
-        }
-
-        protected void addIntegrityAlgo(@IntegrityAlgorithm int algorithm) {
-            // Construct IntegrityTransform and validate proposed algorithm during
-            // construction.
-            mProposedIntegrityAlgos.add(new IntegrityTransform(algorithm));
-        }
-
-        protected void addDh(@DhGroup int dhGroup) {
-            // Construct DhGroupTransform and validate proposed dhGroup during
-            // construction.
-            mProposedDhGroups.add(new DhGroupTransform(dhGroup));
-        }
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append(IkePayload.getProtocolTypeString(mProtocolId)).append(": ");
-
-        int len = getAllTransforms().length;
-        for (int i = 0; i < len; i++) {
-            sb.append(getAllTransforms()[i].toString());
-            if (i < len - 1) sb.append("|");
-        }
-
-        return sb.toString();
-    }
-
-    /**
-     * Check if the provided algorithm is a supported encryption algorithm.
-     *
-     * @param algorithm IKE standard encryption algorithm id.
-     * @return true if the provided algorithm is a supported encryption algorithm.
-     */
-    public static boolean isSupportedEncryptionAlgorithm(@EncryptionAlgorithm int algorithm) {
-        return SUPPORTED_ENCRYPTION_ALGO_TO_STR.get(algorithm) != null;
-    }
-
-    /**
-     * Check if the provided algorithm is a supported pseudorandom function.
-     *
-     * @param algorithm IKE standard pseudorandom function id.
-     * @return true if the provided algorithm is a supported pseudorandom function.
-     */
-    public static boolean isSupportedPseudorandomFunction(@PseudorandomFunction int algorithm) {
-        return SUPPORTED_PRF_TO_STR.get(algorithm) != null;
-    }
-
-    /**
-     * Check if the provided algorithm is a supported integrity algorithm.
-     *
-     * @param algorithm IKE standard integrity algorithm id.
-     * @return true if the provided algorithm is a supported integrity algorithm.
-     */
-    public static boolean isSupportedIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) {
-        return SUPPORTED_INTEGRITY_ALGO_TO_STR.get(algorithm) != null;
-    }
-
-    /**
-     * Check if the provided group number is for a supported Diffie-Hellman Group.
-     *
-     * @param dhGroup IKE standard DH Group id.
-     * @return true if the provided number is for a supported Diffie-Hellman Group.
-     */
-    public static boolean isSupportedDhGroup(@DhGroup int dhGroup) {
-        return SUPPORTED_DH_GROUP_TO_STR.get(dhGroup) != null;
-    }
-
-    /** Return the encryption algorithm as a String. */
-    public static String getEncryptionAlgorithmString(int algorithm) {
-        if (isSupportedEncryptionAlgorithm(algorithm)) {
-            return SUPPORTED_ENCRYPTION_ALGO_TO_STR.get(algorithm);
-        }
-        return "ENC_Unknown_" + algorithm;
-    }
-
-    /** Return the pseudorandom function as a String. */
-    public static String getPseudorandomFunctionString(int algorithm) {
-        if (isSupportedPseudorandomFunction(algorithm)) {
-            return SUPPORTED_PRF_TO_STR.get(algorithm);
-        }
-        return "PRF_Unknown_" + algorithm;
-    }
-
-    /** Return the integrity algorithm as a String. */
-    public static String getIntegrityAlgorithmString(int algorithm) {
-        if (isSupportedIntegrityAlgorithm(algorithm)) {
-            return SUPPORTED_INTEGRITY_ALGO_TO_STR.get(algorithm);
-        }
-        return "AUTH_Unknown_" + algorithm;
-    }
-
-    /** Return Diffie-Hellman Group as a String. */
-    public static String getDhGroupString(int dhGroup) {
-        if (isSupportedDhGroup(dhGroup)) {
-            return SUPPORTED_DH_GROUP_TO_STR.get(dhGroup);
-        }
-        return "DH_Unknown_" + dhGroup;
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/TransportModeChildSessionOptions.java b/src/java/android/net/ipsec/ike/TransportModeChildSessionOptions.java
deleted file mode 100644
index 12e0601..0000000
--- a/src/java/android/net/ipsec/ike/TransportModeChildSessionOptions.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import android.annotation.NonNull;
-
-/**
- * This class contains all user provided configuration options for negotiating a transport mode
- * Child Session.
- */
-public final class TransportModeChildSessionOptions extends ChildSessionOptions {
-    private TransportModeChildSessionOptions(
-            IkeTrafficSelector[] localTs,
-            IkeTrafficSelector[] remoteTs,
-            ChildSaProposal[] proposals) {
-        super(localTs, remoteTs, proposals, true /*isTransport*/);
-    }
-
-    /** This class can be used to incrementally construct a TransportModeChildSessionOptions. */
-    public static final class Builder extends ChildSessionOptions.Builder {
-        /** Create a Builder for negotiating a transport mode Child Session. */
-        public Builder() {
-            super();
-        }
-
-        /**
-         * Adds an Child SA proposal to TransportModeChildSessionOptions being built.
-         *
-         * @param proposal Child SA proposal.
-         * @return Builder this, to facilitate chaining.
-         * @throws IllegalArgumentException if input proposal is not a Child SA proposal.
-         */
-        public Builder addSaProposal(@NonNull ChildSaProposal proposal) {
-            validateAndAddSaProposal(proposal);
-            return this;
-        }
-
-        /**
-         * Validates, builds and returns the TransportModeChildSessionOptions.
-         *
-         * @return the validated TransportModeChildSessionOptions.
-         * @throws IllegalArgumentException if no Child SA proposal is provided.
-         */
-        public TransportModeChildSessionOptions build() {
-            validateOrThrow();
-
-            return new TransportModeChildSessionOptions(
-                    mLocalTsList.toArray(new IkeTrafficSelector[mLocalTsList.size()]),
-                    mRemoteTsList.toArray(new IkeTrafficSelector[mRemoteTsList.size()]),
-                    mSaProposalList.toArray(new ChildSaProposal[mSaProposalList.size()]));
-        }
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptions.java b/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptions.java
deleted file mode 100644
index cb8268c..0000000
--- a/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptions.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import android.annotation.NonNull;
-import android.net.LinkAddress;
-
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dhcp;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dns;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Subnet;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Dns;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Subnet;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This class contains all user provided configuration options for negotiating a tunnel mode Child
- * Session.
- */
-public final class TunnelModeChildSessionOptions extends ChildSessionOptions {
-    private final ConfigAttribute[] mConfigRequests;
-
-    private TunnelModeChildSessionOptions(
-            IkeTrafficSelector[] localTs,
-            IkeTrafficSelector[] remoteTs,
-            ChildSaProposal[] proposals,
-            ConfigAttribute[] configRequests) {
-        super(localTs, remoteTs, proposals, false /*isTransport*/);
-        mConfigRequests = configRequests;
-    }
-
-    public ConfigAttribute[] getConfigurationRequests() {
-        return mConfigRequests;
-    }
-
-    /** This class can be used to incrementally construct a TunnelModeChildSessionOptions. */
-    public static final class Builder extends ChildSessionOptions.Builder {
-        private static final int IPv4_DEFAULT_PREFIX_LEN = 32;
-
-        private boolean mHasIp4AddressRequest;
-        private List<ConfigAttribute> mConfigRequestList;
-
-        /** Create a Builder for negotiating a transport mode Child Session. */
-        public Builder() {
-            super();
-            mHasIp4AddressRequest = false;
-            mConfigRequestList = new LinkedList<>();
-        }
-
-        /**
-         * Adds an Child SA proposal to TunnelModeChildSessionOptions being built.
-         *
-         * @param proposal Child SA proposal.
-         * @return Builder this, to facilitate chaining.
-         * @throws IllegalArgumentException if input proposal is not a Child SA proposal.
-         */
-        public Builder addSaProposal(@NonNull ChildSaProposal proposal) {
-            validateAndAddSaProposal(proposal);
-            return this;
-        }
-
-        /**
-         * Adds internal IP address requests to TunnelModeChildSessionOptions being built.
-         *
-         * @param addressFamily the address family. Only {@link OsConstants.AF_INET} and {@link
-         *     OsConstants.AF_INET6} are allowed.
-         * @param numOfRequest the number of requests for this type of address.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalAddressRequest(int addressFamily, int numOfRequest) {
-            if (addressFamily == AF_INET) {
-                mHasIp4AddressRequest = true;
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv4Address());
-                }
-                return this;
-            } else if (addressFamily == AF_INET6) {
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv6Address());
-                }
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address family: " + addressFamily);
-            }
-        }
-
-        /**
-         * Adds specific internal IP address request to TunnelModeChildSessionOptions being built.
-         *
-         * @param address the requested address.
-         * @param prefixLen length of the InetAddress prefix. When requesting an IPv4 address,
-         *     prefixLen MUST be 32.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalAddressRequest(@NonNull InetAddress address, int prefixLen) {
-            if (address instanceof Inet4Address) {
-                if (prefixLen != IPv4_DEFAULT_PREFIX_LEN) {
-                    throw new IllegalArgumentException("Invalid IPv4 prefix length: " + prefixLen);
-                }
-                mHasIp4AddressRequest = true;
-                mConfigRequestList.add(new ConfigAttributeIpv4Address((Inet4Address) address));
-                return this;
-            } else if (address instanceof Inet6Address) {
-                mConfigRequestList.add(
-                        new ConfigAttributeIpv6Address(new LinkAddress(address, prefixLen)));
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address " + address);
-            }
-        }
-
-        /**
-         * Adds internal DNS server requests to TunnelModeChildSessionOptions being built.
-         *
-         * @param addressFamily the address family. Only {@link OsConstants.AF_INET} and {@link
-         *     OsConstants.AF_INET6} are allowed.
-         * @param numOfRequest the number of requests for this type of address.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalDnsServerRequest(int addressFamily, int numOfRequest) {
-            if (addressFamily == AF_INET) {
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv4Dns());
-                }
-                return this;
-            } else if (addressFamily == AF_INET6) {
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv6Dns());
-                }
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address family: " + addressFamily);
-            }
-        }
-
-        /**
-         * Adds internal DNS server requests to TunnelModeChildSessionOptions being built.
-         *
-         * @param address the requested DNS server address.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalDnsServerRequest(@NonNull InetAddress address) {
-            if (address instanceof Inet4Address) {
-                mConfigRequestList.add(new ConfigAttributeIpv4Dns((Inet4Address) address));
-                return this;
-            } else if (address instanceof Inet6Address) {
-                mConfigRequestList.add(new ConfigAttributeIpv6Dns((Inet6Address) address));
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address " + address);
-            }
-        }
-
-        /**
-         * Adds internal subnet requests to TunnelModeChildSessionOptions being built.
-         *
-         * @param addressFamily the address family. Only {@link OsConstants.AF_INET} and {@link
-         *     OsConstants.AF_INET6} are allowed.
-         * @param numOfRequest the number of requests for this type of address.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalSubnetRequest(int addressFamily, int numOfRequest) {
-            if (addressFamily == AF_INET) {
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv4Subnet());
-                }
-                return this;
-            } else if (addressFamily == AF_INET6) {
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv6Subnet());
-                }
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address family: " + addressFamily);
-            }
-        }
-
-        /**
-         * Adds internal DHCP server requests to TunnelModeChildSessionOptions being built.
-         *
-         * <p>Only DHCP4 server requests are supported.
-         *
-         * @param addressFamily the address family. Only {@link OsConstants.AF_INET} is allowed.
-         * @param numOfRequest the number of requests for this type of address.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalDhcpServerRequest(int addressFamily, int numOfRequest) {
-            if (addressFamily == AF_INET) {
-                for (int i = 0; i < numOfRequest; i++) {
-                    mConfigRequestList.add(new ConfigAttributeIpv4Dhcp());
-                }
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address family: " + addressFamily);
-            }
-        }
-
-        /**
-         * Adds internal DHCP server requests to TunnelModeChildSessionOptions being built.
-         *
-         * <p>Only DHCP4 server requests are supported.
-         *
-         * @param address the requested DHCP server address.
-         * @return Builder this, to facilitate chaining.
-         */
-        public Builder addInternalDhcpServerRequest(@NonNull InetAddress address) {
-            if (address instanceof Inet4Address) {
-                mConfigRequestList.add(new ConfigAttributeIpv4Dhcp((Inet4Address) address));
-                return this;
-            } else {
-                throw new IllegalArgumentException("Invalid address " + address);
-            }
-        }
-
-        /**
-         * Validates, builds and returns the TunnelModeChildSessionOptions.
-         *
-         * @return the validated TunnelModeChildSessionOptions.
-         * @throws IllegalArgumentException if no Child SA proposal is provided.
-         */
-        public TunnelModeChildSessionOptions build() {
-            validateOrThrow();
-
-            if (mHasIp4AddressRequest) {
-                mConfigRequestList.add(new ConfigAttributeIpv4Netmask());
-            }
-
-            return new TunnelModeChildSessionOptions(
-                    mLocalTsList.toArray(new IkeTrafficSelector[mLocalTsList.size()]),
-                    mRemoteTsList.toArray(new IkeTrafficSelector[mRemoteTsList.size()]),
-                    mSaProposalList.toArray(new ChildSaProposal[mSaProposalList.size()]),
-                    mConfigRequestList.toArray(new ConfigAttribute[mConfigRequestList.size()]));
-        }
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/exceptions/IkeException.java b/src/java/android/net/ipsec/ike/exceptions/IkeException.java
deleted file mode 100644
index 867dcf5..0000000
--- a/src/java/android/net/ipsec/ike/exceptions/IkeException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.ipsec.ike.exceptions;
-
-/**
- * IkeException is a generic IKE library exception class that provides type safety for all the
- * IKE-library-related exception classes that extend from it.
- */
-public abstract class IkeException extends Exception {
-    protected IkeException() {
-        super();
-    }
-
-    protected IkeException(String message) {
-        super(message);
-    }
-
-    protected IkeException(Throwable cause) {
-        super(cause);
-    }
-
-    protected IkeException(String message, Throwable cause) {
-        super(message, cause);
-    }
-
-    /**
-     * Returns if this exception is caused by an IKE protocol error.
-     *
-     * @return true if this exception is caused by an IKE protocol error, false otherwise.
-     */
-    public boolean isProtocolException() {
-        return this instanceof IkeProtocolException;
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/exceptions/IkeInternalException.java b/src/java/android/net/ipsec/ike/exceptions/IkeInternalException.java
deleted file mode 100644
index 29a5af9..0000000
--- a/src/java/android/net/ipsec/ike/exceptions/IkeInternalException.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.ipsec.ike.exceptions;
-
-/**
- * IkeInternalException represents all IKE-library-related exceptions that are not IKE protocol
- * error.
- */
-public final class IkeInternalException extends IkeException {
-    /**
-     * Constructs a new exception with the specified cause.
-     *
-     * @param cause the cause (which is saved for later retrieval by the {@link #getCause()}
-     *     method).
-     */
-    public IkeInternalException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a new exception with the specified cause.
-     *
-     * @param message the descriptive message.
-     * @param cause the cause (which is saved for later retrieval by the {@link #getCause()}
-     *     method).
-     */
-    public IkeInternalException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/android/net/ipsec/ike/exceptions/IkeProtocolException.java b/src/java/android/net/ipsec/ike/exceptions/IkeProtocolException.java
deleted file mode 100644
index f589a26..0000000
--- a/src/java/android/net/ipsec/ike/exceptions/IkeProtocolException.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.net.ipsec.ike.exceptions;
-
-import android.annotation.IntDef;
-
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
-
-/**
- * IkeProtocolException is an abstract class that represents the common information for all IKE
- * protocol errors.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.10.1">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public abstract class IkeProtocolException extends IkeException {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD,
-        ERROR_TYPE_INVALID_IKE_SPI,
-        ERROR_TYPE_INVALID_MAJOR_VERSION,
-        ERROR_TYPE_INVALID_SYNTAX,
-        ERROR_TYPE_INVALID_MESSAGE_ID,
-        ERROR_TYPE_NO_PROPOSAL_CHOSEN,
-        ERROR_TYPE_INVALID_KE_PAYLOAD,
-        ERROR_TYPE_AUTHENTICATION_FAILED,
-        ERROR_TYPE_SINGLE_PAIR_REQUIRED,
-        ERROR_TYPE_NO_ADDITIONAL_SAS,
-        ERROR_TYPE_INTERNAL_ADDRESS_FAILURE,
-        ERROR_TYPE_FAILED_CP_REQUIRED,
-        ERROR_TYPE_TS_UNACCEPTABLE,
-        ERROR_TYPE_INVALID_SELECTORS,
-        ERROR_TYPE_TEMPORARY_FAILURE,
-        ERROR_TYPE_CHILD_SA_NOT_FOUND,
-    })
-    public @interface ErrorType {}
-
-    public static final int ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD = 1;
-    public static final int ERROR_TYPE_INVALID_IKE_SPI = 4;
-    public static final int ERROR_TYPE_INVALID_MAJOR_VERSION = 5;
-    public static final int ERROR_TYPE_INVALID_SYNTAX = 7;
-    public static final int ERROR_TYPE_INVALID_MESSAGE_ID = 9;
-    public static final int ERROR_TYPE_NO_PROPOSAL_CHOSEN = 14;
-    public static final int ERROR_TYPE_INVALID_KE_PAYLOAD = 17;
-    public static final int ERROR_TYPE_AUTHENTICATION_FAILED = 24;
-    public static final int ERROR_TYPE_SINGLE_PAIR_REQUIRED = 34;
-    public static final int ERROR_TYPE_NO_ADDITIONAL_SAS = 35;
-    public static final int ERROR_TYPE_INTERNAL_ADDRESS_FAILURE = 36;
-    public static final int ERROR_TYPE_FAILED_CP_REQUIRED = 37;
-    public static final int ERROR_TYPE_TS_UNACCEPTABLE = 38;
-    public static final int ERROR_TYPE_INVALID_SELECTORS = 39;
-    public static final int ERROR_TYPE_TEMPORARY_FAILURE = 43;
-    public static final int ERROR_TYPE_CHILD_SA_NOT_FOUND = 44;
-
-    public static final byte[] ERROR_DATA_NOT_INCLUDED = new byte[0];
-
-    private static final int INTEGER_BYTE_SIZE = 4;
-
-    @ErrorType private final int mErrorType;
-    private final byte[] mErrorData;
-
-    protected IkeProtocolException(@ErrorType int code) {
-        super();
-        mErrorType = code;
-        mErrorData = ERROR_DATA_NOT_INCLUDED;
-    }
-
-    protected IkeProtocolException(@ErrorType int code, String message) {
-        super(message);
-        mErrorType = code;
-        mErrorData = ERROR_DATA_NOT_INCLUDED;
-    }
-
-    protected IkeProtocolException(@ErrorType int code, Throwable cause) {
-        super(cause);
-        mErrorType = code;
-        mErrorData = ERROR_DATA_NOT_INCLUDED;
-    }
-
-    protected IkeProtocolException(@ErrorType int code, String message, Throwable cause) {
-        super(message, cause);
-        mErrorType = code;
-        mErrorData = ERROR_DATA_NOT_INCLUDED;
-    }
-
-    // Construct an instance from a notify Payload.
-    protected IkeProtocolException(@ErrorType int code, byte[] notifyData) {
-        super();
-
-        if (!isValidDataLength(notifyData.length)) {
-            throw new IllegalArgumentException(
-                    "Invalid error data for error type: "
-                            + code
-                            + " Received error data size: "
-                            + notifyData.length);
-        }
-
-        mErrorType = code;
-        mErrorData = notifyData;
-    }
-
-    protected abstract boolean isValidDataLength(int dataLen);
-
-    protected static byte[] integerToByteArray(int integer, int arraySize) {
-        if (arraySize > INTEGER_BYTE_SIZE) {
-            throw new IllegalArgumentException(
-                    "Cannot convert integer to a byte array of length: " + arraySize);
-        }
-
-        ByteBuffer dataBuffer = ByteBuffer.allocate(INTEGER_BYTE_SIZE);
-        dataBuffer.putInt(integer);
-        dataBuffer.rewind();
-
-        byte[] zeroPad = new byte[INTEGER_BYTE_SIZE - arraySize];
-        byte[] byteData = new byte[arraySize];
-        dataBuffer.get(zeroPad).get(byteData);
-
-        return byteData;
-    }
-
-    protected static int byteArrayToInteger(byte[] byteArray) {
-        if (byteArray == null || byteArray.length > INTEGER_BYTE_SIZE) {
-            throw new IllegalArgumentException("Cannot convert the byte array to integer");
-        }
-
-        ByteBuffer dataBuffer = ByteBuffer.allocate(INTEGER_BYTE_SIZE);
-        byte[] zeroPad = new byte[INTEGER_BYTE_SIZE - byteArray.length];
-        dataBuffer.put(zeroPad).put(byteArray);
-        dataBuffer.rewind();
-
-        return dataBuffer.getInt();
-    }
-
-    /**
-     * Returns the IKE standard protocol error type of this {@link IkeProtocolException} instance.
-     *
-     * @return the IKE standard protocol error type.
-     */
-    @ErrorType
-    public int getErrorType() {
-        return mErrorType;
-    }
-
-    /**
-     * Returns the included error data of this {@link IkeProtocolException} instance.
-     *
-     * <p>Note that only few error types will go with an error data. This data has different meaning
-     * with different error types. Users should first check if an error data is included before they
-     * call this method.
-     *
-     * @return the included error data in byte array.
-     */
-    public byte[] getErrorData() {
-        return mErrorData;
-    }
-
-    /**
-     * Build an IKE Notification Payload for this {@link IkeProtocolException} instance.
-     *
-     * @return the notification payload.
-     */
-    public IkeNotifyPayload buildNotifyPayload() {
-        return new IkeNotifyPayload(mErrorType, mErrorData);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapFailureStateTest.java b/src/java/com/android/ike/ikev2/ChildSessionOptions.java
similarity index 65%
rename from tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapFailureStateTest.java
rename to src/java/com/android/ike/ikev2/ChildSessionOptions.java
index 1dd60c0..b311c66 100644
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapFailureStateTest.java
+++ b/src/java/com/android/ike/ikev2/ChildSessionOptions.java
@@ -14,16 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.eap.statemachine;
+package com.android.ike.ikev2;
 
-import org.junit.Before;
-
-public class EapMsChapV2AwaitingEapFailureStateTest extends EapMsChapV2StateTest {
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mStateMachine.transitionTo(mStateMachine.new AwaitingEapFailureState());
-    }
+/**
+ * ChildSessionOptions contains user-provided Child SA proposals and negotiated Child SA
+ * information.
+ */
+public final class ChildSessionOptions {
+    // TODO: Implement it.
 }
diff --git a/src/java/com/android/ike/ikev2/ChildSessionStateMachine.java b/src/java/com/android/ike/ikev2/ChildSessionStateMachine.java
new file mode 100644
index 0000000..81822d5
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/ChildSessionStateMachine.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2;
+
+import android.os.Looper;
+import android.os.Message;
+
+import com.android.ike.ikev2.IkeSessionStateMachine.IChildSessionCallback;
+import com.android.ike.ikev2.SaRecord.ChildSaRecord;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.message.IkePayload;
+import com.android.ike.ikev2.message.IkeSaPayload;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import java.util.List;
+
+/**
+ * ChildSessionStateMachine tracks states and manages exchanges of this Child Session.
+ *
+ * <p>ChildSessionStateMachine has two types of states. One type are states where there is no
+ * ongoing procedure affecting Child Session (non-procedure state), including Initial, Closed, Idle
+ * and Receiving. All other states are "procedure" states which are named as follows:
+ *
+ * <pre>
+ * State Name = [Procedure Type] + [Exchange Initiator] + [Exchange Type].
+ * - An IKE procedure consists of one or two IKE exchanges:
+ *      Procedure Type = {CreateChild | DeleteChild | Info | RekeyChild | SimulRekeyChild}.
+ * - Exchange Initiator indicates whether local or remote peer is the exchange initiator:
+ *      Exchange Initiator = {Local | Remote}
+ * - Exchange type defines the function of this exchange.
+ *      Exchange Type = {Create | Delete}
+ * </pre>
+ */
+public class ChildSessionStateMachine extends StateMachine {
+    private static final String TAG = "ChildSessionStateMachine";
+
+    /** Receive request for negotiating first Child SA. */
+    private static final int CMD_HANDLE_FIRST_CHILD_EXCHANGE = 1;
+
+    private final ChildSessionOptions mChildSessionOptions;
+
+    /** Package private */
+    @VisibleForTesting ChildSaRecord mCurrentChildSaRecord;
+
+    private final State mInitial = new Initial();
+    private final State mClosed = new Closed();
+    private final State mIdle = new Idle();
+
+    /** Package private */
+    ChildSessionStateMachine(String name, Looper looper, ChildSessionOptions sessionOptions) {
+        super(name, looper);
+
+        mChildSessionOptions = sessionOptions;
+
+        addState(mInitial);
+        addState(mClosed);
+        addState(mIdle);
+
+        setInitialState(mInitial);
+    }
+
+    private void validateCreateChildResp(
+            List<IkePayload> reqPayloads, List<IkePayload> respPayloads) throws IkeException {
+        // TODO: Validate SA reponse against request and set negotiated SA in mChildSessionOptions.
+        return;
+    }
+
+    /**
+     * Receive requesting and responding payloads for negotiating first Child SA.
+     *
+     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
+     * as an asynchronous job to the ChildStateMachine handler.
+     *
+     * @param reqPayloads SA negotiation related payloads in IKE_AUTH request.
+     * @param respPayloads SA negotiation related payloads in IKE_AUTH response.
+     * @param callback callback for notifying IkeSessionStateMachine the negotiation result.
+     */
+    public void handleFirstChildExchange(
+            List<IkePayload> reqPayloads,
+            List<IkePayload> respPayloads,
+            IChildSessionCallback callback) {
+        registerProvisionalChildSession(respPayloads, callback);
+
+        sendMessage(
+                CMD_HANDLE_FIRST_CHILD_EXCHANGE,
+                new FirstChildNegotiationData(reqPayloads, respPayloads, callback));
+    }
+
+    /**
+     * Register provisioning ChildSessionStateMachine in IChildSessionCallback
+     *
+     * <p>This method is for avoiding CHILD_SA_NOT_FOUND error in IkeSessionStateMachine when remote
+     * peer sends request for delete/rekey this Child SA before ChildSessionStateMachine sends
+     * FirstChildNegotiationData to itself.
+     */
+    private void registerProvisionalChildSession(
+            List<IkePayload> respPayloads, IChildSessionCallback callback) {
+        // When decoding responding IkeSaPayload in IkeSessionStateMachine, it is validated that
+        // IkeSaPayload has exactly one IkeSaPayload.Proposal.
+        IkeSaPayload saPayload = null;
+        for (IkePayload payload : respPayloads) {
+            if (payload.payloadType == IkePayload.PAYLOAD_TYPE_SA) {
+                saPayload = (IkeSaPayload) payload;
+                break;
+            }
+        }
+        if (saPayload == null) {
+            throw new IllegalArgumentException(
+                    "Receive no SA payload for first Child SA negotiation.");
+        }
+        // IkeSaPayload.Proposal stores SPI in long type so as to be applied to both 8-byte IKE SPI
+        // and 4-byte Child SPI. Here we cast the stored SPI to int to represent a Child SPI.
+        int remoteGenSpi = (int) (saPayload.proposalList.get(0).spi);
+        callback.onCreateChildSa(remoteGenSpi, this);
+    }
+
+    /**
+     * FirstChildNegotiationData contains payloads for negotiating first Child SA in IKE_AUTH
+     * request and IKE_AUTH response and callback to notify IkeSessionStateMachine the SA
+     * negotiation result.
+     */
+    private static class FirstChildNegotiationData {
+        public final List<IkePayload> requestPayloads;
+        public final List<IkePayload> responsePayloads;
+        public final IChildSessionCallback childCallback;
+
+        FirstChildNegotiationData(
+                List<IkePayload> reqPayloads,
+                List<IkePayload> respPayloads,
+                IChildSessionCallback callback) {
+            requestPayloads = reqPayloads;
+            responsePayloads = respPayloads;
+            childCallback = callback;
+        }
+    }
+
+    /** Initial state of ChildSessionStateMachine. */
+    class Initial extends State {
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                    // TODO: Handle local request for creating Child SA.
+                case CMD_HANDLE_FIRST_CHILD_EXCHANGE:
+                    FirstChildNegotiationData childNegotiationData =
+                            (FirstChildNegotiationData) message.obj;
+                    try {
+                        List<IkePayload> reqPayloads = childNegotiationData.requestPayloads;
+                        List<IkePayload> respPayloads = childNegotiationData.responsePayloads;
+                        validateCreateChildResp(reqPayloads, respPayloads);
+
+                        mCurrentChildSaRecord =
+                                ChildSaRecord.makeChildSaRecord(reqPayloads, respPayloads);
+                        // TODO: Add mCurrentChildSaRecord in mSpiToSaRecordMap.
+                        transitionTo(mIdle);
+                    } catch (IkeException e) {
+                        // TODO: Unregister remotely generated SPI and handle Child SA negotiation
+                        // failure.
+                    }
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
+    /**
+     * Closed represents the state when this ChildSessionStateMachine is closed, and no further
+     * actions can be performed on it.
+     */
+    class Closed extends State {
+        // TODO: Implement it.
+    }
+
+    /**
+     * Idle represents a state when there is no ongoing IKE exchange affecting established Child SA.
+     */
+    class Idle extends State {
+        // TODO: Implement it.
+    }
+
+    // TODO: Add states to support creating additional Child SA, deleting Child SA and rekeying
+    // Child SA.
+}
diff --git a/src/java/com/android/ike/ikev2/ChildSessionStateMachineFactory.java b/src/java/com/android/ike/ikev2/ChildSessionStateMachineFactory.java
new file mode 100644
index 0000000..f182111
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/ChildSessionStateMachineFactory.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import android.os.Looper;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+/** Package private factory for making ChildSessionStateMachine. */
+//TODO: Make it a inner Creator class of ChildSessionStateMachine
+final class ChildSessionStateMachineFactory {
+
+    private static IChildSessionFactoryHelper sChildSessionHelper = new ChildSessionFactoryHelper();
+
+    /** Package private. */
+    static ChildSessionStateMachine makeChildSessionStateMachine(
+            String name, Looper looper, ChildSessionOptions sessionOptions) {
+        return sChildSessionHelper.makeChildSessionStateMachine(name, looper, sessionOptions);
+    }
+
+    @VisibleForTesting
+    static void setChildSessionFactoryHelper(IChildSessionFactoryHelper helper) {
+        sChildSessionHelper = helper;
+    }
+
+    /**
+     * IChildSessionFactoryHelper provides a package private interface for constructing
+     * ChildSessionStateMachine.
+     *
+     * <p>IChildSessionFactoryHelper exists so that the interface is injectable for testing.
+     */
+    interface IChildSessionFactoryHelper {
+        ChildSessionStateMachine makeChildSessionStateMachine(
+                String name, Looper looper, ChildSessionOptions sessionOptions);
+    }
+
+    /**
+     * ChildSessionFactoryHelper implements a method for constructing ChildSessionStateMachine.
+     *
+     * <p>Package private.
+     */
+    static class ChildSessionFactoryHelper implements IChildSessionFactoryHelper {
+        public ChildSessionStateMachine makeChildSessionStateMachine(
+                String name, Looper looper, ChildSessionOptions sessionOptions) {
+            ChildSessionStateMachine childSession =
+                    new ChildSessionStateMachine(name, looper, sessionOptions);
+            childSession.start();
+            return childSession;
+        }
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeDhParams.java b/src/java/com/android/ike/ikev2/IkeDhParams.java
similarity index 97%
rename from src/java/com/android/internal/net/ipsec/ike/IkeDhParams.java
rename to src/java/com/android/ike/ikev2/IkeDhParams.java
index 44373fc..604353a 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeDhParams.java
+++ b/src/java/com/android/ike/ikev2/IkeDhParams.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike;
+package com.android.ike.ikev2;
 
 /** IkeDhParams contains Diffie-Hellman constants for IKEv2 supported DH Groups */
 public class IkeDhParams {
diff --git a/src/java/com/android/ike/ikev2/IkeIdentification.java b/src/java/com/android/ike/ikev2/IkeIdentification.java
new file mode 100644
index 0000000..994a024
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/IkeIdentification.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import android.annotation.IntDef;
+import android.util.ArraySet;
+
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * IkeIdentification is abstract base class that represents the common information for all types of
+ * IKE entity identification.
+ *
+ * <p>IkeIdentification can be user configured or be constructed from an inbound packet.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.5">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public abstract class IkeIdentification {
+    // Set of supported ID types.
+    private static final Set<Integer> SUPPORTED_ID_TYPES;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        ID_TYPE_IPV4_ADDR,
+        ID_TYPE_FQDN,
+        ID_TYPE_RFC822_ADDR,
+        ID_TYPE_IPV6_ADDR,
+        ID_TYPE_DER_ASN1_DN,
+        ID_TYPE_DER_ASN1_GN,
+        ID_TYPE_KEY_ID
+    })
+    public @interface IdType {}
+
+    public static final int ID_TYPE_IPV4_ADDR = 1;
+    public static final int ID_TYPE_FQDN = 2;
+    public static final int ID_TYPE_RFC822_ADDR = 3;
+    public static final int ID_TYPE_IPV6_ADDR = 5;
+    public static final int ID_TYPE_DER_ASN1_DN = 9;
+    public static final int ID_TYPE_DER_ASN1_GN = 10;
+    public static final int ID_TYPE_KEY_ID = 11;
+
+    static {
+        SUPPORTED_ID_TYPES = new ArraySet();
+        SUPPORTED_ID_TYPES.add(ID_TYPE_IPV4_ADDR);
+        SUPPORTED_ID_TYPES.add(ID_TYPE_FQDN);
+        SUPPORTED_ID_TYPES.add(ID_TYPE_RFC822_ADDR);
+        SUPPORTED_ID_TYPES.add(ID_TYPE_IPV6_ADDR);
+        SUPPORTED_ID_TYPES.add(ID_TYPE_DER_ASN1_DN);
+        SUPPORTED_ID_TYPES.add(ID_TYPE_DER_ASN1_GN);
+        SUPPORTED_ID_TYPES.add(ID_TYPE_KEY_ID);
+    }
+
+    public final int idType;
+
+    protected IkeIdentification(@IdType int type) {
+        idType = type;
+    }
+
+    /**
+     * Return the encoded identification data in a byte array.
+     *
+     * @return the encoded identification data.
+     */
+    public abstract byte[] getEncodedIdData();
+
+    /** IkeIpv4AddrIdentification represents ID information in IPv4 address ID type. */
+    public static class IkeIpv4AddrIdentification extends IkeIdentification {
+        public final Inet4Address ipv4Address;
+
+        /**
+         * Construct an instance of IkeIpv4AddrIdentification from decoding an inbound packet.
+         *
+         * @param ipv4AddrBytes IPv4 address in byte array.
+         * @throws AuthenticationFailedException for decoding bytes error.
+         */
+        public IkeIpv4AddrIdentification(byte[] ipv4AddrBytes)
+                throws AuthenticationFailedException {
+            super(ID_TYPE_IPV4_ADDR);
+            try {
+                ipv4Address = (Inet4Address) (Inet4Address.getByAddress(ipv4AddrBytes));
+            } catch (ClassCastException | UnknownHostException e) {
+                throw new AuthenticationFailedException(e);
+            }
+        }
+
+        /**
+         * Construct an instance of IkeIpv4AddrIdentification with user provided IPv4 address for
+         * building outbound packet.
+         *
+         * @param address user provided IPv4 address
+         */
+        public IkeIpv4AddrIdentification(Inet4Address address) {
+            super(ID_TYPE_IPV4_ADDR);
+            ipv4Address = address;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(idType, ipv4Address);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof IkeIpv4AddrIdentification)) return false;
+
+            return ipv4Address.equals(((IkeIpv4AddrIdentification) o).ipv4Address);
+        }
+
+        /**
+         * Retrieve the byte-representation of the IPv4 address.
+         *
+         * @return the byte-representation of the IPv4 address.
+         */
+        @Override
+        public byte[] getEncodedIdData() {
+            return ipv4Address.getAddress();
+        }
+    }
+
+    /** IkeIpv6AddrIdentification represents ID information in IPv6 address ID type. */
+    public static class IkeIpv6AddrIdentification extends IkeIdentification {
+        public final Inet6Address ipv6Address;
+
+        /**
+         * Construct an instance of IkeIpv6AddrIdentification from decoding an inbound packet.
+         *
+         * @param ipv6AddrBytes IPv6 address in byte array.
+         * @throws AuthenticationFailedException for decoding bytes error.
+         */
+        public IkeIpv6AddrIdentification(byte[] ipv6AddrBytes)
+                throws AuthenticationFailedException {
+            super(ID_TYPE_IPV6_ADDR);
+            try {
+                ipv6Address = (Inet6Address) (Inet6Address.getByAddress(ipv6AddrBytes));
+            } catch (ClassCastException | UnknownHostException e) {
+                throw new AuthenticationFailedException(e);
+            }
+        }
+
+        /**
+         * Construct an instance of IkeIpv6AddrIdentification with user provided IPv6 address for
+         * building outbound packet.
+         *
+         * @param address user provided IPv6 address
+         */
+        public IkeIpv6AddrIdentification(Inet6Address address) {
+            super(ID_TYPE_IPV6_ADDR);
+            ipv6Address = address;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(idType, ipv6Address);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof IkeIpv6AddrIdentification)) return false;
+
+            return ipv6Address.equals(((IkeIpv6AddrIdentification) o).ipv6Address);
+        }
+
+        /**
+         * Retrieve the byte-representation of the IPv6 address.
+         *
+         * @return the byte-representation of the IPv6 address.
+         */
+        @Override
+        public byte[] getEncodedIdData() {
+            return ipv6Address.getAddress();
+        }
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/IkeSessionOptions.java b/src/java/com/android/ike/ikev2/IkeSessionOptions.java
new file mode 100644
index 0000000..9f2094f
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/IkeSessionOptions.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import android.net.IpSecManager.UdpEncapsulationSocket;
+
+import com.android.ike.ikev2.message.IkePayload;
+
+import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * IkeSessionOptions contains all user provided configurations for negotiating an IKE SA.
+ *
+ * <p>TODO: Make this doc more user-friendly.
+ */
+public final class IkeSessionOptions {
+    private final InetAddress mServerAddress;
+    private final UdpEncapsulationSocket mUdpEncapSocket;
+    private final SaProposal[] mSaProposals;
+    private final boolean mIsIkeFragmentationSupported;
+
+    private IkeSessionOptions(
+            InetAddress serverAddress,
+            UdpEncapsulationSocket udpEncapsulationSocket,
+            SaProposal[] proposals,
+            boolean isIkeFragmentationSupported) {
+        mServerAddress = serverAddress;
+        mUdpEncapSocket = udpEncapsulationSocket;
+        mSaProposals = proposals;
+        mIsIkeFragmentationSupported = isIkeFragmentationSupported;
+    }
+
+    /** Package private */
+    InetAddress getServerAddress() {
+        return mServerAddress;
+    }
+    /** Package private */
+    UdpEncapsulationSocket getUdpEncapsulationSocket() {
+        return mUdpEncapSocket;
+    }
+    /** Package private */
+    SaProposal[] getSaProposals() {
+        return mSaProposals;
+    }
+    /** Package private */
+    boolean isIkeFragmentationSupported() {
+        return mIsIkeFragmentationSupported;
+    }
+
+    /** This class can be used to incrementally construct a IkeSessionOptions. */
+    public static final class Builder {
+        private final InetAddress mServerAddress;
+        private final UdpEncapsulationSocket mUdpEncapSocket;
+        private final List<SaProposal> mSaProposalList = new LinkedList<>();
+
+        private boolean mIsIkeFragmentationSupported = false;
+
+        /**
+         * Returns a new Builder for an IkeSessionOptions.
+         *
+         * @param serverAddress IP address of remote IKE server.
+         * @param udpEncapsulationSocket {@link IpSecManager.UdpEncapsulationSocket} for sending and
+         *     receiving IKE message.
+         * @return Builder for an IkeSessionOptions.
+         */
+        public Builder(InetAddress serverAddress, UdpEncapsulationSocket udpEncapsulationSocket) {
+            mServerAddress = serverAddress;
+            mUdpEncapSocket = udpEncapsulationSocket;
+        }
+
+        /**
+         * Adds an IKE SA proposal to IkeSessionOptions being built.
+         *
+         * @param proposal IKE SA proposal.
+         * @return Builder for an IkeSessionOptions.
+         * @throws IllegalArgumentException if input proposal is not IKE SA proposal.
+         */
+        public Builder addSaProposal(SaProposal proposal) {
+            if (proposal.getProtocolId() != IkePayload.PROTOCOL_ID_IKE) {
+                throw new IllegalArgumentException(
+                        "Expected IKE SA Proposal but received Child SA proposal");
+            }
+            mSaProposalList.add(proposal);
+            return this;
+        }
+
+        /**
+         * Validates, builds and returns the IkeSessionOptions
+         *
+         * @return IkeSessionOptions the validated IkeSessionOptions
+         * @throws IllegalStateException if no IKE SA proposal is provided
+         */
+        public IkeSessionOptions build() {
+            if (mSaProposalList.isEmpty()) {
+                throw new IllegalArgumentException("IKE SA proposal not found");
+            }
+            return new IkeSessionOptions(
+                    mServerAddress,
+                    mUdpEncapSocket,
+                    mSaProposalList.toArray(new SaProposal[mSaProposalList.size()]),
+                    mIsIkeFragmentationSupported);
+        }
+
+        // TODO: add methods for supporting IKE fragmentation.
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/IkeSessionStateMachine.java b/src/java/com/android/ike/ikev2/IkeSessionStateMachine.java
new file mode 100644
index 0000000..b4a7b9c
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/IkeSessionStateMachine.java
@@ -0,0 +1,952 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2;
+
+import android.os.Looper;
+import android.os.Message;
+import android.system.ErrnoException;
+import android.util.LongSparseArray;
+import android.util.SparseArray;
+
+import com.android.ike.ikev2.SaRecord.IkeSaRecord;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.message.IkeHeader;
+import com.android.ike.ikev2.message.IkeKePayload;
+import com.android.ike.ikev2.message.IkeMessage;
+import com.android.ike.ikev2.message.IkeNoncePayload;
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+import com.android.ike.ikev2.message.IkePayload;
+import com.android.ike.ikev2.message.IkeSaPayload;
+import com.android.ike.ikev2.message.IkeSaPayload.DhGroupTransform;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.State;
+import com.android.internal.util.StateMachine;
+
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * IkeSessionStateMachine tracks states and manages exchanges of this IKE session.
+ *
+ * <p>IkeSessionStateMachine has two types of states. One type are states where there is no ongoing
+ * procedure affecting IKE session (non-procedure state), including Initial, Closed, Idle and
+ * Receiving. All other states are "procedure" states which are named as follows:
+ *
+ * <pre>
+ * State Name = [Procedure Type] + [Exchange Initiator] + [Exchange Type].
+ * - An IKE procedure consists of one or two IKE exchanges:
+ *      Procedure Type = {CreateIke | DeleteIke | Info | RekeyIke | SimulRekeyIke}.
+ * - Exchange Initiator indicates whether local or remote peer is the exchange initiator:
+ *      Exchange Initiator = {Local | Remote}
+ * - Exchange type defines the function of this exchange. To make it more descriptive, we separate
+ *      Delete Exchange from generic Informational Exchange:
+ *      Exchange Type = {IkeInit | IkeAuth | Create | Delete | Info}
+ * </pre>
+ */
+public class IkeSessionStateMachine extends StateMachine {
+
+    private static final String TAG = "IkeSessionStateMachine";
+
+    /** Package private signals accessible for testing code. */
+    private static final int CMD_GENERAL_BASE = 0;
+    /** Receive encoded IKE packet on IkeSessionStateMachine. */
+    static final int CMD_RECEIVE_IKE_PACKET = CMD_GENERAL_BASE + 1;
+    /** Receive locally built payloads from Child Session for building outbound IKE message. */
+    static final int CMD_RECEIVE_OUTBOUND_CHILD_PAYLOADS = CMD_GENERAL_BASE + 2;
+    /** Receive encoded IKE packet with unrecognized IKE SPI on IkeSessionStateMachine. */
+    static final int CMD_RECEIVE_PACKET_INVALID_IKE_SPI = CMD_GENERAL_BASE + 3;
+    // TODO: Add signal for retransmission.
+
+    private static final int CMD_LOCAL_REQUEST_BASE = CMD_GENERAL_BASE + 100;
+    static final int CMD_LOCAL_REQUEST_CREATE_IKE = CMD_LOCAL_REQUEST_BASE + 1;
+    static final int CMD_LOCAL_REQUEST_DELETE_IKE = CMD_LOCAL_REQUEST_BASE + 2;
+    static final int CMD_LOCAL_REQUEST_REKEY_IKE = CMD_LOCAL_REQUEST_BASE + 3;
+    static final int CMD_LOCAL_REQUEST_INFO = CMD_LOCAL_REQUEST_BASE + 4;
+    static final int CMD_LOCAL_REQUEST_CREATE_CHILD = CMD_LOCAL_REQUEST_BASE + 5;
+    static final int CMD_LOCAL_REQUEST_DELETE_CHILD = CMD_LOCAL_REQUEST_BASE + 6;
+    static final int CMD_LOCAL_REQUEST_REKEY_CHILD = CMD_LOCAL_REQUEST_BASE + 7;
+    // TODO: Add signals for other procedure types and notificaitons.
+
+    // Remember locally assigned IKE SPIs to avoid SPI collision.
+    private static final Set<Long> ASSIGNED_LOCAL_IKE_SPI_SET = new HashSet<>();
+    private static final int MAX_ASSIGN_IKE_SPI_ATTEMPTS = 100;
+    private static final SecureRandom IKE_SPI_RANDOM = new SecureRandom();
+
+    private final IkeSessionOptions mIkeSessionOptions;
+    private final ChildSessionOptions mFirstChildSessionOptions;
+    /** Map that stores all IkeSaRecords, keyed by remotely generated IKE SPI. */
+    private final LongSparseArray<IkeSaRecord> mSpiToSaRecordMap;
+    /**
+     * Map that stores all ChildSessionStateMachines, keyed by remotely generated Child SPI for
+     * sending IPsec packet. Different SPIs may point to the same ChildSessionStateMachine if this
+     * Child Session is doing Rekey.
+     */
+    private final SparseArray<ChildSessionStateMachine> mSpiToChildSessionMap;
+
+    /**
+     * Package private socket that sends and receives encoded IKE message. Initialized in Initial
+     * State.
+     */
+    @VisibleForTesting IkeSocket mIkeSocket;
+
+    /** Package */
+    @VisibleForTesting IkeSaRecord mCurrentIkeSaRecord;
+    /** Package */
+    @VisibleForTesting IkeSaRecord mLocalInitNewIkeSaRecord;
+    /** Package */
+    @VisibleForTesting IkeSaRecord mRemoteInitNewIkeSaRecord;
+
+    /** Package */
+    @VisibleForTesting IkeSaRecord mIkeSaRecordSurviving;
+    /** Package */
+    @VisibleForTesting IkeSaRecord mIkeSaRecordAwaitingLocalDel;
+    /** Package */
+    @VisibleForTesting IkeSaRecord mIkeSaRecordAwaitingRemoteDel;
+
+    // States
+    private final State mInitial = new Initial();
+    private final State mClosed = new Closed();
+    private final State mIdle = new Idle();
+    private final State mReceiving = new Receiving();
+    private final State mCreateIkeLocalIkeInit = new CreateIkeLocalIkeInit();
+    private final State mCreateIkeLocalIkeAuth = new CreateIkeLocalIkeAuth();
+    private final State mRekeyIkeLocalCreate = new RekeyIkeLocalCreate();
+    private final State mSimulRekeyIkeLocalCreate = new SimulRekeyIkeLocalCreate();
+    private final State mSimulRekeyIkeLocalDeleteRemoteDelete =
+            new SimulRekeyIkeLocalDeleteRemoteDelete();
+    private final State mSimulRekeyIkeLocalDelete = new SimulRekeyIkeLocalDelete();
+    private final State mSimulRekeyIkeRemoteDelete = new SimulRekeyIkeRemoteDelete();
+    private final State mRekeyIkeLocalDelete = new RekeyIkeLocalDelete();
+    private final State mRekeyIkeRemoteDelete = new RekeyIkeRemoteDelete();
+    // TODO: Add InfoLocal and DeleteIkeLocal.
+
+    /** Package private constructor */
+    IkeSessionStateMachine(
+            String name,
+            Looper looper,
+            IkeSessionOptions ikeOptions,
+            ChildSessionOptions firstChildOptions) {
+        super(name, looper);
+        mIkeSessionOptions = ikeOptions;
+        mFirstChildSessionOptions = firstChildOptions;
+        // There are at most three IkeSaRecords co-existing during simultaneous rekeying.
+        mSpiToSaRecordMap = new LongSparseArray<>(3);
+        mSpiToChildSessionMap = new SparseArray<>();
+
+        addState(mInitial);
+        addState(mClosed);
+        addState(mCreateIkeLocalIkeInit);
+        addState(mCreateIkeLocalIkeAuth);
+        addState(mIdle);
+        addState(mReceiving);
+        addState(mRekeyIkeLocalCreate);
+        addState(mSimulRekeyIkeLocalCreate, mRekeyIkeLocalCreate);
+        addState(mSimulRekeyIkeLocalDeleteRemoteDelete);
+        addState(mSimulRekeyIkeLocalDelete, mSimulRekeyIkeLocalDeleteRemoteDelete);
+        addState(mSimulRekeyIkeRemoteDelete, mSimulRekeyIkeLocalDeleteRemoteDelete);
+        addState(mRekeyIkeLocalDelete);
+        addState(mRekeyIkeRemoteDelete);
+
+        setInitialState(mInitial);
+    }
+
+    // Generate IKE SPI. Throw an exception if it failed and handle this exception in current State.
+    private static Long getIkeSpiOrThrow() {
+        for (int i = 0; i < MAX_ASSIGN_IKE_SPI_ATTEMPTS; i++) {
+            long spi = IKE_SPI_RANDOM.nextLong();
+            if (ASSIGNED_LOCAL_IKE_SPI_SET.add(spi)) return spi;
+        }
+        throw new IllegalStateException("Failed to generate IKE SPI.");
+    }
+
+    private IkeMessage buildIkeInitReq() {
+        // TODO: Handle IKE SPI assigning error in CreateIkeLocalIkeInit State.
+
+        List<IkePayload> payloadList = new LinkedList<>();
+
+        // Generate IKE SPI
+        long initSpi = getIkeSpiOrThrow();
+        long respSpi = 0;
+
+        // It is validated in IkeSessionOptions.Builder to ensure IkeSessionOptions has at least one
+        // SaProposal and all SaProposals are valid for IKE SA negotiation.
+        SaProposal[] saProposals = mIkeSessionOptions.getSaProposals();
+
+        // Build SA Payload
+        IkeSaPayload saPayload = new IkeSaPayload(saProposals);
+        payloadList.add(saPayload);
+
+        // Build KE Payload using the first DH group number in the first SaProposal.
+        DhGroupTransform dhGroupTransform = saProposals[0].getDhGroupTransforms()[0];
+        IkeKePayload kePayload = new IkeKePayload(dhGroupTransform.id);
+        payloadList.add(kePayload);
+
+        // Build Nonce Payload
+        IkeNoncePayload noncePayload = new IkeNoncePayload();
+        payloadList.add(noncePayload);
+
+        // TODO: Add Notification Payloads according to user configurations.
+
+        // Build IKE header
+        IkeHeader ikeHeader =
+                new IkeHeader(
+                        initSpi,
+                        respSpi,
+                        IkePayload.PAYLOAD_TYPE_SA,
+                        IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT,
+                        false /*isResponseMsg*/,
+                        true /*fromIkeInitiator*/,
+                        0 /*messageId*/);
+
+        return new IkeMessage(ikeHeader, payloadList);
+    }
+
+    private IkeMessage buildIkeAuthReq() {
+        // TODO: Build IKE_AUTH request according to mIkeSessionOptions and
+        // firstChildSessionOptions.
+        return null;
+    }
+
+    private IkeMessage buildIkeDeleteReq(IkeSaRecord ikeSaRecord) {
+        // TODO: Implement it.
+        return null;
+    }
+
+    private IkeMessage buildIkeDeleteResp(IkeSaRecord ikeSaRecord) {
+        // TODO: Implement it.
+        return null;
+    }
+
+    private IkeMessage buildIkeRekeyReq() {
+        // TODO: Implement it.
+        return null;
+    }
+
+    private IkeMessage buildIkeRekeyResp(IkeMessage reqMsg) {
+        // TODO: Implement it.
+        return null;
+    }
+
+    private void validateIkeInitResp(IkeMessage reqMsg, IkeMessage respMsg) throws IkeException {
+        // TODO: Validate ikeMessage against IKE_INIT request and set confiugration negotiation
+        // results
+        // in mIkeSessionOptions(e.g.NAT detecting result).
+    }
+
+    private void validateIkeAuthResp(IkeMessage reqMsg, IkeMessage respMsg) throws IkeException {
+        // TODO: Validate ikeMessage against IKE_AUTH request and mIkeSessionOptions.
+    }
+
+    private void validateIkeDeleteReq(IkeMessage ikeMessage) throws IkeException {
+        // TODO: Validate ikeMessage.
+    }
+
+    private void validateIkeDeleteResp(IkeMessage ikeMessage) throws IkeException {
+        // TODO: Validate ikeMessage.
+    }
+
+    private void validateIkeRekeyReq(IkeMessage ikeMessage) throws IkeException {
+        // TODO: Validate it againsr mIkeSessionOptions.
+    }
+
+    private void validateIkeRekeyResp(IkeMessage reqMsg, IkeMessage respMsg) throws IkeException {
+        // TODO: Validate ikeMessage against Rekey request.
+    }
+
+    // TODO: Add methods for building and validating general Informational packet.
+
+    private void addIkeSaRecord(IkeSaRecord record) {
+        mSpiToSaRecordMap.put(record.getRemoteSpi(), record);
+    }
+
+    private void removeIkeSaRecord(IkeSaRecord record) {
+        mSpiToSaRecordMap.remove(record.getRemoteSpi());
+    }
+
+    /**
+     * Receive IKE packet from remote server.
+     *
+     * <p>This method is called synchronously from IkeSocket. It proxies the synchronous call as an
+     * asynchronous job to the IkeSessionStateMachine handler.
+     *
+     * @param ikeHeader the decoded IKE header.
+     * @param ikePacketBytes the byte array of the entire received IKE packet.
+     */
+    public void receiveIkePacket(IkeHeader ikeHeader, byte[] ikePacketBytes) {
+        sendMessage(CMD_RECEIVE_IKE_PACKET, new ReceivedIkePacket(ikeHeader, ikePacketBytes));
+    }
+
+    /**
+     * ReceivedIkePacket is a package private data container consists of decoded IkeHeader and
+     * encoded IKE packet in a byte array.
+     */
+    static class ReceivedIkePacket {
+        /** Decoded IKE header */
+        public final IkeHeader ikeHeader;
+        /** Entire encoded IKE message including IKE header */
+        public final byte[] ikePacketBytes;
+
+        ReceivedIkePacket(IkeHeader ikeHeader, byte[] ikePacketBytes) {
+            this.ikeHeader = ikeHeader;
+            this.ikePacketBytes = ikePacketBytes;
+        }
+    }
+
+    /**
+     * Interface for ChildSessionStateMachine to notify IkeSessionStateMachine.
+     *
+     * <p>Package private so as to be injectable for testing.
+     */
+    interface IChildSessionCallback {
+        /** Notify that new Child SA is created. */
+        void onCreateChildSa(int remoteSpi, ChildSessionStateMachine childSession);
+        /** Notify that the Child SA is deleted. */
+        void onDeleteChildSa(int remoteSpi);
+        // TODO: Add methods for handling errors and sending out locally built payloads.
+    }
+
+    /**
+     * Callback for ChildSessionStateMachine to notify IkeSessionStateMachine.
+     *
+     * <p>Package private for being passed to only ChildSessionStateMachine.
+     */
+    class ChildSessionCallback implements IChildSessionCallback {
+        public void onCreateChildSa(int remoteSpi, ChildSessionStateMachine childSession) {
+            mSpiToChildSessionMap.put(remoteSpi, childSession);
+        }
+
+        public void onDeleteChildSa(int remoteSpi) {
+            mSpiToChildSessionMap.remove(remoteSpi);
+        }
+    }
+
+    /** Initial state of IkeSessionStateMachine. */
+    class Initial extends State {
+        @Override
+        public void enter() {
+            try {
+                mIkeSocket = IkeSocket.getIkeSocket(mIkeSessionOptions.getUdpEncapsulationSocket());
+            } catch (ErrnoException e) {
+                // TODO: handle exception and close IkeSession.
+            }
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_LOCAL_REQUEST_CREATE_IKE:
+                    transitionTo(mCreateIkeLocalIkeInit);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+    }
+
+    /**
+     * Closed represents the state when this IkeSessionStateMachine is closed, and no further
+     * actions can be performed on it.
+     */
+    class Closed extends State {
+        // TODO:Implement it.
+    }
+
+    /**
+     * Idle represents a state when there is no ongoing IKE exchange affecting established IKE SA.
+     */
+    class Idle extends State {
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_RECEIVE_IKE_PACKET:
+                    deferMessage(message);
+                    transitionTo(mReceiving);
+                    return HANDLED;
+                case CMD_LOCAL_REQUEST_REKEY_IKE:
+                    transitionTo(mRekeyIkeLocalCreate);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+                    // TODO: Add more cases for supporting local request.
+            }
+        }
+    }
+
+    /** Base state defines common behaviours when receiving an IKE packet. */
+    private abstract class BaseState extends State {
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_RECEIVE_IKE_PACKET:
+                    handleReceivedIkePacket(message);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        protected void handleReceivedIkePacket(Message message) {
+            ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
+            IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
+            byte[] ikePacketBytes = receivedIkePacket.ikePacketBytes;
+            IkeSaRecord ikeSaRecord = getIkeSaRecordForPacket(ikeHeader);
+            try {
+                IkeMessage ikeMessage =
+                        IkeMessage.decode(
+                                mIkeSessionOptions, ikeSaRecord, ikeHeader, ikePacketBytes);
+                int messageType = ikeMessage.getMessageType();
+                // TODO: Handle fatal error notifications.
+                handleIkeMessage(ikeMessage, messageType, message);
+            } catch (IkeException e) {
+
+            } catch (GeneralSecurityException e) {
+                // IKE library failed on intergity checksum validation or on message decryption.
+                // TODO: Handle decrypting exception
+            }
+        }
+
+        // Default handler for decode errors in encrypted request.
+        protected void handleDecodingErrorInEncryptedRequest(
+                IkeException exception, IkeSaRecord ikeSaRecord) {
+            switch (exception.errorCode) {
+                case IkeNotifyPayload.NOTIFY_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD:
+                    // TODO: Send encrypted error notification.
+                    return;
+                case IkeNotifyPayload.NOTIFY_TYPE_INVALID_MAJOR_VERSION:
+                    // TODO: Send unencrypted error notification.
+                    return;
+                case IkeNotifyPayload.NOTIFY_TYPE_INVALID_SYNTAX:
+                    // TODO: Send encrypted error notification and close IKE session if Message ID
+                    // and cryptogtaphic checksum were invalid.
+                    return;
+                default:
+                    // Won't hit this case.
+                    throw new UnsupportedOperationException("Unknown error decoding IKE Message.");
+            }
+        }
+
+        // Default handler for decode errors in encrypted responses.
+        // NOTE: The DeleteIkeLocal state MUST override this state to avoid the possibility of an
+        // infinite loop.
+        protected void handleDecodingErrorInEncryptedResponse(
+                IkeException exception, IkeSaRecord ikeSaRecord) {
+            // All errors in parsing or processing reponse packets should cause the IKE library to
+            // initiate a Delete IKE Exchange.
+
+            // TODO: Initiate Delete IKE Exchange
+        }
+
+        protected IkeSaRecord getIkeSaRecordForPacket(IkeHeader ikeHeader) {
+            if (ikeHeader.fromIkeInitiator) {
+                return mSpiToSaRecordMap.get(ikeHeader.ikeInitiatorSpi);
+            } else {
+                return mSpiToSaRecordMap.get(ikeHeader.ikeResponderSpi);
+            }
+        }
+
+        protected abstract void handleIkeMessage(
+                IkeMessage ikeMessage, int messageType, Message message);
+    }
+
+    /**
+     * Receiving represents a state when idle IkeSessionStateMachine receives an incoming packet.
+     */
+    class Receiving extends BaseState {
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_REKEY_IKE_REQ:
+                    try {
+                        validateIkeRekeyReq(ikeMessage);
+                        // Reply
+                        IkeMessage responseIkeMessage = buildIkeRekeyResp(ikeMessage);
+                        // TODO: Encode and send out responseIkeMessage
+
+                        mRemoteInitNewIkeSaRecord =
+                                IkeSaRecord.makeNewIkeSaRecord(
+                                        mCurrentIkeSaRecord, ikeMessage, responseIkeMessage);
+                        addIkeSaRecord(mRemoteInitNewIkeSaRecord);
+                        transitionTo(mRekeyIkeRemoteDelete);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                    // TODO: Add more cases for supporting local request.
+                default:
+            }
+        }
+    }
+
+    /**
+     * LocalNewExchangeBase represents the common behaviours when IKE library initiates a new
+     * exchange.
+     */
+    private abstract class LocalNewExchangeBase extends BaseState {
+        protected IkeMessage mRequestMsg;
+        protected byte[] mRequestPacket;
+
+        @Override
+        public void enter() {
+            mRequestMsg = buildRequest();
+            mRequestPacket = encodeRequest();
+            mIkeSocket.sendIkePacket(mRequestPacket, mIkeSessionOptions.getServerAddress());
+            // TODO: Send out packet and start retransmission timer.
+        }
+
+        @Override
+        public void exit() {
+            // TODO: Stop retransmission
+            mRequestMsg = null;
+            mRequestPacket = null;
+        }
+
+        protected abstract IkeMessage buildRequest();
+
+        // CreateIkeLocalInit should override encodeRequest() to encode unencrypted packet
+        protected byte[] encodeRequest() {
+            // TODO: encrypt and encode mRequestMsg
+            return new byte[0];
+        }
+    }
+
+    /** CreateIkeLocalIkeInit represents state when IKE library initiates IKE_INIT exchange. */
+    class CreateIkeLocalIkeInit extends LocalNewExchangeBase {
+
+        @Override
+        public void enter() {
+            super.enter();
+            mIkeSocket.registerIke(
+                    mRequestMsg.ikeHeader.ikeInitiatorSpi, IkeSessionStateMachine.this);
+        }
+
+        @Override
+        protected IkeMessage buildRequest() {
+            return buildIkeInitReq();
+        }
+
+        @Override
+        protected byte[] encodeRequest() {
+            return mRequestMsg.encode();
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_RECEIVE_IKE_PACKET:
+                    handleReceivedIkePacket(message);
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        protected void handleReceivedIkePacket(Message message) {
+            ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
+            IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
+            byte[] ikePacketBytes = receivedIkePacket.ikePacketBytes;
+            try {
+                IkeMessage ikeMessage = IkeMessage.decode(ikeHeader, ikePacketBytes);
+                int messageType = ikeMessage.getMessageType();
+                // TODO: Handle fatal error notifications.
+                handleIkeMessage(ikeMessage, messageType, message);
+            } catch (IkeException e) {
+                // TODO:Since IKE_INIT is not protected, log and ignore this message.
+            }
+        }
+
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_IKE_INIT_RESP:
+                    try {
+                        validateIkeInitResp(mRequestMsg, ikeMessage);
+                        mCurrentIkeSaRecord =
+                                IkeSaRecord.makeFirstIkeSaRecord(mRequestMsg, ikeMessage);
+                        addIkeSaRecord(mCurrentIkeSaRecord);
+                        transitionTo(mCreateIkeLocalIkeAuth);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                default:
+                    // TODO: Handle unexpected message type.
+            }
+        }
+
+        @Override
+        public void exit() {
+            super.exit();
+            // TODO: Store IKE_INIT request and response in mIkeSessionOptions for IKE_AUTH
+        }
+    }
+
+    /** CreateIkeLocalIkeAuth represents state when IKE library initiates IKE_AUTH exchange. */
+    class CreateIkeLocalIkeAuth extends LocalNewExchangeBase {
+        @Override
+        protected IkeMessage buildRequest() {
+            return buildIkeAuthReq();
+        }
+
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                    // TODO: Handle EAP Authentication.
+                case IkeMessage.MESSAGE_TYPE_IKE_AUTH_RESP:
+                    try {
+                        validateIkeAuthResp(mRequestMsg, ikeMessage);
+
+                        ChildSessionStateMachine firstChild =
+                                ChildSessionStateMachineFactory.makeChildSessionStateMachine(
+                                        "ChildSessionStateMachine",
+                                        getHandler().getLooper(),
+                                        mFirstChildSessionOptions);
+                        // TODO: Replace null input params to payload lists in IKE_AUTH request and
+                        // IKE_AUTH response for negotiating Child SA.
+                        firstChild.handleFirstChildExchange(null, null, new ChildSessionCallback());
+
+                        transitionTo(mIdle);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                default:
+                    // TODO: Add more cases for other packet types (e.g. for receiving and sending
+                    // EAP).
+            }
+        }
+    }
+
+    /** RekeyIkeLocalCreate represents state when IKE library initiates Rekey IKE exchange. */
+    class RekeyIkeLocalCreate extends LocalNewExchangeBase {
+        @Override
+        public IkeMessage buildRequest() {
+            return buildIkeRekeyReq();
+        }
+
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_REKEY_IKE_RESP:
+                    try {
+                        handleRekeyResp(ikeMessage);
+                        transitionTo(mRekeyIkeLocalDelete);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                case IkeMessage.MESSAGE_TYPE_REKEY_IKE_REQ:
+                    try {
+                        validateIkeRekeyReq(ikeMessage);
+                        // Reply
+                        IkeMessage responseIkeMessage = buildIkeRekeyResp(ikeMessage);
+                        mRemoteInitNewIkeSaRecord =
+                                IkeSaRecord.makeNewIkeSaRecord(
+                                        mCurrentIkeSaRecord, ikeMessage, responseIkeMessage);
+                        addIkeSaRecord(mRemoteInitNewIkeSaRecord);
+                        // TODO: Encode and send responseIkeMessage.
+
+                        transitionTo(mSimulRekeyIkeLocalCreate);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                default:
+                    // TODO: Add more cases for other packet types.
+            }
+        }
+
+        // Is also called by SimulRekeyIkeLocalCreate to handle incoming rekey response.
+        protected void handleRekeyResp(IkeMessage ikeMessage) throws IkeException {
+            validateIkeRekeyResp(mRequestMsg, ikeMessage);
+            mLocalInitNewIkeSaRecord =
+                    IkeSaRecord.makeNewIkeSaRecord(mCurrentIkeSaRecord, mRequestMsg, ikeMessage);
+            addIkeSaRecord(mLocalInitNewIkeSaRecord);
+            // TODO: Stop retransmission
+        }
+    }
+
+    /**
+     * SimulRekeyIkeLocalCreate represents the state where IKE library has replied to rekey request
+     * sent from the remote and is waiting for a rekey response for a locally initiated rekey
+     * request.
+     *
+     * <p>SimulRekeyIkeLocalCreate extends RekeyIkeLocalCreate so that it can call super class to
+     * validate incoming rekey response against locally initiated rekey request.
+     */
+    class SimulRekeyIkeLocalCreate extends RekeyIkeLocalCreate {
+        @Override
+        public void enter() {
+            // Do not send request.
+        }
+
+        @Override
+        public IkeMessage buildRequest() {
+            throw new UnsupportedOperationException(
+                    "Do not support sending request in " + getCurrentState().getName());
+        }
+
+        @Override
+        public void exit() {
+            // Do nothing.
+        }
+
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_RECEIVE_IKE_PACKET:
+                    ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
+                    IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
+
+                    if (mRemoteInitNewIkeSaRecord == getIkeSaRecordForPacket(ikeHeader)) {
+                        deferMessage(message);
+                    } else {
+                        handleReceivedIkePacket(message);
+                    }
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+            }
+        }
+
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_DELETE_IKE_REQ:
+                    deferMessage(message);
+                    return;
+                case IkeMessage.MESSAGE_TYPE_REKEY_IKE_RESP:
+                    try {
+                        super.handleRekeyResp(ikeMessage);
+                        transitionTo(mSimulRekeyIkeLocalDeleteRemoteDelete);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                default:
+                    // TODO: Add more cases for other packet types.
+            }
+        }
+    }
+
+    /** RekeyIkeDeleteBase represents common behaviours of deleting stage during rekeying IKE SA. */
+    private abstract class RekeyIkeDeleteBase extends BaseState {
+        @Override
+        public boolean processMessage(Message message) {
+            switch (message.what) {
+                case CMD_RECEIVE_IKE_PACKET:
+                    ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
+                    IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
+
+                    // Request received on the new/surviving SA; treat it as acknowledgement that
+                    // remote has successfully rekeyed.
+                    if (mIkeSaRecordSurviving == getIkeSaRecordForPacket(ikeHeader)) {
+                        deferMessage(message);
+                        // TODO: Locally close old (and losing) IKE SAs.
+                        finishRekey();
+                    } else {
+                        handleReceivedIkePacket(message);
+                    }
+                    return HANDLED;
+                default:
+                    return NOT_HANDLED;
+                    // TODO: Add more cases for other packet types.
+            }
+        }
+
+        protected void finishRekey() {
+            mCurrentIkeSaRecord = mIkeSaRecordSurviving;
+            mLocalInitNewIkeSaRecord = null;
+            mRemoteInitNewIkeSaRecord = null;
+
+            mIkeSaRecordSurviving = null;
+            mIkeSaRecordAwaitingLocalDel = null;
+            mIkeSaRecordAwaitingRemoteDel = null;
+        }
+    }
+
+    /**
+     * SimulRekeyIkeLocalDeleteRemoteDelete represents the deleting stage during simultaneous
+     * rekeying when IKE library is waiting for both a Delete request and a Delete response.
+     */
+    class SimulRekeyIkeLocalDeleteRemoteDelete extends RekeyIkeDeleteBase {
+        @Override
+        public void enter() {
+            // Detemine surviving IKE SA. According to RFC 7296: "The new IKE SA containing the
+            // lowest nonce SHOULD be deleted by the node that created it, and the other surviving
+            // new IKE SA MUST inherit all the Child SAs."
+            if (mLocalInitNewIkeSaRecord.compareTo(mRemoteInitNewIkeSaRecord) > 0) {
+                mIkeSaRecordSurviving = mLocalInitNewIkeSaRecord;
+                mIkeSaRecordAwaitingLocalDel = mCurrentIkeSaRecord;
+                mIkeSaRecordAwaitingRemoteDel = mRemoteInitNewIkeSaRecord;
+            } else {
+                mIkeSaRecordSurviving = mRemoteInitNewIkeSaRecord;
+                mIkeSaRecordAwaitingLocalDel = mLocalInitNewIkeSaRecord;
+                mIkeSaRecordAwaitingRemoteDel = mCurrentIkeSaRecord;
+            }
+            IkeMessage ikeMessage = buildIkeDeleteReq(mIkeSaRecordAwaitingLocalDel);
+            // TODO: Encode and send out delete request and start retransmission timer.
+            // TODO: Set timer awaiting for delete request.
+        }
+
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            IkeSaRecord ikeSaRecordForPacket = getIkeSaRecordForPacket(ikeMessage.ikeHeader);
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_DELETE_IKE_REQ:
+                    if (ikeSaRecordForPacket == mIkeSaRecordAwaitingRemoteDel) {
+                        try {
+                            validateIkeDeleteReq(ikeMessage);
+                            IkeMessage respMsg = buildIkeDeleteResp(mIkeSaRecordAwaitingRemoteDel);
+                            removeIkeSaRecord(mIkeSaRecordAwaitingRemoteDel);
+                            // TODO: Encode and send response and close
+                            // mIkeSaRecordAwaitingRemoteDel.
+                            // TODO: Stop timer awating delete request.
+                            transitionTo(mSimulRekeyIkeLocalDelete);
+                        } catch (IkeException e) {
+                            // TODO: Handle processing errors.
+                        }
+                    } else {
+                        // TODO: The other side deletes wrong IKE SA and we should close whole IKE
+                        // session.
+                    }
+                    return;
+                case IkeMessage.MESSAGE_TYPE_DELETE_IKE_RESP:
+                    if (ikeSaRecordForPacket == mIkeSaRecordAwaitingLocalDel) {
+                        try {
+                            validateIkeDeleteResp(ikeMessage);
+                            transitionTo(mSimulRekeyIkeRemoteDelete);
+                            removeIkeSaRecord(mIkeSaRecordAwaitingLocalDel);
+                            // TODO: Close mIkeSaRecordAwaitingLocalDel
+                            // TODO: Stop retransmission timer
+                        } catch (IkeException e) {
+                            // TODO: Handle processing errors.
+                        }
+                    } else {
+                        // TODO: Close whole IKE session
+                    }
+                    return;
+                default:
+                    // TODO: Add more cases for other packet types.
+            }
+        }
+
+        @Override
+        public void exit() {
+            finishRekey();
+            // TODO: Stop retransmission timer and awaiting delete request timer.
+        }
+    }
+
+    /**
+     * SimulRekeyIkeLocalDelete represents the state when IKE library is waiting for a Delete
+     * response during simultaneous rekeying.
+     */
+    class SimulRekeyIkeLocalDelete extends RekeyIkeDeleteBase {
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_DELETE_IKE_RESP:
+                    try {
+                        validateIkeDeleteResp(ikeMessage);
+                        removeIkeSaRecord(mIkeSaRecordAwaitingLocalDel);
+                        // TODO: Close mIkeSaRecordAwaitingLocalDel.
+                        transitionTo(mIdle);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                default:
+                    // TODO: Add more cases for other packet types.
+            }
+        }
+    }
+
+    /**
+     * SimulRekeyIkeRemoteDelete represents the state that waiting for a Delete request during
+     * simultaneous rekeying.
+     */
+    class SimulRekeyIkeRemoteDelete extends RekeyIkeDeleteBase {
+        // TODO: Implement methods for processing Delete response
+        @Override
+        protected void handleIkeMessage(IkeMessage ikeMessage, int messageType, Message message) {
+            switch (messageType) {
+                case IkeMessage.MESSAGE_TYPE_DELETE_IKE_REQ:
+                    try {
+                        validateIkeDeleteReq(ikeMessage);
+                        IkeMessage respMsg = buildIkeDeleteResp(mIkeSaRecordAwaitingRemoteDel);
+                        // TODO: Encode and send response and close mIkeSaRecordAwaitingRemoteDel
+                        removeIkeSaRecord(mIkeSaRecordAwaitingRemoteDel);
+                        transitionTo(mIdle);
+                    } catch (IkeException e) {
+                        // TODO: Handle processing errors.
+                    }
+                    return;
+                default:
+                    // TODO: Add more cases for other packet types.
+            }
+        }
+    }
+
+    /**
+     * RekeyIkeLocalDelete represents the deleting stage when IKE library is initiating a Rekey
+     * procedure.
+     *
+     * <p>RekeyIkeLocalDelete and SimulRekeyIkeLocalDelete have same behaviours in processMessage().
+     * While RekeyIkeLocalDelete overrides enter() and exit() methods for initiating and finishing
+     * the deleting stage for IKE rekeying.
+     */
+    class RekeyIkeLocalDelete extends SimulRekeyIkeLocalDelete {
+        @Override
+        public void enter() {
+            mIkeSaRecordSurviving = mLocalInitNewIkeSaRecord;
+            mIkeSaRecordAwaitingLocalDel = mCurrentIkeSaRecord;
+            IkeMessage ikeMessage = buildIkeDeleteReq(mIkeSaRecordAwaitingLocalDel);
+            // TODO: Encode ikeMessage, send out packet and start retransmission timer.
+        }
+
+        @Override
+        public void exit() {
+            finishRekey();
+            // TODO: Stop retransmission.
+        }
+    }
+
+    /**
+     * RekeyIkeRemoteDelete represents the deleting stage when responding to a Rekey procedure.
+     *
+     * <p>RekeyIkeRemoteDelete and SimulRekeyIkeRemoteDelete have same behaviours in
+     * processMessage(). While RekeyIkeLocalDelete overrides enter() and exit() methods for waiting
+     * incoming delete request and for finishing the deleting stage for IKE rekeying.
+     */
+    class RekeyIkeRemoteDelete extends SimulRekeyIkeRemoteDelete {
+        @Override
+        public void enter() {
+            mIkeSaRecordSurviving = mRemoteInitNewIkeSaRecord;
+            mIkeSaRecordAwaitingRemoteDel = mCurrentIkeSaRecord;
+            // TODO: Set timer awaiting delete request.
+        }
+
+        @Override
+        public void exit() {
+            finishRekey();
+            // TODO: Stop timer awaiting delete request.
+        }
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSocket.java b/src/java/com/android/ike/ikev2/IkeSocket.java
similarity index 82%
rename from src/java/com/android/internal/net/ipsec/ike/IkeSocket.java
rename to src/java/com/android/ike/ikev2/IkeSocket.java
index 2f853c7..e235ab8 100644
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSocket.java
+++ b/src/java/com/android/ike/ikev2/IkeSocket.java
@@ -14,23 +14,23 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike;
+package com.android.ike.ikev2;
 
-import static android.net.ipsec.ike.IkeManager.getIkeLog;
 import static android.system.OsConstants.F_SETFL;
 import static android.system.OsConstants.SOCK_DGRAM;
 import static android.system.OsConstants.SOCK_NONBLOCK;
 
 import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
+import android.net.util.PacketReader;
 import android.os.Handler;
 import android.system.ErrnoException;
 import android.system.Os;
+import android.util.Log;
 import android.util.LongSparseArray;
 
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.message.IkeHeader;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.message.IkeHeader;
-import com.android.internal.net.ipsec.ike.utils.PacketReader;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -38,9 +38,7 @@
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.Map;
-import java.util.Set;
 
 /**
  * IkeSocket sends and receives IKE packets via the user provided {@link UdpEncapsulationSocket}.
@@ -82,16 +80,18 @@
 
     // Package private map from locally generated IKE SPI to IkeSessionStateMachine instances.
     @VisibleForTesting
-    final LongSparseArray<IkeSessionStateMachine> mSpiToIkeSession = new LongSparseArray<>();
-
-    // Package private set to store all running IKE Sessions that are using this IkeSocket instance.
-    @VisibleForTesting final Set<IkeSessionStateMachine> mAliveIkeSessions = new HashSet<>();
-
+    final LongSparseArray<IkeSessionStateMachine> mSpiToIkeSession =
+            new LongSparseArray<>();
     // UdpEncapsulationSocket for sending and receving IKE packet.
     private final UdpEncapsulationSocket mUdpEncapSocket;
 
+    /** Package private */
+    @VisibleForTesting
+    int mRefCount;
+
     private IkeSocket(UdpEncapsulationSocket udpEncapSocket, Handler handler) {
         super(handler);
+        mRefCount = 1;
         mUdpEncapSocket = udpEncapSocket;
     }
 
@@ -102,31 +102,27 @@
      * udpEncapSocket. Otherwise, create and return a new IkeSocket instance.
      *
      * @param udpEncapSocket user provided UdpEncapsulationSocket
-     * @param ikeSession the IkeSessionStateMachine that is requesting an IkeSocket.
-     * @return an IkeSocket instance
+     * @return an IkSocket instance
      */
-    public static IkeSocket getIkeSocket(
-            UdpEncapsulationSocket udpEncapSocket, IkeSessionStateMachine ikeSession)
+    public static IkeSocket getIkeSocket(UdpEncapsulationSocket udpEncapSocket)
             throws ErrnoException {
         FileDescriptor fd = udpEncapSocket.getFileDescriptor();
         // All created IkeSocket has modified its FileDescriptor to non-blocking type for handling
         // read events in a non-blocking way.
         Os.fcntlInt(fd, F_SETFL, SOCK_DGRAM | SOCK_NONBLOCK);
 
-        IkeSocket ikeSocket = null;
         if (sFdToIkeSocketMap.containsKey(udpEncapSocket)) {
-            ikeSocket = sFdToIkeSocketMap.get(udpEncapSocket);
-
+            IkeSocket ikeSocket = sFdToIkeSocketMap.get(udpEncapSocket);
+            ikeSocket.mRefCount++;
+            return ikeSocket;
         } else {
-            ikeSocket = new IkeSocket(udpEncapSocket, new Handler());
+            IkeSocket ikeSocket = new IkeSocket(udpEncapSocket, new Handler());
             // Create and register FileDescriptor for receiving IKE packet on current thread.
             ikeSocket.start();
 
             sFdToIkeSocketMap.put(udpEncapSocket, ikeSocket);
+            return ikeSocket;
         }
-
-        ikeSocket.mAliveIkeSessions.add(ikeSession);
-        return ikeSocket;
     }
 
     /**
@@ -155,6 +151,10 @@
     static final class PacketReceiver implements IPacketReceiver {
         public void handlePacket(
                 byte[] recvbuf, LongSparseArray<IkeSessionStateMachine> spiToIkeSession) {
+            // TODO: b/129708574 Consider only logging the error some % of the time it happens, or
+            // only logging the error the first time it happens and then keep a count to prevent
+            // logspam.
+
             ByteBuffer byteBuffer = ByteBuffer.wrap(recvbuf);
 
             // Check the existence of the Non-ESP Marker. A received packet can be either an IKE
@@ -164,7 +164,7 @@
             byteBuffer.get(espMarker);
             if (!Arrays.equals(NON_ESP_MARKER, espMarker)) {
                 // Drop the received ESP packet.
-                getIkeLog().e(TAG, "Receive an ESP packet.");
+                Log.e(TAG, "Receive an ESP packet.");
                 return;
             }
 
@@ -173,11 +173,6 @@
                 // IKE SPI.
                 byte[] ikePacketBytes = new byte[byteBuffer.remaining()];
                 byteBuffer.get(ikePacketBytes);
-
-                // TODO: Retrieve and log the source address
-                getIkeLog().d(TAG, "Receive packet of " + ikePacketBytes.length + " bytes)");
-                getIkeLog().d(TAG, getIkeLog().pii(ikePacketBytes));
-
                 IkeHeader ikeHeader = new IkeHeader(ikePacketBytes);
 
                 long localGeneratedSpi =
@@ -187,14 +182,14 @@
 
                 IkeSessionStateMachine ikeStateMachine = spiToIkeSession.get(localGeneratedSpi);
                 if (ikeStateMachine == null) {
-                    getIkeLog().w(TAG, "Unrecognized IKE SPI.");
+                    Log.e(TAG, "Unrecognized IKE SPI.");
                     // TODO: Handle invalid IKE SPI error
                 } else {
                     ikeStateMachine.receiveIkePacket(ikeHeader, ikePacketBytes);
                 }
-            } catch (IkeProtocolException e) {
+            } catch (IkeException e) {
                 // Handle invalid IKE header
-                getIkeLog().i(TAG, "Can't parse malformed IKE packet header.");
+                Log.e(TAG, "Can't parse malformed IKE packet header.");
             }
         }
     }
@@ -221,14 +216,6 @@
      * @param serverAddress IP address of remote server
      */
     public void sendIkePacket(byte[] ikePacket, InetAddress serverAddress) {
-        getIkeLog()
-                .d(
-                        TAG,
-                        "Send packet to "
-                                + serverAddress.getHostAddress()
-                                + "( "
-                                + ikePacket.length
-                                + " bytes)");
         try {
             ByteBuffer buffer = ByteBuffer.allocate(NON_ESP_MARKER_LEN + ikePacket.length);
 
@@ -265,9 +252,9 @@
     }
 
     /** Release reference of current IkeSocket when the IKE session is closed. */
-    public void releaseReference(IkeSessionStateMachine ikeSession) {
-        mAliveIkeSessions.remove(ikeSession);
-        if (mAliveIkeSessions.isEmpty()) close();
+    public void releaseReference() {
+        mRefCount--;
+        if (mRefCount == 0) close();
     }
 
     /** Implement {@link AutoCloseable#close()} */
diff --git a/src/java/com/android/ike/ikev2/IkeTrafficSelector.java b/src/java/com/android/ike/ikev2/IkeTrafficSelector.java
new file mode 100644
index 0000000..baebe64
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/IkeTrafficSelector.java
@@ -0,0 +1,231 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import android.annotation.IntDef;
+import android.util.ArraySet;
+
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+
+/**
+ * IkeTrafficSelector represents a Traffic Selector of a Child SA.
+ *
+ * <p>IkeTrafficSelector can be constructed by users for initiating Create Child exchange or be
+ * constructed from a decoded inbound Traffic Selector Payload.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.13">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class IkeTrafficSelector {
+
+    // IpProtocolId consists of standard IP Protocol IDs.
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({IP_PROTOCOL_ID_UNSPEC, IP_PROTOCOL_ID_ICMP, IP_PROTOCOL_ID_TCP, IP_PROTOCOL_ID_UCP})
+    public @interface IpProtocolId {}
+
+    // Zero value is re-defined by IKE to indicate that all IP protocols are acceptable.
+    @VisibleForTesting static final int IP_PROTOCOL_ID_UNSPEC = 0;
+    @VisibleForTesting static final int IP_PROTOCOL_ID_ICMP = 1;
+    @VisibleForTesting static final int IP_PROTOCOL_ID_TCP = 6;
+    @VisibleForTesting static final int IP_PROTOCOL_ID_UCP = 17;
+
+    private static final ArraySet<Integer> IP_PROTOCOL_ID_SET = new ArraySet<>();
+
+    static {
+        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_UNSPEC);
+        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_ICMP);
+        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_TCP);
+        IP_PROTOCOL_ID_SET.add(IP_PROTOCOL_ID_UCP);
+    }
+
+    /**
+     * TrafficSelectorType consists of IKE standard Traffic Selector Types.
+     *
+     * @see <a
+     *     href="https://www.iana.org/assignments/ikev2-parameters/ikev2-parameters.xhtml">Internet
+     *     Key Exchange Version 2 (IKEv2) Parameters</a>
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE})
+    public @interface TrafficSelectorType {}
+
+    public static final int TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE = 7;
+    public static final int TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE = 8;
+
+    // TODO: Consider defining these constants in a central place in Connectivity.
+    private static final int IPV4_ADDR_LEN = 4;
+    private static final int IPV6_ADDR_LEN = 16;
+
+    @VisibleForTesting static final int TRAFFIC_SELECTOR_IPV4_LEN = 16;
+    @VisibleForTesting static final int TRAFFIC_SELECTOR_IPV6_LEN = 40;
+
+    public final int tsType;
+    public final int ipProtocolId;
+    public final int selectorLength;
+    public final int startPort;
+    public final int endPort;
+    public final InetAddress startingAddress;
+    public final InetAddress endingAddress;
+
+    private IkeTrafficSelector(
+            int tsType,
+            int ipProtocolId,
+            int selectorLength,
+            int startPort,
+            int endPort,
+            InetAddress startingAddress,
+            InetAddress endingAddress) {
+        this.tsType = tsType;
+        this.ipProtocolId = ipProtocolId;
+        this.selectorLength = selectorLength;
+        this.startPort = startPort;
+        this.endPort = endPort;
+        this.startingAddress = startingAddress;
+        this.endingAddress = endingAddress;
+    }
+
+    // TODO: Add a constructor for users to construct IkeTrafficSelector.
+
+    /**
+     * Decode IkeTrafficSelectors from inbound Traffic Selector Payload.
+     *
+     * <p>This method is only called by IkeTsPayload when decoding inbound IKE message.
+     *
+     * @param numTs number or Traffic Selectors
+     * @param tsBytes encoded byte array of Traffic Selectors
+     * @return an array of decoded IkeTrafficSelectors
+     * @throws InvalidSyntaxException if received bytes are malformed.
+     */
+    public static IkeTrafficSelector[] decodeIkeTrafficSelectors(int numTs, byte[] tsBytes)
+            throws InvalidSyntaxException {
+        IkeTrafficSelector[] tsArray = new IkeTrafficSelector[numTs];
+        ByteBuffer inputBuffer = ByteBuffer.wrap(tsBytes);
+
+        try {
+            for (int i = 0; i < numTs; i++) {
+                int tsType = Byte.toUnsignedInt(inputBuffer.get());
+                switch (tsType) {
+                    case TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE:
+                        tsArray[i] = decodeIpv4TrafficSelector(inputBuffer);
+                        break;
+                    case TRAFFIC_SELECTOR_TYPE_IPV6_ADDR_RANGE:
+                        // TODO: Support it.
+                        throw new UnsupportedOperationException("Cannot decode this type.");
+                    default:
+                        throw new InvalidSyntaxException(
+                                "Invalid Traffic Selector type: " + tsType);
+                }
+            }
+        } catch (BufferOverflowException e) {
+            // Throw exception if any Traffic Selector has invalid length.
+            throw new InvalidSyntaxException(e);
+        }
+
+        if (inputBuffer.remaining() != 0) {
+            throw new InvalidSyntaxException(
+                    "Unexpected trailing characters of Traffic Selectors.");
+        }
+
+        return tsArray;
+    }
+
+    // Decode Traffic Selector using IPv4 address range from a ByteBuffer. A BufferOverflowException
+    // will be thrown and caught by method caller if operation reaches the input ByteBuffer's limit.
+    private static IkeTrafficSelector decodeIpv4TrafficSelector(ByteBuffer inputBuffer)
+            throws InvalidSyntaxException {
+        // Decode and validate IP Protocol ID
+        int ipProtocolId = Byte.toUnsignedInt(inputBuffer.get());
+        if (!IP_PROTOCOL_ID_SET.contains(ipProtocolId)) {
+            throw new InvalidSyntaxException("Invalid IP Protocol ID.");
+        }
+
+        // Decode and validate Selector Length
+        int tsLength = Short.toUnsignedInt(inputBuffer.getShort());
+        if (TRAFFIC_SELECTOR_IPV4_LEN != tsLength) {
+            throw new InvalidSyntaxException("Invalid Traffic Selector Length.");
+        }
+
+        // Decode and validate ports
+        int startPort = Short.toUnsignedInt(inputBuffer.getShort());
+        int endPort = Short.toUnsignedInt(inputBuffer.getShort());
+        if (startPort > endPort) {
+            throw new InvalidSyntaxException("Received invalid port range.");
+        }
+
+        // Decode and validate IPv4 addresses
+        byte[] startAddressBytes = new byte[IPV4_ADDR_LEN];
+        byte[] endAddressBytes = new byte[IPV4_ADDR_LEN];
+        inputBuffer.get(startAddressBytes);
+        inputBuffer.get(endAddressBytes);
+        try {
+            Inet4Address startAddress =
+                    (Inet4Address) (Inet4Address.getByAddress(startAddressBytes));
+            Inet4Address endAddress = (Inet4Address) (Inet4Address.getByAddress(endAddressBytes));
+
+            // Validate address range.
+            if (!isInetAddressRangeValid(startAddress, endAddress)) {
+                throw new InvalidSyntaxException("Received invalid IPv4 address range.");
+            }
+
+            return new IkeTrafficSelector(
+                    TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
+                    ipProtocolId,
+                    TRAFFIC_SELECTOR_IPV4_LEN,
+                    startPort,
+                    endPort,
+                    startAddress,
+                    endAddress);
+        } catch (ClassCastException | UnknownHostException | IllegalArgumentException e) {
+            throw new InvalidSyntaxException(e);
+        }
+    }
+
+    // TODO: Add a method for decoding IPv6 traffic selector.
+
+    // Validate address range. Caller must ensure two address are same types.
+    // TODO: Consider moving it to the platform code in the future.
+    private static boolean isInetAddressRangeValid(
+            InetAddress startAddress, InetAddress endAddress) {
+        byte[] startAddrBytes = startAddress.getAddress();
+        byte[] endAddrBytes = endAddress.getAddress();
+
+        if (startAddrBytes.length != endAddrBytes.length) {
+            throw new IllegalArgumentException("Two addresses are different types.");
+        }
+
+        for (int i = 0; i < startAddrBytes.length; i++) {
+            int unsignedByteStart = Byte.toUnsignedInt(startAddrBytes[i]);
+            int unsignedByteEnd = Byte.toUnsignedInt(endAddrBytes[i]);
+
+            if (unsignedByteStart < unsignedByteEnd) {
+                return true;
+            } else if (unsignedByteStart > unsignedByteEnd) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/SaProposal.java b/src/java/com/android/ike/ikev2/SaProposal.java
new file mode 100644
index 0000000..53206cc
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/SaProposal.java
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import android.annotation.IntDef;
+import android.util.ArraySet;
+
+import com.android.ike.ikev2.message.IkePayload;
+import com.android.ike.ikev2.message.IkeSaPayload.DhGroupTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.EncryptionTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.EsnTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.IntegrityTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.PrfTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.Transform;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * SaProposal represents a user configured set contains cryptograhic algorithms and key generating
+ * materials for negotiating an IKE or Child SA.
+ *
+ * <p>User must provide at least a valid SaProposal when they are creating a new IKE SA or Child SA.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class SaProposal {
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        ENCRYPTION_ALGORITHM_3DES,
+        ENCRYPTION_ALGORITHM_AES_CBC,
+        ENCRYPTION_ALGORITHM_AES_GCM_8,
+        ENCRYPTION_ALGORITHM_AES_GCM_12,
+        ENCRYPTION_ALGORITHM_AES_GCM_16
+    })
+    public @interface EncryptionAlgorithm {}
+
+    public static final int ENCRYPTION_ALGORITHM_3DES = 3;
+    public static final int ENCRYPTION_ALGORITHM_AES_CBC = 12;
+    public static final int ENCRYPTION_ALGORITHM_AES_GCM_8 = 18;
+    public static final int ENCRYPTION_ALGORITHM_AES_GCM_12 = 19;
+    public static final int ENCRYPTION_ALGORITHM_AES_GCM_16 = 20;
+
+    private static final Set<Integer> SUPPORTED_ENCRYPTION_ALGORITHM;
+
+    static {
+        SUPPORTED_ENCRYPTION_ALGORITHM = new ArraySet<>();
+        SUPPORTED_ENCRYPTION_ALGORITHM.add(ENCRYPTION_ALGORITHM_3DES);
+        SUPPORTED_ENCRYPTION_ALGORITHM.add(ENCRYPTION_ALGORITHM_AES_CBC);
+        SUPPORTED_ENCRYPTION_ALGORITHM.add(ENCRYPTION_ALGORITHM_AES_GCM_8);
+        SUPPORTED_ENCRYPTION_ALGORITHM.add(ENCRYPTION_ALGORITHM_AES_GCM_12);
+        SUPPORTED_ENCRYPTION_ALGORITHM.add(ENCRYPTION_ALGORITHM_AES_GCM_16);
+    }
+
+    public static final int KEY_LEN_AES_128 = 128;
+    public static final int KEY_LEN_AES_192 = 192;
+    public static final int KEY_LEN_AES_256 = 256;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({PSEUDORANDOM_FUNCTION_HMAC_SHA1, PSEUDORANDOM_FUNCTION_AES128_XCBC})
+    public @interface PseudorandomFunction {}
+
+    public static final int PSEUDORANDOM_FUNCTION_HMAC_SHA1 = 2;
+    public static final int PSEUDORANDOM_FUNCTION_AES128_XCBC = 4;
+
+    private static final Set<Integer> SUPPORTED_PSEUDORANDOM_FUNCTION;
+
+    static {
+        SUPPORTED_PSEUDORANDOM_FUNCTION = new ArraySet<>();
+        SUPPORTED_PSEUDORANDOM_FUNCTION.add(PSEUDORANDOM_FUNCTION_HMAC_SHA1);
+        SUPPORTED_PSEUDORANDOM_FUNCTION.add(PSEUDORANDOM_FUNCTION_AES128_XCBC);
+    }
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        INTEGRITY_ALGORITHM_NONE,
+        INTEGRITY_ALGORITHM_HMAC_SHA1_96,
+        INTEGRITY_ALGORITHM_AES_XCBC_96,
+        INTEGRITY_ALGORITHM_HMAC_SHA2_256_128,
+        INTEGRITY_ALGORITHM_HMAC_SHA2_384_192,
+        INTEGRITY_ALGORITHM_HMAC_SHA2_512_256
+    })
+    public @interface IntegrityAlgorithm {}
+
+    public static final int INTEGRITY_ALGORITHM_NONE = 0;
+    public static final int INTEGRITY_ALGORITHM_HMAC_SHA1_96 = 2;
+    public static final int INTEGRITY_ALGORITHM_AES_XCBC_96 = 5;
+    public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_256_128 = 12;
+    public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_384_192 = 13;
+    public static final int INTEGRITY_ALGORITHM_HMAC_SHA2_512_256 = 14;
+
+    private static final Set<Integer> SUPPORTED_INTEGRITY_ALGORITHM;
+
+    static {
+        SUPPORTED_INTEGRITY_ALGORITHM = new ArraySet<>();
+        SUPPORTED_INTEGRITY_ALGORITHM.add(INTEGRITY_ALGORITHM_NONE);
+        SUPPORTED_INTEGRITY_ALGORITHM.add(INTEGRITY_ALGORITHM_HMAC_SHA1_96);
+        SUPPORTED_INTEGRITY_ALGORITHM.add(INTEGRITY_ALGORITHM_AES_XCBC_96);
+        SUPPORTED_INTEGRITY_ALGORITHM.add(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128);
+        SUPPORTED_INTEGRITY_ALGORITHM.add(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192);
+        SUPPORTED_INTEGRITY_ALGORITHM.add(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256);
+    }
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({DH_GROUP_NONE, DH_GROUP_1024_BIT_MODP, DH_GROUP_2048_BIT_MODP})
+    public @interface DhGroup {}
+
+    public static final int DH_GROUP_NONE = 0;
+    public static final int DH_GROUP_1024_BIT_MODP = 2;
+    public static final int DH_GROUP_2048_BIT_MODP = 14;
+
+    private static final Set<Integer> SUPPORTED_DH_GROUP;
+
+    static {
+        SUPPORTED_DH_GROUP = new ArraySet<>();
+        SUPPORTED_DH_GROUP.add(DH_GROUP_NONE);
+        SUPPORTED_DH_GROUP.add(DH_GROUP_1024_BIT_MODP);
+        SUPPORTED_DH_GROUP.add(DH_GROUP_2048_BIT_MODP);
+    }
+
+    /** Package private */
+    @IkePayload.ProtocolId private final int mProtocolId;
+    /** Package private */
+    private final EncryptionTransform[] mEncryptionAlgorithms;
+    /** Package private */
+    private final PrfTransform[] mPseudorandomFunctions;
+    /** Package private */
+    private final IntegrityTransform[] mIntegrityAlgorithms;
+    /** Package private */
+    private final DhGroupTransform[] mDhGroups;
+    /** Package private */
+    private final EsnTransform[] mEsns;
+
+    private SaProposal(
+            @IkePayload.ProtocolId int protocol,
+            EncryptionTransform[] encryptionAlgos,
+            PrfTransform[] prfs,
+            IntegrityTransform[] integrityAlgos,
+            DhGroupTransform[] dhGroups) {
+        mProtocolId = protocol;
+        mEncryptionAlgorithms = encryptionAlgos;
+        mPseudorandomFunctions = prfs;
+        mIntegrityAlgorithms = integrityAlgos;
+        mDhGroups = dhGroups;
+
+        if (protocol == IkePayload.PROTOCOL_ID_IKE) {
+            // Do not negotiate ESN for IKE SA proposal
+            mEsns = new EsnTransform[0];
+        } else {
+            // Do not support negotiating Child SAs using extended sequence numbers.
+            mEsns = new EsnTransform[] {new EsnTransform()};
+        }
+    }
+
+    /**
+     * Construct SaProposal from a decoded inbound IKE packet, only called by IkeSaPayload.
+     *
+     * @param protocol IP protocol ID
+     * @param encryptionAlgos encryption algorithms decoded from inbound IKE packet.
+     * @param prfs pseudorandom functions decoded from inbound IKE packet.
+     * @param integrityAlgos integrity algorithms decoded from inbound IKE packet.
+     * @param dhGroups Dh groups decoded from inbound IKE packet.
+     * @param esns ESN policies decoded from IKE packet.
+     */
+    public SaProposal(
+            @IkePayload.ProtocolId int protocol,
+            EncryptionTransform[] encryptionAlgos,
+            PrfTransform[] prfs,
+            IntegrityTransform[] integrityAlgos,
+            DhGroupTransform[] dhGroups,
+            EsnTransform[] esns) {
+        mProtocolId = protocol;
+        mEncryptionAlgorithms = encryptionAlgos;
+        mPseudorandomFunctions = prfs;
+        mIntegrityAlgorithms = integrityAlgos;
+        mDhGroups = dhGroups;
+        mEsns = esns;
+    }
+
+    /**
+     * Check if the current SaProposal from the SA responder is consistent with the selected
+     * reqProposal from the SA initiator.
+     *
+     * @param reqProposal selected SaProposal from SA initiator
+     * @return if current SaProposal from SA responder is consistent with the selected reqProposal
+     *     from SA initiator.
+     */
+    public boolean isNegotiatedFrom(SaProposal reqProposal) {
+        return isTransformSelectedFrom(mEncryptionAlgorithms, reqProposal.mEncryptionAlgorithms)
+                && isTransformSelectedFrom(
+                        mPseudorandomFunctions, reqProposal.mPseudorandomFunctions)
+                && isTransformSelectedFrom(mIntegrityAlgorithms, reqProposal.mIntegrityAlgorithms)
+                && isTransformSelectedFrom(mDhGroups, reqProposal.mDhGroups)
+                && isTransformSelectedFrom(mEsns, reqProposal.mEsns);
+    }
+
+    /** Package private */
+    static boolean isTransformSelectedFrom(Transform[] selected, Transform[] selectFrom) {
+        // If the selected proposal has multiple transforms with the same type, the responder MUST
+        // choose a single one.
+        if ((selected.length > 1) || (selected.length == 0) != (selectFrom.length == 0)) {
+            return false;
+        }
+
+        if (selected.length == 0) return true;
+
+        return Arrays.asList(selectFrom).contains(selected[0]);
+    }
+
+    /*Package private*/
+    @IkePayload.ProtocolId
+    int getProtocolId() {
+        return mProtocolId;
+    }
+
+    /*Package private*/
+    EncryptionTransform[] getEncryptionTransforms() {
+        return mEncryptionAlgorithms;
+    }
+
+    /*Package private*/
+    PrfTransform[] getPrfTransforms() {
+        return mPseudorandomFunctions;
+    }
+
+    /*Package private*/
+    IntegrityTransform[] getIntegrityTransforms() {
+        return mIntegrityAlgorithms;
+    }
+
+    /*Package private*/
+    DhGroupTransform[] getDhGroupTransforms() {
+        return mDhGroups;
+    }
+
+    /*Package private*/
+    EsnTransform[] getEsnTransforms() {
+        return mEsns;
+    }
+
+    /**
+     * Return all SA Transforms in this SaProposal to be encoded for building an outbound IKE
+     * message.
+     *
+     * <p>This method can be called by only IKE library.
+     *
+     * @return Array of Transforms to be encoded.
+     */
+    public Transform[] getAllTransforms() {
+        int encodedNumTransforms =
+                mEncryptionAlgorithms.length
+                        + mPseudorandomFunctions.length
+                        + mIntegrityAlgorithms.length
+                        + mDhGroups.length
+                        + mEsns.length;
+
+        List<Transform> transformList = new ArrayList<Transform>(encodedNumTransforms);
+        transformList.addAll(Arrays.asList(mEncryptionAlgorithms));
+        transformList.addAll(Arrays.asList(mPseudorandomFunctions));
+        transformList.addAll(Arrays.asList(mIntegrityAlgorithms));
+        transformList.addAll(Arrays.asList(mDhGroups));
+        transformList.addAll(Arrays.asList(mEsns));
+
+        return transformList.toArray(new Transform[encodedNumTransforms]);
+    }
+
+    /**
+     * This class can be used to incrementally construct a SaProposal. SaProposal instances are
+     * immutable once built.
+     *
+     * <p>TODO: Support users to add algorithms from most preferred to least preferred.
+     */
+    public static final class Builder {
+        private static final String ERROR_TAG = "Invalid SA Proposal: ";
+
+        /** Indicate if Builder is for building IKE SA proposal or Child SA proposal. */
+        private final boolean mIsIkeProposal;
+        /**
+         * Indicate if Builder is for building first Child SA proposal or addtional Child SA
+         * proposal. Only valid if mIsIkeProposal is false.
+         */
+        private final boolean mIsFirstChild;
+
+        // Use set to avoid adding repeated algorithms.
+        private final Set<EncryptionTransform> mProposedEncryptAlgos = new ArraySet<>();
+        private final Set<PrfTransform> mProposedPrfs = new ArraySet<>();
+        private final Set<IntegrityTransform> mProposedIntegrityAlgos = new ArraySet<>();
+        private final Set<DhGroupTransform> mProposedDhGroups = new ArraySet<>();
+
+        private boolean mHasAead = false;
+
+        private Builder(boolean isIke, boolean isFirstChild) {
+            mIsIkeProposal = isIke;
+            mIsFirstChild = isFirstChild;
+        }
+
+        private static boolean isAead(@EncryptionAlgorithm int algorithm) {
+            switch (algorithm) {
+                case ENCRYPTION_ALGORITHM_3DES:
+                    // Fall through
+                case ENCRYPTION_ALGORITHM_AES_CBC:
+                    return false;
+                case ENCRYPTION_ALGORITHM_AES_GCM_8:
+                    // Fall through
+                case ENCRYPTION_ALGORITHM_AES_GCM_12:
+                    // Fall through
+                case ENCRYPTION_ALGORITHM_AES_GCM_16:
+                    return true;
+                default:
+                    // Won't hit here.
+                    throw new IllegalArgumentException("Unsupported Encryption Algorithm.");
+            }
+        }
+
+        private EncryptionTransform[] buildEncryptAlgosOrThrow() {
+            if (mProposedEncryptAlgos.isEmpty()) {
+                throw new IllegalArgumentException(
+                        ERROR_TAG + "Encryption algorithm must be proposed.");
+            }
+
+            return mProposedEncryptAlgos.toArray(
+                    new EncryptionTransform[mProposedEncryptAlgos.size()]);
+        }
+
+        private PrfTransform[] buildPrfsOrThrow() {
+            if (mIsIkeProposal == mProposedPrfs.isEmpty()) {
+                throw new IllegalArgumentException(
+                        ERROR_TAG + "Invalid PRF configuration for this SA Proposal.");
+            }
+
+            return mProposedPrfs.toArray(new PrfTransform[mProposedPrfs.size()]);
+        }
+
+        private IntegrityTransform[] buildIntegAlgosForIkeOrThrow() {
+            // When building IKE SA Proposal with normal-mode ciphers, mProposedIntegrityAlgos must
+            // not be empty and must not have INTEGRITY_ALGORITHM_NONE. When building IKE SA
+            // Proposal with combined-mode ciphers, mProposedIntegrityAlgos must be either empty or
+            // only have INTEGRITY_ALGORITHM_NONE.
+            if (mProposedIntegrityAlgos.isEmpty() && !mHasAead) {
+                throw new IllegalArgumentException(
+                        ERROR_TAG
+                                + "Integrity algorithm "
+                                + "must be proposed with normal ciphers in IKE proposal.");
+            }
+
+            for (IntegrityTransform transform : mProposedIntegrityAlgos) {
+                if ((transform.id == INTEGRITY_ALGORITHM_NONE) != mHasAead) {
+                    throw new IllegalArgumentException(
+                            ERROR_TAG
+                                    + "Invalid integrity algorithm configuration"
+                                    + " for this SA Proposal");
+                }
+            }
+
+            return mProposedIntegrityAlgos.toArray(
+                    new IntegrityTransform[mProposedIntegrityAlgos.size()]);
+        }
+
+        private IntegrityTransform[] buildIntegAlgosForChildOrThrow() {
+            // When building Child SA Proposal with normal-mode ciphers, there is no contraint on
+            // integrity algorithm. When building Child SA Proposal with combined-mode ciphers,
+            // mProposedIntegrityAlgos must be either empty or only have INTEGRITY_ALGORITHM_NONE.
+            for (IntegrityTransform transform : mProposedIntegrityAlgos) {
+                if (transform.id != INTEGRITY_ALGORITHM_NONE && mHasAead) {
+                    throw new IllegalArgumentException(
+                            ERROR_TAG
+                                    + "Only INTEGRITY_ALGORITHM_NONE can be"
+                                    + " proposed with combined-mode ciphers in any proposal.");
+                }
+            }
+
+            return mProposedIntegrityAlgos.toArray(
+                    new IntegrityTransform[mProposedIntegrityAlgos.size()]);
+        }
+
+        private DhGroupTransform[] buildDhGroupsForIkeOrThrow() {
+            if (mProposedDhGroups.isEmpty()) {
+                throw new IllegalArgumentException(
+                        ERROR_TAG + "DH group must be proposed in IKE SA proposal.");
+            }
+
+            for (DhGroupTransform transform : mProposedDhGroups) {
+                if (transform.id == DH_GROUP_NONE) {
+                    throw new IllegalArgumentException(
+                            ERROR_TAG
+                                    + "None-value DH group must not"
+                                    + " be proposed in IKE SA proposal");
+                }
+            }
+
+            return mProposedDhGroups.toArray(new DhGroupTransform[mProposedDhGroups.size()]);
+        }
+
+        private DhGroupTransform[] buildDhGroupsForChildOrThrow() {
+            for (DhGroupTransform transform : mProposedDhGroups) {
+                if (transform.id != DH_GROUP_NONE && mIsFirstChild) {
+                    throw new IllegalArgumentException(
+                            ERROR_TAG
+                                    + "Only DH_GROUP_NONE can be"
+                                    + " proposed in first Child SA proposal.");
+                }
+            }
+            return mProposedDhGroups.toArray(new DhGroupTransform[mProposedDhGroups.size()]);
+        }
+
+        /** Returns a new Builder for a IKE SA Proposal. */
+        public static Builder newIkeSaProposalBuilder() {
+            return new Builder(true, false);
+        }
+
+        /**
+         * Returns a new Builder for a Child SA Proposal.
+         *
+         * @param isFirstChildSaProposal indicates if this SA proposal for first Child SA.
+         * @return Builder for a Child SA Proposal.
+         */
+        public static Builder newChildSaProposalBuilder(boolean isFirstChildSaProposal) {
+            return new Builder(false, isFirstChildSaProposal);
+        }
+
+        /**
+         * Adds an encryption algorithm to SA proposal being built.
+         *
+         * @param algorithm encryption algorithm to add to SaProposal.
+         * @return Builder of SaProposal.
+         */
+        public Builder addEncryptionAlgorithm(@EncryptionAlgorithm int algorithm) {
+            // Construct EncryptionTransform and validate proposed algorithm during
+            // construction.
+            EncryptionTransform encryptionTransform = new EncryptionTransform(algorithm);
+
+            validateOnlyOneModeEncryptAlgoProposedOrThrow(algorithm);
+
+            mProposedEncryptAlgos.add(encryptionTransform);
+            return this;
+        }
+
+        /**
+         * Adds an encryption algorithm with specific key length to SA proposal being built.
+         *
+         * @param algorithm encryption algorithm to add to SaProposal.
+         * @param keyLength key length of algorithm.
+         * @return Builder of SaProposal.
+         * @throws IllegalArgumentException if AEAD and non-combined mode algorithms are mixed.
+         */
+        public Builder addEncryptionAlgorithm(@EncryptionAlgorithm int algorithm, int keyLength) {
+            // Construct EncryptionTransform and validate proposed algorithm during
+            // construction.
+            EncryptionTransform encryptionTransform = new EncryptionTransform(algorithm, keyLength);
+
+            validateOnlyOneModeEncryptAlgoProposedOrThrow(algorithm);
+
+            mProposedEncryptAlgos.add(encryptionTransform);
+            return this;
+        }
+
+        private void validateOnlyOneModeEncryptAlgoProposedOrThrow(
+                @EncryptionAlgorithm int algorithm) {
+            boolean isCurrentAead = isAead(algorithm);
+
+            if (!mProposedEncryptAlgos.isEmpty() && (mHasAead ^ isCurrentAead)) {
+                throw new IllegalArgumentException(
+                        ERROR_TAG
+                                + "Proposal cannot has both normal ciphers "
+                                + "and combined-mode ciphers.");
+            }
+
+            if (isCurrentAead) mHasAead = true;
+        }
+
+        /**
+         * Adds a pseudorandom function to SA proposal being built.
+         *
+         * @param algorithm pseudorandom function to add to SaProposal.
+         * @return Builder of SaProposal.
+         */
+        public Builder addPseudorandomFunction(@PseudorandomFunction int algorithm) {
+            // Construct PrfTransform and validate proposed algorithm during
+            // construction.
+            mProposedPrfs.add(new PrfTransform(algorithm));
+            return this;
+        }
+
+        /**
+         * Adds an integrity algorithm to SA proposal being built.
+         *
+         * @param algorithm integrity algorithm to add to SaProposal.
+         * @return Builder of SaProposal.
+         */
+        public Builder addIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) {
+            // Construct IntegrityTransform and validate proposed algorithm during
+            // construction.
+            mProposedIntegrityAlgos.add(new IntegrityTransform(algorithm));
+            return this;
+        }
+
+        /**
+         * Adds a Diffie-Hellman Group to SA proposal being built.
+         *
+         * @param dhGroup to add to SaProposal.
+         * @return Builder of SaProposal.
+         */
+        public Builder addDhGroup(@DhGroup int dhGroup) {
+            // Construct DhGroupTransform and validate proposed dhGroup during
+            // construction.
+            mProposedDhGroups.add(new DhGroupTransform(dhGroup));
+            return this;
+        }
+
+        /**
+         * Validates, builds and returns the SaProposal
+         *
+         * @return SaProposal the validated SaProposal.
+         * @throws IllegalArgumentException if SaProposal is invalid.
+         */
+        public SaProposal build() {
+            EncryptionTransform[] encryptionTransforms = buildEncryptAlgosOrThrow();
+            PrfTransform[] prfTransforms = buildPrfsOrThrow();
+            IntegrityTransform[] integrityTransforms =
+                    mIsIkeProposal
+                            ? buildIntegAlgosForIkeOrThrow()
+                            : buildIntegAlgosForChildOrThrow();
+
+            DhGroupTransform[] dhGroupTransforms =
+                    mIsIkeProposal ? buildDhGroupsForIkeOrThrow() : buildDhGroupsForChildOrThrow();
+            // IKE library only supports negotiating ESP Child SA.
+            int protocol = mIsIkeProposal ? IkePayload.PROTOCOL_ID_IKE : IkePayload.PROTOCOL_ID_ESP;
+
+            return new SaProposal(
+                    protocol,
+                    encryptionTransforms,
+                    prfTransforms,
+                    integrityTransforms,
+                    dhGroupTransforms);
+        }
+    }
+
+    /**
+     * Check if the provided algorithm is a supported encryption algorithm.
+     *
+     * @param algorithm IKE standard encryption algorithm id.
+     * @return true if the provided algorithm is a supported encryption algorithm.
+     */
+    public static boolean isSupportedEncryptionAlgorithm(@EncryptionAlgorithm int algorithm) {
+        return SUPPORTED_ENCRYPTION_ALGORITHM.contains(algorithm);
+    }
+
+    /**
+     * Check if the provided algorithm is a supported pseudorandom function.
+     *
+     * @param algorithm IKE standard pseudorandom function id.
+     * @return true if the provided algorithm is a supported pseudorandom function.
+     */
+    public static boolean isSupportedPseudorandomFunction(@PseudorandomFunction int algorithm) {
+        return SUPPORTED_PSEUDORANDOM_FUNCTION.contains(algorithm);
+    }
+
+    /**
+     * Check if the provided algorithm is a supported integrity algorithm.
+     *
+     * @param algorithm IKE standard integrity algorithm id.
+     * @return true if the provided algorithm is a supported integrity algorithm.
+     */
+    public static boolean isSupportedIntegrityAlgorithm(@IntegrityAlgorithm int algorithm) {
+        return SUPPORTED_INTEGRITY_ALGORITHM.contains(algorithm);
+    }
+
+    /**
+     * Check if the provided group number is for a supported Diffie-Hellman Group.
+     *
+     * @param dhGroup IKE standard DH Group id.
+     * @return true if the provided number is for a supported Diffie-Hellman Group.
+     */
+    public static boolean isSupportedDhGroup(@DhGroup int dhGroup) {
+        return SUPPORTED_DH_GROUP.contains(dhGroup);
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/SaRecord.java b/src/java/com/android/ike/ikev2/SaRecord.java
new file mode 100644
index 0000000..4dcddec
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/SaRecord.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2;
+
+import com.android.ike.ikev2.message.IkeMessage;
+import com.android.ike.ikev2.message.IkePayload;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.List;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+
+/**
+ * SaRecord represents common information of an IKE SA and a Child SA.
+ *
+ * <p>When doing rekey, there can be multiple SAs in the same IkeSessionStateMachine or
+ * ChildSessionStateMachine, where they use same cryptographic algorithms but with different keys.
+ * We store cryptographic algorithms and unchanged SA configurations in IkeSessionOptions or
+ * ChildSessionOptions and store changed information including keys, SPIs, and nonces in SaRecord.
+ */
+public abstract class SaRecord {
+
+    private static ISaRecordHelper sSaRecordHelper = new SaRecordHelper();
+
+    public final byte[] nonceInitiator;
+    public final byte[] nonceResponder;
+
+    /** Package private */
+    SaRecord(byte[] nonceInit, byte[] nonceResp) {
+        nonceInitiator = nonceInit;
+        nonceResponder = nonceResp;
+    }
+
+    /**
+     * SaRecordHelper implements methods for constructing SaRecord.
+     *
+     * <p>Package private
+     */
+    static class SaRecordHelper implements ISaRecordHelper {
+        @Override
+        public IkeSaRecord makeFirstIkeSaRecord(IkeMessage initRequest, IkeMessage initResponse) {
+            // TODO: Generate keying materials
+            return null;
+        }
+
+        @Override
+        public IkeSaRecord makeNewIkeSaRecord(
+                IkeSaRecord oldSaRecord, IkeMessage rekeyRequest, IkeMessage rekeyResponse) {
+            // TODO: Generate keying materials based on old SK_d
+            return null;
+        }
+
+        @Override
+        public ChildSaRecord makeChildSaRecord(
+                List<IkePayload> reqPayloads, List<IkePayload> respPayloads) {
+            // TODO: Calculate keys and build IpSecTransform.
+            return null;
+        }
+    }
+
+    /** Package private */
+    static void setSaRecordHelper(ISaRecordHelper helper) {
+        sSaRecordHelper = helper;
+    }
+
+    /** IkeSaRecord represents an IKE SA. */
+    public static class IkeSaRecord extends SaRecord implements Comparable<IkeSaRecord> {
+
+        /** SPI of IKE SA initiator */
+        public final long initiatorSpi;
+        /** SPI of IKE SA responder */
+        public final long responderSpi;
+        /** Flag indicates if this IKE SA is locally initiated */
+        public final boolean isLocalInit;
+
+        /** Package private */
+        IkeSaRecord(
+                long initSpi, long respSpi, boolean localInit, byte[] nonceInit, byte[] nonceResp) {
+            super(nonceInit, nonceResp);
+            initiatorSpi = initSpi;
+            responderSpi = respSpi;
+            isLocalInit = localInit;
+            // TODO: Impement constructor. There will be more input parameters.
+        }
+
+        /** Package private */
+        static IkeSaRecord makeFirstIkeSaRecord(IkeMessage initRequest, IkeMessage initResponse) {
+            return sSaRecordHelper.makeFirstIkeSaRecord(initRequest, initResponse);
+        }
+
+        /** Package private */
+        static IkeSaRecord makeNewIkeSaRecord(
+                IkeSaRecord oldSaRecord, IkeMessage rekeyRequest, IkeMessage rekeyResponse) {
+            return sSaRecordHelper.makeNewIkeSaRecord(oldSaRecord, rekeyRequest, rekeyResponse);
+        }
+
+        /** Package private */
+        long getRemoteSpi() {
+            if (isLocalInit) {
+                return responderSpi;
+            } else {
+                return initiatorSpi;
+            }
+        }
+
+        /**
+         * Compare with a specific IkeSaRecord
+         *
+         * @param record IkeSaRecord to be compared.
+         * @return a negative integer if input IkeSaRecord contains lowest nonce; a positive integer
+         *     if this IkeSaRecord has lowest nonce; return zero if lowest nonces of two
+         *     IkeSaRecords match.
+         */
+        public int compareTo(IkeSaRecord record) {
+            // TODO: Implement it b/122924815.
+            return 1;
+        }
+    }
+
+    /** ChildSaRecord represents an Child SA. */
+    public static class ChildSaRecord extends SaRecord implements Comparable<ChildSaRecord> {
+
+        /** Locally generated SPI for receiving IPsec Packet. */
+        public final int inboundSpi;
+        /** Remotely generated SPI for sending IPsec Packet. */
+        public final int outboundSpi;
+
+        /** Package private */
+        ChildSaRecord(int inSpi, int outSpi, byte[] nonceInit, byte[] nonceResp) {
+            super(nonceInit, nonceResp);
+            inboundSpi = inSpi;
+            outboundSpi = outSpi;
+            // TODO: Impement constructor. Will be more input parameters.
+        }
+
+        /** Package private */
+        static ChildSaRecord makeChildSaRecord(
+                List<IkePayload> reqPayloads, List<IkePayload> respPayloads) {
+            return sSaRecordHelper.makeChildSaRecord(reqPayloads, respPayloads);
+        }
+
+        /**
+         * Compare with a specific ChildSaRecord
+         *
+         * @param record ChildSaRecord to be compared.
+         * @return a negative integer if input ChildSaRecord contains lowest nonce; a positive
+         *     integer if this ChildSaRecord has lowest nonce; return zero if lowest nonces of two
+         *     ChildSaRecord match.
+         */
+        public int compareTo(ChildSaRecord record) {
+            // TODO: Implement it b/122924815
+            return 1;
+        }
+    }
+
+    /**
+     * ISaRecordHelper provides a package private interface for constructing SaRecord.
+     *
+     * <p>ISaRecordHelper exists so that the interface is injectable for testing.
+     */
+    interface ISaRecordHelper {
+        /**
+         * Construct IkeSaRecord as results of IKE initial exchange.
+         *
+         * @param initRequest IKE_INIT request.
+         * @param initResponse IKE_INIT request.
+         * @return ikeSaRecord for initial IKE SA.
+         */
+        IkeSaRecord makeFirstIkeSaRecord(IkeMessage initRequest, IkeMessage initResponse);
+
+        /**
+         * Construct new IkeSaRecord when doing rekey.
+         *
+         * @param oldSaRecord old IKE SA
+         * @param rekeyRequest Rekey IKE request.
+         * @param rekeyResponse Rekey IKE response.
+         * @return ikeSaRecord for new IKE SA.
+         */
+        IkeSaRecord makeNewIkeSaRecord(
+                IkeSaRecord oldSaRecord, IkeMessage rekeyRequest, IkeMessage rekeyResponse);
+
+        /**
+         * Construct ChildSaRecord and generate IpSecTransform pairs.
+         *
+         * @param reqPayloads payload list in request.
+         * @param respPayloads payload list in response.
+         * @return new Child SA.
+         */
+        ChildSaRecord makeChildSaRecord(
+                List<IkePayload> reqPayloads, List<IkePayload> respPayloads);
+    }
+
+    /** Generate SKEYSEED using negotiated PRF. */
+    @VisibleForTesting
+    static byte[] generateSKeySeed(
+            String prfAlgorithm, byte[] nonceInit, byte[] nonceResp, byte[] sharedDhKey) {
+        try {
+            ByteBuffer keyBuffer = ByteBuffer.allocate(nonceInit.length + nonceResp.length);
+            keyBuffer.put(nonceInit).put(nonceResp);
+            SecretKeySpec prfKeySpec = new SecretKeySpec(keyBuffer.array(), prfAlgorithm);
+
+            Mac prfMac = Mac.getInstance(prfAlgorithm, IkeMessage.getSecurityProvider());
+            prfMac.init(prfKeySpec);
+
+            ByteBuffer sharedKeyBuffer = ByteBuffer.wrap(sharedDhKey);
+            prfMac.update(sharedKeyBuffer);
+
+            return prfMac.doFinal();
+        } catch (InvalidKeyException | NoSuchAlgorithmException e) {
+            throw new IllegalArgumentException("Failed to generate SKEYSEED", e);
+        }
+    }
+
+    /**
+     * Derives key materials using negotiated PRF.
+     *
+     * <p>prf+(K, S) outputs a pseudorandom stream by using negotiated PRF iteratively. In this way
+     * it can generate long enough keying material containing all the keys for this IKE/Child SA.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.13">RFC 7296 nternet Key Exchange
+     *     Protocol Version 2 (IKEv2) 2.13. Generating Keying Material </a>
+     */
+    @VisibleForTesting
+    static byte[] generateKeyMat(
+            String prfAlgorithm, byte[] prfKey, byte[] dataToSign, int keyMaterialLen)
+            throws InvalidKeyException {
+        try {
+            SecretKeySpec prfKeySpec = new SecretKeySpec(prfKey, prfAlgorithm);
+            Mac prfMac = Mac.getInstance(prfAlgorithm, IkeMessage.getSecurityProvider());
+
+            ByteBuffer keyMatBuffer = ByteBuffer.allocate(keyMaterialLen);
+
+            byte[] previousMac = new byte[0];
+            final int padLen = 1;
+            byte padValue = 1;
+
+            while (keyMatBuffer.remaining() > 0) {
+                prfMac.init(prfKeySpec);
+
+                ByteBuffer dataToSignBuffer =
+                        ByteBuffer.allocate(previousMac.length + dataToSign.length + padLen);
+                dataToSignBuffer.put(previousMac).put(dataToSign).put(padValue);
+                dataToSignBuffer.rewind();
+
+                prfMac.update(dataToSignBuffer);
+
+                previousMac = prfMac.doFinal();
+                keyMatBuffer.put(
+                        previousMac, 0, Math.min(previousMac.length, keyMatBuffer.remaining()));
+
+                padValue++;
+            }
+
+            return keyMatBuffer.array();
+        } catch (InvalidKeyException | NoSuchAlgorithmException e) {
+            throw new IllegalArgumentException("Failed to generate keying material", e);
+        }
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/exceptions/AuthenticationFailedException.java b/src/java/com/android/ike/ikev2/exceptions/AuthenticationFailedException.java
new file mode 100644
index 0000000..8a5433b
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/exceptions/AuthenticationFailedException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.exceptions;
+
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+
+/**
+ * This exception is thrown when IKE authentication fails.
+ *
+ * <p>Contains an exception message detailing the failure cause.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.21.2">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class AuthenticationFailedException extends IkeException {
+    /**
+     * Construct a instance of AuthenticationFailedException.
+     *
+     * @param message the detail message.
+     */
+    public AuthenticationFailedException(String message) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_AUTHENTICATION_FAILED, message);
+    }
+
+    /**
+     * Construct a instance of AuthenticationFailedExcepion.
+     *
+     * @param cause the cause.
+     */
+    public AuthenticationFailedException(Throwable cause) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_AUTHENTICATION_FAILED, cause);
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/exceptions/IkeException.java b/src/java/com/android/ike/ikev2/exceptions/IkeException.java
new file mode 100644
index 0000000..532b634
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/exceptions/IkeException.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.exceptions;
+
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+
+/**
+ * IkeException is an abstract class that represents the common information for all IKE protocol
+ * errors.
+ *
+ * <p>Each types of IKE error should implement its own subclass
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.10.1">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public abstract class IkeException extends Exception {
+    @IkeNotifyPayload.NotifyType public final int errorCode;
+
+    /**
+     * Construct an instance of IkeException.
+     *
+     * @param code the protocol error code.
+     */
+    public IkeException(@IkeNotifyPayload.NotifyType int code) {
+        super();
+        errorCode = code;
+    }
+
+    /**
+     * Construct an instance of IkeException with specified detail message.
+     *
+     * @param code the protocol error code.
+     * @param message the detail message.
+     */
+    public IkeException(@IkeNotifyPayload.NotifyType int code, String message) {
+        super(message);
+        errorCode = code;
+    }
+
+    /**
+     * Construct an instance of IkeException with specified cause.
+     *
+     * @param code the protocol error code.
+     * @param cause the cause.
+     */
+    public IkeException(@IkeNotifyPayload.NotifyType int code, Throwable cause) {
+        super(cause);
+        errorCode = code;
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/exceptions/InvalidMajorVersionException.java b/src/java/com/android/ike/ikev2/exceptions/InvalidMajorVersionException.java
new file mode 100644
index 0000000..d23d0e3
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/exceptions/InvalidMajorVersionException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.exceptions;
+
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+
+/**
+ * This exception is thrown when major version is higher than 2.
+ *
+ * <p>Include INVALID_MAJOR_VERSION Notify payload in an unencrypted response message containing
+ * version number 2.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.5">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class InvalidMajorVersionException extends IkeException {
+    public final byte receivedMajorVersion;
+
+    /**
+     * Construct a instance of InvalidMajorVersionException
+     *
+     * @param version the major version in received packet
+     */
+    public InvalidMajorVersionException(byte version) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_INVALID_MAJOR_VERSION);
+        receivedMajorVersion = version;
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/exceptions/InvalidSyntaxException.java b/src/java/com/android/ike/ikev2/exceptions/InvalidSyntaxException.java
new file mode 100644
index 0000000..489eeff
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/exceptions/InvalidSyntaxException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.exceptions;
+
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+
+/**
+ * This exception is thrown if any IKE message field is invalid.
+ *
+ * <p>Include INVALID_SYNTAX Notify payload in an encrypted response message if current message is
+ * an encrypted request and cryptographic checksum is valid. Fatal error.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.10.1">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class InvalidSyntaxException extends IkeException {
+    /**
+     * Construct an instance of InvalidSyntaxException.
+     *
+     * @param message the descriptive message.
+     */
+    public InvalidSyntaxException(String message) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_INVALID_SYNTAX);
+    }
+
+    /**
+     * Construct a instance of InvalidSyntaxException.
+     *
+     * @param cause the reason of exception.
+     */
+    public InvalidSyntaxException(Throwable cause) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_INVALID_SYNTAX, cause);
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/exceptions/NoValidProposalChosenException.java b/src/java/com/android/ike/ikev2/exceptions/NoValidProposalChosenException.java
new file mode 100644
index 0000000..8aac872
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/exceptions/NoValidProposalChosenException.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.exceptions;
+
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+
+/**
+ * This exception is thrown if either none of SA proposals from SA initiator is acceptable or the
+ * negotiated SA proposal from SA responder is invalid.
+ *
+ * <p>Include the NO_PROPOSAL_CHOSEN Notify payload in an encrypted response message if received
+ * message is an encrypted request from SA initiator.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.7">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class NoValidProposalChosenException extends IkeException {
+    /**
+     * Construct an instance of NoValidProposalChosenException.
+     *
+     * @param message the descriptive message.
+     */
+    public NoValidProposalChosenException(String message) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_NO_PROPOSAL_CHOSEN, message);
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/exceptions/UnsupportedCriticalPayloadException.java b/src/java/com/android/ike/ikev2/exceptions/UnsupportedCriticalPayloadException.java
new file mode 100644
index 0000000..1bfde97
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/exceptions/UnsupportedCriticalPayloadException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.exceptions;
+
+import com.android.ike.ikev2.message.IkeNotifyPayload;
+
+import java.util.List;
+
+/**
+ * This exception is thrown when payload type is not supported and critical bit is set
+ *
+ * <p>Include UNSUPPORTED_CRITICAL_PAYLOAD Notify payload in a response message containing the
+ * payload type for each payload.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.5">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class UnsupportedCriticalPayloadException extends IkeException {
+
+    public final List<Integer> payloadTypeList;
+
+    /**
+     * Construct an instance of UnsupportedCriticalPayloadException
+     *
+     * @param payloadList the list of all unsupported critical payload types
+     */
+    public UnsupportedCriticalPayloadException(List<Integer> payloadList) {
+        super(IkeNotifyPayload.NOTIFY_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD);
+        payloadTypeList = payloadList;
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayload.java b/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayload.java
new file mode 100644
index 0000000..9d7e044
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayload.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import android.annotation.StringDef;
+
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.message.IkeAuthPayload.AuthMethod;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+/**
+ * IkeAuthDigitalSignPayload represents Authentication Payload using a specific or generic digital
+ * signature authentication method.
+ *
+ * <p>If AUTH_METHOD_RSA_DIGITAL_SIGN is used, then the hash algorithm is SHA1. If
+ * AUTH_METHOD_GENERIC_DIGITAL_SIGN is used, the signature algorihtm and hash algorithm are
+ * extracted from authentication data.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.8">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ * @see <a href="https://tools.ietf.org/html/rfc7427">RFC 7427, Signature Authentication in the
+ *     Internet Key Exchange Version 2 (IKEv2)</a>
+ */
+public class IkeAuthDigitalSignPayload extends IkeAuthPayload {
+
+    // Byte arrays of DER encoded identifier ASN.1 objects that indicates the algorithm used to
+    // generate the signature, extracted from
+    // <a href="https://tools.ietf.org/html/rfc7427#appendix-A"> RFC 7427. There is no need to
+    // understand the encoding process. They are just constants to indicate the algorithm type.
+    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA1 = {
+        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+        (byte) 0x05, (byte) 0x05, (byte) 0x00
+    };
+    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA2_256 = {
+        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+        (byte) 0x0b, (byte) 0x05, (byte) 0x00
+    };
+    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA2_384 = {
+        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+        (byte) 0x0c, (byte) 0x05, (byte) 0x00
+    };
+    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA2_512 = {
+        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
+        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
+        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
+        (byte) 0x0d, (byte) 0x05, (byte) 0x00
+    };
+
+    // Length of ASN.1 object length field.
+    private static final int SIGNATURE_ALGO_ASN1_LEN_LEN = 1;
+
+    // Currently we only support RSA for signature algorithm.
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef({
+        SIGNATURE_ALGO_RSA_SHA1,
+        SIGNATURE_ALGO_RSA_SHA2_256,
+        SIGNATURE_ALGO_RSA_SHA2_384,
+        SIGNATURE_ALGO_RSA_SHA2_512
+    })
+    public @interface SignatureAlgo {}
+
+    public static final String SIGNATURE_ALGO_RSA_SHA1 = "SHA1withRSA";
+    public static final String SIGNATURE_ALGO_RSA_SHA2_256 = "SHA256withRSA";
+    public static final String SIGNATURE_ALGO_RSA_SHA2_384 = "SHA384withRSA";
+    public static final String SIGNATURE_ALGO_RSA_SHA2_512 = "SHA512withRSA";
+    // TODO: Allow users to configure authentication method using @SignatureAlgo
+
+    public final String signatureAlgoAndHash;
+    public final byte[] signature;
+
+    protected IkeAuthDigitalSignPayload(
+            boolean critical, @AuthMethod int authMethod, byte[] authData) throws IkeException {
+        super(critical, authMethod);
+        switch (authMethod) {
+            case AUTH_METHOD_RSA_DIGITAL_SIGN:
+                signatureAlgoAndHash = SIGNATURE_ALGO_RSA_SHA1;
+                signature = authData;
+                break;
+            case AUTH_METHOD_GENERIC_DIGITAL_SIGN:
+                ByteBuffer inputBuffer = ByteBuffer.wrap(authData);
+
+                // Get signature algorithm.
+                int signAlgoLen = Byte.toUnsignedInt(inputBuffer.get());
+                byte[] signAlgoBytes = new byte[signAlgoLen];
+                inputBuffer.get(signAlgoBytes);
+                signatureAlgoAndHash = bytesToSignAlgoName(signAlgoBytes);
+
+                // Get signature.
+                signature = new byte[authData.length - SIGNATURE_ALGO_ASN1_LEN_LEN - signAlgoLen];
+                inputBuffer.get(signature);
+                break;
+            default:
+                // Won't hit here.
+                throw new IllegalArgumentException("Unrecognized authentication method.");
+        }
+    }
+
+    private String bytesToSignAlgoName(byte[] signAlgoBytes) throws AuthenticationFailedException {
+        if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA1, signAlgoBytes)) {
+            return SIGNATURE_ALGO_RSA_SHA1;
+        } else if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA2_256, signAlgoBytes)) {
+            return SIGNATURE_ALGO_RSA_SHA2_256;
+        } else if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA2_384, signAlgoBytes)) {
+            return SIGNATURE_ALGO_RSA_SHA2_384;
+        } else if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA2_512, signAlgoBytes)) {
+            return SIGNATURE_ALGO_RSA_SHA2_512;
+        } else {
+            throw new AuthenticationFailedException(
+                    "Unrecognized ASN.1 objects for Signature algorithm and Hash");
+        }
+    }
+
+    // TODO: Add methods for generating and validating signature.
+
+    @Override
+    protected void encodeAuthDataToByteBuffer(ByteBuffer byteBuffer) {
+        // TODO: Implement it.
+        throw new UnsupportedOperationException(
+                "It is not supported to encode a " + getTypeString());
+    }
+
+    @Override
+    protected int getAuthDataLength() {
+        // TODO: Implement it.
+        throw new UnsupportedOperationException(
+                "It is not supported to get payload length of " + getTypeString());
+    }
+
+    @Override
+    public String getTypeString() {
+        return "Authentication-Digital-Signature Payload";
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayload.java b/src/java/com/android/ike/ikev2/message/IkeAuthPayload.java
similarity index 77%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayload.java
rename to src/java/com/android/ike/ikev2/message/IkeAuthPayload.java
index 53a3f65..d6e2db0 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeAuthPayload.java
@@ -14,17 +14,19 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import android.annotation.IntDef;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
 
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.IkeException;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
 
 /**
  * IkeAuthPayload is an abstract class that represents the common information for all Authentication
@@ -65,7 +67,7 @@
     }
 
     protected static IkeAuthPayload getIkeAuthPayload(boolean critical, byte[] payloadBody)
-            throws IkeProtocolException {
+            throws IkeException {
         ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
 
         int authMethod = Byte.toUnsignedInt(inputBuffer.get());
@@ -76,6 +78,7 @@
         byte[] authData = new byte[payloadBody.length - AUTH_HEADER_LEN];
         inputBuffer.get(authData);
         switch (authMethod) {
+                // TODO: Handle RSA and generic signature-based authentication.
             case AUTH_METHOD_PRE_SHARED_KEY:
                 return new IkeAuthPskPayload(critical, authData);
             case AUTH_METHOD_RSA_DIGITAL_SIGN:
@@ -85,10 +88,26 @@
                 return new IkeAuthDigitalSignPayload(
                         critical, AUTH_METHOD_GENERIC_DIGITAL_SIGN, authData);
             default:
-                throw new AuthenticationFailedException("Unsupported authentication method");
+                // TODO: Throw AuthenticationFailedException
+                throw new UnsupportedOperationException("Unsupported authentication method");
         }
     }
 
+    // Sign data with PRF when building outbound packet or verifying inbound packet. It is called
+    // for calculating signature over ID payload for all types of authentication and also for
+    // calculating signature over PSK for PSK authentication.
+    protected static byte[] signWithPrf(Mac prfMac, byte[] prfKeyBytes, byte[] dataToSign)
+            throws InvalidKeyException {
+        SecretKeySpec prfKey = new SecretKeySpec(prfKeyBytes, prfMac.getAlgorithm());
+        prfMac.init(prfKey);
+
+        ByteBuffer dataBuffer = ByteBuffer.wrap(dataToSign);
+
+        // Calculate MAC.
+        prfMac.update(dataBuffer);
+        return prfMac.doFinal();
+    }
+
     // When not using EAP, the peers are authenticated by having each sign a block of data named as
     // SignedOctets. IKE initiator's SignedOctets are the concatenation of the IKE_INIT request
     // message, the Nonce of IKE responder and the signed ID-Initiator payload body. Similarly, IKE
@@ -98,9 +117,10 @@
             byte[] ikeInitBytes,
             byte[] nonce,
             byte[] idPayloadBodyBytes,
-            IkeMacPrf ikePrf,
-            byte[] prfKeyBytes) {
-        byte[] signedidPayloadBodyBytes = ikePrf.signBytes(prfKeyBytes, idPayloadBodyBytes);
+            Mac prfMac,
+            byte[] prfKeyBytes)
+            throws InvalidKeyException {
+        byte[] signedidPayloadBodyBytes = signWithPrf(prfMac, prfKeyBytes, idPayloadBodyBytes);
 
         ByteBuffer buffer =
                 ByteBuffer.allocate(
@@ -122,6 +142,11 @@
         return GENERIC_HEADER_LENGTH + AUTH_HEADER_LEN + getAuthDataLength();
     }
 
+    @Override
+    public String getTypeString() {
+        return "Authentication Payload";
+    }
+
     protected abstract void encodeAuthDataToByteBuffer(ByteBuffer byteBuffer);
 
     protected abstract int getAuthDataLength();
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayload.java b/src/java/com/android/ike/ikev2/message/IkeAuthPskPayload.java
similarity index 82%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayload.java
rename to src/java/com/android/ike/ikev2/message/IkeAuthPskPayload.java
index 93bef17..182df8a 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeAuthPskPayload.java
@@ -14,14 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
 
 import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
 import java.util.Arrays;
 
+import javax.crypto.Mac;
+
 /**
  * IkeAuthPskPayload represents an Authentication Payload using Pre-Shared Key to do authentication.
  *
@@ -61,20 +63,20 @@
      * @param nonce nonce of IKE responder for calculating IKE initiator's SignedOctets.
      * @param idPayloadBodyBytes ID-Initiator payload body for calculating IKE initiator's
      *     SignedOctets.
-     * @param ikePrf the negotiated PRF.
-     * @param prfKeyBytes the negotiated PRF key.
+     * @param prfMac locally stored PRF
+     * @param prfKeyBytes locally stored PRF keys
      */
     public IkeAuthPskPayload(
             byte[] psk,
             byte[] ikeInitBytes,
             byte[] nonce,
             byte[] idPayloadBodyBytes,
-            IkeMacPrf ikePrf,
+            Mac prfMac,
             byte[] prfKeyBytes) {
         super(false, IkeAuthPayload.AUTH_METHOD_PRE_SHARED_KEY);
         signature =
                 calculatePskSignature(
-                        psk, ikeInitBytes, nonce, idPayloadBodyBytes, ikePrf, prfKeyBytes);
+                        psk, ikeInitBytes, nonce, idPayloadBodyBytes, prfMac, prfKeyBytes);
     }
 
     private static byte[] calculatePskSignature(
@@ -82,13 +84,16 @@
             byte[] ikeInitBytes,
             byte[] nonce,
             byte[] idPayloadBodyBytes,
-            IkeMacPrf ikePrf,
+            Mac prfMac,
             byte[] prfKeyBytes) {
-        byte[] signingKeyBytes = ikePrf.signBytes(psk, IKE_KEY_PAD_STRING_ASCII_HEX_BYTES);
-        byte[] dataToSignBytes =
-                getSignedOctets(ikeInitBytes, nonce, idPayloadBodyBytes, ikePrf, prfKeyBytes);
-
-        return ikePrf.signBytes(signingKeyBytes, dataToSignBytes);
+        try {
+            byte[] signingKeyBytes = signWithPrf(prfMac, psk, IKE_KEY_PAD_STRING_ASCII_HEX_BYTES);
+            byte[] dataToSignBytes =
+                    getSignedOctets(ikeInitBytes, nonce, idPayloadBodyBytes, prfMac, prfKeyBytes);
+            return signWithPrf(prfMac, signingKeyBytes, dataToSignBytes);
+        } catch (InvalidKeyException e) {
+            throw new IllegalArgumentException("Locally stored PRF key is invalid: ", e);
+        }
     }
 
     /**
@@ -103,8 +108,8 @@
      * @param nonce nonce of IKE initiator for calculating IKE responder's SignedOctets.
      * @param idPayloadBodyBytes ID-Responder payload body for calculating IKE responder's
      *     SignedOctets.
-     * @param ikePrf the negotiated PRF.
-     * @param prfKeyBytes the negotiated PRF key.
+     * @param prfMac locally stored PRF
+     * @param prfKeyBytes locally stored PRF keys
      * @throws AuthenticationFailedException if received signature is not equal to calculated
      *     signature.
      */
@@ -113,12 +118,12 @@
             byte[] ikeInitBytes,
             byte[] nonce,
             byte[] idPayloadBodyBytes,
-            IkeMacPrf ikePrf,
+            Mac prfMac,
             byte[] prfKeyBytes)
             throws AuthenticationFailedException {
         byte[] calculatedSignature =
                 calculatePskSignature(
-                        psk, ikeInitBytes, nonce, idPayloadBodyBytes, ikePrf, prfKeyBytes);
+                        psk, ikeInitBytes, nonce, idPayloadBodyBytes, prfMac, prfKeyBytes);
         if (!Arrays.equals(signature, calculatedSignature)) {
             throw new AuthenticationFailedException("Signature verification failed.");
         }
@@ -136,6 +141,6 @@
 
     @Override
     public String getTypeString() {
-        return "Auth(PSK)";
+        return "Authentication-PSK Payload";
     }
 }
diff --git a/src/java/com/android/ike/ikev2/message/IkeCertPayload.java b/src/java/com/android/ike/ikev2/message/IkeCertPayload.java
new file mode 100644
index 0000000..bd54ee2
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeCertPayload.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import android.annotation.IntDef;
+
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.IkeException;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+
+/**
+ * IkeCertPayload is an abstract class that represents the common information for all Certificate
+ * Payload carrying different types of certifciate-related data and static methods related to
+ * certificate validation.
+ *
+ * <p>Certificate Payload is only sent in IKE_AUTH exchange.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.6">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public abstract class IkeCertPayload extends IkePayload {
+    // Length of certificate encoding type field in octets.
+    private static final int CERT_ENCODING_LEN = 1;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        CERTIFICATE_ENCODING_X509_CERT_SIGNATURE,
+        CERTIFICATE_ENCODING_CRL,
+        CERTIFICATE_ENCODING_X509_CERT_HASH_URL,
+    })
+    public @interface CertificateEncoding {}
+
+    public static final int CERTIFICATE_ENCODING_X509_CERT_SIGNATURE = 4;
+    public static final int CERTIFICATE_ENCODING_CRL = 7;
+    public static final int CERTIFICATE_ENCODING_X509_CERT_HASH_URL = 12;
+
+    @CertificateEncoding public final int certEncodingType;
+
+    protected IkeCertPayload(boolean critical, @CertificateEncoding int encodingType) {
+        super(PAYLOAD_TYPE_CERT, critical);
+        certEncodingType = encodingType;
+    }
+
+    protected static IkeCertPayload getIkeCertPayload(boolean critical, byte[] payloadBody)
+            throws IkeException {
+        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
+
+        int certEncodingType = Byte.toUnsignedInt(inputBuffer.get());
+        byte[] certData = new byte[payloadBody.length - CERT_ENCODING_LEN];
+        inputBuffer.get(certData);
+        switch (certEncodingType) {
+            case CERTIFICATE_ENCODING_X509_CERT_SIGNATURE:
+                return new IkeCertX509CertPayload(critical, certData);
+                // TODO: Support decoding CRL and "Hash and URL".
+            case CERTIFICATE_ENCODING_CRL:
+                throw new AuthenticationFailedException(
+                        "CERTIFICATE_ENCODING_CRL decoding is unsupported.");
+            case CERTIFICATE_ENCODING_X509_CERT_HASH_URL:
+                throw new AuthenticationFailedException(
+                        "CERTIFICATE_ENCODING_X509_CERT_HASH_URL decoding is unsupported");
+            default:
+                throw new AuthenticationFailedException("Unrecognized certificate encoding type.");
+        }
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayload.java b/src/java/com/android/ike/ikev2/message/IkeCertX509CertPayload.java
similarity index 86%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayload.java
rename to src/java/com/android/ike/ikev2/message/IkeCertX509CertPayload.java
index 1804b9b..76fab4f 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeCertX509CertPayload.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.IkeException;
 
 import java.io.ByteArrayInputStream;
 import java.nio.ByteBuffer;
@@ -40,14 +39,7 @@
 public final class IkeCertX509CertPayload extends IkeCertPayload {
     public final X509Certificate certificate;
 
-    /** Construct IkeCertX509CertPayload for an outbound packet. */
-    public IkeCertX509CertPayload(X509Certificate x509Certificate) {
-        super(CERTIFICATE_ENCODING_X509_CERT_SIGNATURE);
-        certificate = x509Certificate;
-    }
-
-    protected IkeCertX509CertPayload(boolean critical, byte[] certData)
-            throws IkeProtocolException {
+    protected IkeCertX509CertPayload(boolean critical, byte[] certData) throws IkeException {
         super(critical, CERTIFICATE_ENCODING_X509_CERT_SIGNATURE);
         try {
             CertificateFactory factory =
@@ -100,6 +92,6 @@
      */
     @Override
     public String getTypeString() {
-        return "Cert(X509)";
+        return "Certificate Payload Carrying X.509 Certificate";
     }
 }
diff --git a/src/java/com/android/ike/ikev2/message/IkeDeletePayload.java b/src/java/com/android/ike/ikev2/message/IkeDeletePayload.java
new file mode 100644
index 0000000..fd4f364
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeDeletePayload.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+
+import java.nio.ByteBuffer;
+
+/**
+ * IkeDeletePayload represents a Delete Payload.
+ *
+ * <p>As instructed in RFC 7296, deletion of the IKE SA is indicated by a protocol ID of 1 (IKE) but
+ * no SPIs. Deletion of a Child SA will contain the IPsec protocol ID and SPIs of inbound IPsec
+ * packets. Since IKE library only supports negotiating Child SA using ESP, only the protocol ID of
+ * 3 (ESP) is used for deleting Child SA.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.11">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class IkeDeletePayload extends IkePayload {
+
+    @ProtocolId public final int protocolId;
+    public final byte spiSize;
+    public final int numSpi;
+    public final int[] spisToDelete;
+
+    /**
+     * Construct an instance of IkeDeletePayload from decoding inbound IKE packet.
+     *
+     * <p>NegativeArraySizeException and BufferUnderflowException will be caught in {@link
+     * IkeMessage}
+     *
+     * @param critical indicates if this payload is critical. Ignored in supported payload as
+     *     instructed by the RFC 7296.
+     * @param payloadBody payload body in byte array
+     * @throws IkeException if there is any error
+     */
+    IkeDeletePayload(boolean critical, byte[] payloadBody) throws IkeException {
+        super(PAYLOAD_TYPE_DELETE, critical);
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
+
+        protocolId = Byte.toUnsignedInt(inputBuffer.get());
+        spiSize = inputBuffer.get();
+        numSpi = Short.toUnsignedInt(inputBuffer.getShort());
+        spisToDelete = new int[numSpi];
+
+        switch (protocolId) {
+            case PROTOCOL_ID_IKE:
+                // Delete payload for IKE SA must not include SPI.
+                if (spiSize != SPI_LEN_NOT_INCLUDED
+                        || numSpi != 0
+                        || inputBuffer.remaining() != 0) {
+                    throw new InvalidSyntaxException("Invalid Delete IKE Payload.");
+                }
+                break;
+            case PROTOCOL_ID_ESP:
+                // Delete payload for Child SA must include SPI
+                if (spiSize != SPI_LEN_IPSEC
+                        || numSpi == 0
+                        || inputBuffer.remaining() != SPI_LEN_IPSEC * numSpi) {
+                    throw new InvalidSyntaxException("Invalid Delete Child Payload.");
+                }
+
+                for (int i = 0; i < numSpi; i++) {
+                    spisToDelete[i] = inputBuffer.getInt();
+                }
+                break;
+            default:
+                throw new InvalidSyntaxException("Unrecognized protocol in Delete Payload.");
+        }
+    }
+
+    // TODO: Add a constructor for building outbound IKE message.
+
+    /**
+     * Encode Delete Payload to ByteBuffer.
+     *
+     * @param nextPayload type of payload that follows this payload.
+     * @param byteBuffer destination ByteBuffer that stores encoded payload.
+     */
+    @Override
+    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+        throw new UnsupportedOperationException("Operation not supported.");
+        // TODO: Implement it.
+    }
+
+    /**
+     * Get entire payload length.
+     *
+     * @return entire payload length.
+     */
+    @Override
+    protected int getPayloadLength() {
+        throw new UnsupportedOperationException("Operation not supported.");
+        // TODO: Implement it.
+    }
+
+    /**
+     * Return the payload type as a String.
+     *
+     * @return the payload type as a String.
+     */
+    @Override
+    public String getTypeString() {
+        return "Delete Payload";
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBody.java b/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBody.java
new file mode 100644
index 0000000..a41d855
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBody.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.security.SecureRandom;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+
+/**
+ * IkeEncryptedPayloadBody is a package private class that represents an IKE payload substructure
+ * that contains initialization vector, encrypted content, padding, pad length and integrity
+ * checksum.
+ *
+ * <p>Both an Encrypted Payload (IkeSkPayload) and an EncryptedFragmentPayload (IkeSkfPayload)
+ * consists of an IkeEncryptedPayloadBody instance.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#page-105">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ * @see <a href="https://tools.ietf.org/html/rfc7383#page-6">RFC 7383, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2) Message Fragmentation</a>
+ */
+final class IkeEncryptedPayloadBody {
+    // Length of pad length field.
+    private static final int PAD_LEN_LEN = 1;
+
+    private final byte[] mUnencryptedData;
+    private final byte[] mEncryptedAndPaddedData;
+    private final byte[] mIv;
+    private final byte[] mIntegrityChecksum;
+
+    /**
+     * Package private constructor for constructing an instance of IkeEncryptedPayloadBody from
+     * decrypting an incoming packet.
+     */
+    IkeEncryptedPayloadBody(
+            byte[] message, Mac integrityMac, int checksumLen, Cipher decryptCipher, SecretKey dKey)
+            throws IkeException, GeneralSecurityException {
+        ByteBuffer inputBuffer = ByteBuffer.wrap(message);
+
+        // Skip IKE header and SK payload header
+        byte[] tempArray = new byte[IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH];
+        inputBuffer.get(tempArray);
+
+        // Extract bytes for authentication and decryption.
+        int expectedIvLen = decryptCipher.getBlockSize();
+        mIv = new byte[expectedIvLen];
+
+        int encryptedDataLen =
+                message.length
+                        - (IkeHeader.IKE_HEADER_LENGTH
+                                + IkePayload.GENERIC_HEADER_LENGTH
+                                + expectedIvLen
+                                + checksumLen);
+        // IkeMessage will catch exception if encryptedDataLen is negative.
+        mEncryptedAndPaddedData = new byte[encryptedDataLen];
+
+        mIntegrityChecksum = new byte[checksumLen];
+        inputBuffer.get(mIv).get(mEncryptedAndPaddedData).get(mIntegrityChecksum);
+
+        // Authenticate and decrypt.
+        byte[] dataToAuthenticate = Arrays.copyOfRange(message, 0, message.length - checksumLen);
+        validateChecksumOrThrow(dataToAuthenticate, integrityMac, mIntegrityChecksum);
+        mUnencryptedData = decrypt(mEncryptedAndPaddedData, decryptCipher, dKey, mIv);
+    }
+
+    /**
+     * Package private constructor for constructing an instance of IkeEncryptedPayloadBody for
+     * building an outbound packet.
+     */
+    IkeEncryptedPayloadBody(
+            IkeHeader ikeHeader,
+            @IkePayload.PayloadType int firstPayloadType,
+            byte[] unencryptedPayloads,
+            Mac integrityMac,
+            int checksumLen,
+            Cipher encryptCipher,
+            SecretKey eKey) {
+        this(
+                ikeHeader,
+                firstPayloadType,
+                unencryptedPayloads,
+                integrityMac,
+                checksumLen,
+                encryptCipher,
+                eKey,
+                encryptCipher.getIV(),
+                calculatePadding(unencryptedPayloads.length, encryptCipher.getBlockSize()));
+    }
+
+    /** Package private constructor only for testing. */
+    @VisibleForTesting
+    IkeEncryptedPayloadBody(
+            IkeHeader ikeHeader,
+            @IkePayload.PayloadType int firstPayloadType,
+            byte[] unencryptedPayloads,
+            Mac integrityMac,
+            int checksumLen,
+            Cipher encryptCipher,
+            SecretKey eKey,
+            byte[] iv,
+            byte[] padding) {
+        mUnencryptedData = unencryptedPayloads;
+
+        // Encrypt data
+        mIv = iv;
+        mEncryptedAndPaddedData = encrypt(unencryptedPayloads, encryptCipher, eKey, iv, padding);
+
+        // Build authenticated section using ByteBuffer. Authenticated section includes bytes from
+        // beginning of IKE header to the pad length, which are concatenation of IKE header, current
+        // payload header, iv and encrypted and padded data.
+        int dataToAuthenticateLength =
+                IkeHeader.IKE_HEADER_LENGTH
+                        + IkePayload.GENERIC_HEADER_LENGTH
+                        + iv.length
+                        + mEncryptedAndPaddedData.length;
+        ByteBuffer authenticatedSectionBuffer = ByteBuffer.allocate(dataToAuthenticateLength);
+
+        // Encode IKE header
+        int encryptedPayloadLength =
+                IkePayload.GENERIC_HEADER_LENGTH
+                        + iv.length
+                        + mEncryptedAndPaddedData.length
+                        + checksumLen;
+        ikeHeader.encodeToByteBuffer(authenticatedSectionBuffer, encryptedPayloadLength);
+
+        // Encode payload header. The next payload type field indicates the first payload nested in
+        // this SkPayload/SkfPayload.
+        int payloadLength =
+                IkePayload.GENERIC_HEADER_LENGTH
+                        + iv.length
+                        + mEncryptedAndPaddedData.length
+                        + checksumLen;
+        IkePayload.encodePayloadHeaderToByteBuffer(
+                firstPayloadType, payloadLength, authenticatedSectionBuffer);
+
+        // Encode iv and padded encrypted data.
+        authenticatedSectionBuffer.put(iv).put(mEncryptedAndPaddedData);
+
+        // Calculate checksum
+        mIntegrityChecksum =
+                calculateChecksum(authenticatedSectionBuffer.array(), integrityMac, checksumLen);
+    }
+
+    // TODO: Add another constructor for AEAD protected payload.
+
+    // TODO: Add constructors that initiate IkeEncryptedPayloadBody for an outbound packet
+
+    /** Package private for testing */
+    @VisibleForTesting
+    static byte[] calculateChecksum(byte[] dataToAuthenticate, Mac integrityMac, int checksumLen) {
+        ByteBuffer inputBuffer = ByteBuffer.wrap(dataToAuthenticate);
+        integrityMac.update(inputBuffer);
+        byte[] calculatedChecksum = Arrays.copyOfRange(integrityMac.doFinal(), 0, checksumLen);
+        return calculatedChecksum;
+    }
+
+    /** Package private for testing */
+    @VisibleForTesting
+    static void validateChecksumOrThrow(
+            byte[] dataToAuthenticate, Mac integrityMac, byte[] integrityChecksum)
+            throws GeneralSecurityException {
+        // TODO: Make it package private and add test.
+        int checkSumLen = integrityChecksum.length;
+        byte[] calculatedChecksum =
+                calculateChecksum(dataToAuthenticate, integrityMac, checkSumLen);
+
+        if (!Arrays.equals(integrityChecksum, calculatedChecksum)) {
+            throw new GeneralSecurityException("Message authentication failed.");
+        }
+    }
+
+    /** Package private for testing */
+    @VisibleForTesting
+    static byte[] encrypt(
+            byte[] dataToEncrypt, Cipher encryptCipher, SecretKey eKey, byte[] iv, byte[] padding) {
+        int padLength = padding.length;
+        int paddedDataLength = dataToEncrypt.length + padLength + PAD_LEN_LEN;
+        ByteBuffer inputBuffer = ByteBuffer.allocate(paddedDataLength);
+        inputBuffer.put(dataToEncrypt).put(padding).put((byte) padLength);
+        inputBuffer.rewind();
+
+        try {
+            // Encrypt data.
+            ByteBuffer outputBuffer = ByteBuffer.allocate(paddedDataLength);
+            encryptCipher.init(Cipher.ENCRYPT_MODE, eKey, new IvParameterSpec(iv));
+            encryptCipher.doFinal(inputBuffer, outputBuffer);
+            return outputBuffer.array();
+        } catch (GeneralSecurityException e) {
+            throw new IllegalArgumentException("Fail to encrypt IKE message. ", e);
+        }
+    }
+
+    /** Package private for testing */
+    @VisibleForTesting
+    static byte[] decrypt(byte[] encryptedData, Cipher decryptCipher, SecretKey dKey, byte[] iv)
+            throws GeneralSecurityException {
+        // TODO: Make it package private and add test.
+        decryptCipher.init(Cipher.DECRYPT_MODE, dKey, new IvParameterSpec(iv));
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(encryptedData);
+        ByteBuffer outputBuffer = ByteBuffer.allocate(encryptedData.length);
+        decryptCipher.doFinal(inputBuffer, outputBuffer);
+
+        // Remove padding
+        outputBuffer.rewind();
+        int padLength = Byte.toUnsignedInt(outputBuffer.get(encryptedData.length - PAD_LEN_LEN));
+        byte[] decryptedData = new byte[encryptedData.length - padLength - PAD_LEN_LEN];
+
+        outputBuffer.get(decryptedData);
+        return decryptedData;
+    }
+
+    /** Package private for testing */
+    @VisibleForTesting
+    static byte[] calculatePadding(int dataToEncryptLength, int blockSize) {
+        // Sum of dataToEncryptLength, PAD_LEN_LEN and padLength should be aligned with block size.
+        int unpaddedLen = dataToEncryptLength + PAD_LEN_LEN;
+        int padLength = (unpaddedLen + blockSize - 1) / blockSize * blockSize - unpaddedLen;
+        byte[] padding = new byte[padLength];
+
+        // According to RFC 7296, "Padding MAY contain any value".
+        new SecureRandom().nextBytes(padding);
+
+        return padding;
+    }
+
+    /** Package private */
+    byte[] getUnencryptedData() {
+        return mUnencryptedData;
+    }
+
+    /** Package private */
+    int getLength() {
+        return (mIv.length + mEncryptedAndPaddedData.length + mIntegrityChecksum.length);
+    }
+
+    /** Package private */
+    byte[] encode() {
+        ByteBuffer buffer = ByteBuffer.allocate(getLength());
+        buffer.put(mIv).put(mEncryptedAndPaddedData).put(mIntegrityChecksum);
+        return buffer.array();
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeHeader.java b/src/java/com/android/ike/ikev2/message/IkeHeader.java
similarity index 75%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeHeader.java
rename to src/java/com/android/ike/ikev2/message/IkeHeader.java
index 7aa4fbc..c4f215c 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeHeader.java
+++ b/src/java/com/android/ike/ikev2/message/IkeHeader.java
@@ -14,17 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PayloadType;
+import static com.android.ike.ikev2.message.IkePayload.PayloadType;
 
 import android.annotation.IntDef;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.util.SparseArray;
 
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidMajorVersionException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidMajorVersionException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -46,8 +45,6 @@
     // Indicate whether this message is sent from the original IKE initiator
     private static final byte IKE_HEADER_FLAG_FROM_IKE_INITIATOR = (byte) 0x08;
 
-    private static final SparseArray<String> EXCHANGE_TYPE_TO_STRING;
-
     public static final int IKE_HEADER_LENGTH = 28;
 
     @Retention(RetentionPolicy.SOURCE)
@@ -64,14 +61,6 @@
     public static final int EXCHANGE_TYPE_CREATE_CHILD_SA = 36;
     public static final int EXCHANGE_TYPE_INFORMATIONAL = 37;
 
-    static {
-        EXCHANGE_TYPE_TO_STRING = new SparseArray<>();
-        EXCHANGE_TYPE_TO_STRING.put(EXCHANGE_TYPE_IKE_SA_INIT, "IKE INIT");
-        EXCHANGE_TYPE_TO_STRING.put(EXCHANGE_TYPE_IKE_AUTH, "IKE AUTH");
-        EXCHANGE_TYPE_TO_STRING.put(EXCHANGE_TYPE_CREATE_CHILD_SA, "Create Child");
-        EXCHANGE_TYPE_TO_STRING.put(EXCHANGE_TYPE_INFORMATIONAL, "Informational");
-    }
-
     public final long ikeInitiatorSpi;
     public final long ikeResponderSpi;
     @PayloadType public final int nextPayloadType;
@@ -131,7 +120,7 @@
      *
      * @param packet the raw byte array of the whole IKE message
      */
-    public IkeHeader(byte[] packet) throws IkeProtocolException {
+    public IkeHeader(byte[] packet) throws IkeException {
         if (packet.length <= IKE_HEADER_LENGTH) {
             throw new InvalidSyntaxException("IKE message is too short to contain a header");
         }
@@ -156,21 +145,6 @@
         mEncodedMessageLength = buffer.getInt();
     }
 
-    /** Packet private method to build header of an IKE fragemnt from current IKE header. */
-    IkeHeader makeSkfHeaderFromSkHeader() {
-        if (nextPayloadType != IkePayload.PAYLOAD_TYPE_SK) {
-            throw new IllegalArgumentException("Next payload type is not SK.");
-        }
-        return new IkeHeader(
-                ikeInitiatorSpi,
-                ikeResponderSpi,
-                IkePayload.PAYLOAD_TYPE_SKF,
-                exchangeType,
-                isResponseMsg,
-                fromIkeInitiator,
-                messageId);
-    }
-
     /*Package private*/
     @VisibleForTesting
     int getInboundMessageLength() {
@@ -181,8 +155,8 @@
         return mEncodedMessageLength;
     }
 
-    /** Validate major version of inbound IKE header. */
-    public void validateMajorVersion() throws IkeProtocolException {
+    /** Validate syntax and major version of inbound IKE header. */
+    public void checkInboundValidOrThrow(int packetLength) throws IkeException {
         if (majorVersion > 2) {
             // Receive higher version of protocol. Stop parsing.
             throw new InvalidMajorVersionException(majorVersion);
@@ -194,15 +168,6 @@
             // error.
             throw new InvalidSyntaxException("Major version is smaller than 2.");
         }
-    }
-
-    /**
-     * Validate syntax of inbound IKE header.
-     *
-     * <p>It MUST only be used for an inbound IKE header because we don't know the outbound message
-     * length before we encode it.
-     */
-    public void validateInboundHeader(int packetLength) throws IkeProtocolException {
         if (exchangeType < EXCHANGE_TYPE_IKE_SA_INIT
                 || exchangeType > EXCHANGE_TYPE_INFORMATIONAL) {
             throw new InvalidSyntaxException("Invalid IKE Exchange Type.");
@@ -231,14 +196,4 @@
 
         byteBuffer.put(flag).putInt(messageId).putInt(IKE_HEADER_LENGTH + encodedMessageBodyLen);
     }
-
-    /** Returns basic information for logging. */
-    public String getBasicInfoString() {
-        String exchangeStr = EXCHANGE_TYPE_TO_STRING.get(exchangeType);
-        if (exchangeStr == null) exchangeStr = "Unknown exchange (" + exchangeType + ")";
-
-        String reqOrResp = isResponseMsg ? "response" : "request";
-
-        return exchangeStr + " " + reqOrResp + " " + messageId;
-    }
 }
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayload.java b/src/java/com/android/ike/ikev2/message/IkeIdPayload.java
similarity index 76%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayload.java
rename to src/java/com/android/ike/ikev2/message/IkeIdPayload.java
index 12cc14a..49b8860 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeIdPayload.java
@@ -14,18 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeIdentification;
-import android.net.ipsec.ike.IkeIpv4AddrIdentification;
-import android.net.ipsec.ike.IkeIpv6AddrIdentification;
-import android.net.ipsec.ike.IkeKeyIdIdentification;
-import android.net.ipsec.ike.IkeRfc822AddrIdentification;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.IkeIdentification;
+import com.android.ike.ikev2.IkeIdentification.IkeIpv4AddrIdentification;
+import com.android.ike.ikev2.IkeIdentification.IkeIpv6AddrIdentification;
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.message.IkePayload.PayloadType;
 
 import java.nio.ByteBuffer;
 
@@ -54,10 +51,9 @@
      * @param payloadBody payload body in byte array.
      * @param isInitiator indicates whether this payload contains the ID of IKE initiator or IKE
      *     responder.
-     * @throws IkeProtocolException for decoding error.
+     * @throws IkeException for decoding error.
      */
-    IkeIdPayload(boolean critical, byte[] payloadBody, boolean isInitiator)
-            throws IkeProtocolException {
+    IkeIdPayload(boolean critical, byte[] payloadBody, boolean isInitiator) throws IkeException {
         super((isInitiator ? PAYLOAD_TYPE_ID_INITIATOR : PAYLOAD_TYPE_ID_RESPONDER), critical);
         // TODO: b/119791832 Add helper method for checking payload body length in superclass.
         if (payloadBody.length <= ID_HEADER_LEN) {
@@ -78,20 +74,18 @@
                 ikeId = new IkeIpv4AddrIdentification(idData);
                 return;
             case IkeIdentification.ID_TYPE_FQDN:
-                ikeId = new IkeFqdnIdentification(idData);
-                return;
+                // Fall through
             case IkeIdentification.ID_TYPE_RFC822_ADDR:
-                ikeId = new IkeRfc822AddrIdentification(idData);
-                return;
+                throw new UnsupportedOperationException("ID type is not supported currently.");
             case IkeIdentification.ID_TYPE_IPV6_ADDR:
                 ikeId = new IkeIpv6AddrIdentification(idData);
                 return;
-            case IkeIdentification.ID_TYPE_DER_ASN1_DN: // Fall through
+            case IkeIdentification.ID_TYPE_DER_ASN1_DN:
+                // Fall through
             case IkeIdentification.ID_TYPE_DER_ASN1_GN:
-                throw new UnsupportedOperationException("ID type is not supported currently.");
+                // Fall through
             case IkeIdentification.ID_TYPE_KEY_ID:
-                ikeId = new IkeKeyIdIdentification(idData);
-                return;
+                throw new UnsupportedOperationException("ID type is not supported currently.");
             default:
                 throw new AuthenticationFailedException("Unsupported ID type: " + idType);
         }
@@ -110,21 +104,6 @@
     }
 
     /**
-     * Get encoded ID payload body for building or validating an Auth Payload.
-     *
-     * @return the byte array of encoded ID payload body.
-     */
-    public byte[] getEncodedPayloadBody() {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(getPayloadLength() - GENERIC_HEADER_LENGTH);
-
-        byteBuffer
-                .put((byte) ikeId.idType)
-                .put(new byte[ID_HEADER_RESERVED_LEN])
-                .put(ikeId.getEncodedIdData());
-        return byteBuffer.array();
-    }
-
-    /**
      * Encode Identification Payload to ByteBuffer.
      *
      * @param nextPayload type of payload that follows this payload.
@@ -133,7 +112,10 @@
     @Override
     protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
         encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer.put(getEncodedPayloadBody());
+        byteBuffer
+                .put((byte) ikeId.idType)
+                .put(new byte[ID_HEADER_RESERVED_LEN])
+                .put(ikeId.getEncodedIdData());
     }
 
     /**
@@ -155,9 +137,9 @@
     public String getTypeString() {
         switch (payloadType) {
             case PAYLOAD_TYPE_ID_INITIATOR:
-                return "IDi";
+                return "Identification Initiator Payload";
             case PAYLOAD_TYPE_ID_RESPONDER:
-                return "IDr";
+                return "Identification Responder Payload";
             default:
                 // Won't reach here.
                 throw new IllegalArgumentException(
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayload.java b/src/java/com/android/ike/ikev2/message/IkeKePayload.java
similarity index 84%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeKePayload.java
rename to src/java/com/android/ike/ikev2/message/IkeKePayload.java
index 7389bf8..92e2238 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeKePayload.java
@@ -14,28 +14,26 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import android.annotation.Nullable;
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
 
-import com.android.internal.net.ipsec.ike.IkeDhParams;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.utils.BigIntegerUtils;
+import com.android.ike.ikev2.IkeDhParams;
+import com.android.ike.ikev2.SaProposal;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.utils.BigIntegerUtils;
 
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
 import java.security.GeneralSecurityException;
 import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
 import java.security.KeyFactory;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
 import java.security.NoSuchAlgorithmException;
 import java.security.ProviderException;
 import java.security.SecureRandom;
-import java.security.spec.InvalidKeySpecException;
 
 import javax.crypto.KeyAgreement;
 import javax.crypto.interfaces.DHPrivateKey;
@@ -77,8 +75,8 @@
 
     /**
      * localPrivateKey caches the locally generated private key when building an outbound KE
-     * payload. It will not be sent out. It is only used to calculate DH shared key when IKE library
-     * receives a public key from the remote server.
+     * payload. It will not be sent out. It is only used to calculate DH shared
+     * key when IKE library receives a public key from the remote server.
      *
      * <p>localPrivateKey of a inbound payload will be set to null. Caller MUST ensure its an
      * outbound payload before using localPrivateKey.
@@ -91,11 +89,11 @@
      * @param critical indicates if this payload is critical. Ignored in supported payload as
      *     instructed by the RFC 7296.
      * @param payloadBody payload body in byte array
-     * @throws IkeProtocolException if there is any error
+     * @throws IkeException if there is any error
      * @see <a href="https://tools.ietf.org/html/rfc7296#page-76">RFC 7296, Internet Key Exchange
      *     Protocol Version 2 (IKEv2), Critical.
      */
-    IkeKePayload(boolean critical, byte[] payloadBody) throws IkeProtocolException {
+    IkeKePayload(boolean critical, byte[] payloadBody) throws IkeException {
         super(PAYLOAD_TYPE_KE, critical);
 
         isOutbound = false;
@@ -225,38 +223,29 @@
      *
      * @param privateKeySpec contains the local private key, DH prime and DH base generator.
      * @param remotePublicKey the public key from remote server.
-     * @throws GeneralSecurityException if the remote public key is invalid.
+     * @throws GeneralSecurityException for security-related exception.
      */
     public static byte[] getSharedKey(DHPrivateKeySpec privateKeySpec, byte[] remotePublicKey)
             throws GeneralSecurityException {
-        KeyAgreement dhKeyAgreement;
-        KeyFactory dhKeyFactory;
-        try {
-            // Apply local private key.
-            dhKeyAgreement =
-                    KeyAgreement.getInstance(
-                            KEY_EXCHANGE_ALGORITHM, IkeMessage.getSecurityProvider());
-            dhKeyFactory =
-                    KeyFactory.getInstance(
-                            KEY_EXCHANGE_ALGORITHM, IkeMessage.getSecurityProvider());
-            DHPrivateKey privateKey = (DHPrivateKey) dhKeyFactory.generatePrivate(privateKeySpec);
-            dhKeyAgreement.init(privateKey);
-        } catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException e) {
-            throw new IllegalArgumentException("Failed to generate DH private key", e);
-        }
-
-        // Build public key.
         BigInteger publicKeyValue = BigIntegerUtils.unsignedByteArrayToBigInteger(remotePublicKey);
         BigInteger primeValue = privateKeySpec.getP();
+        // TODO: Add recipient test of remotePublicKey, as instructed by RFC6989 section 2.1
+
         BigInteger baseGenValue = privateKeySpec.getG();
+
         DHPublicKeySpec publicKeySpec =
                 new DHPublicKeySpec(publicKeyValue, primeValue, baseGenValue);
-
-        // Validate and apply public key. Validation includes range check as instructed by RFC6989
-        // section 2.1
+        KeyFactory dhKeyFactory =
+                KeyFactory.getInstance(KEY_EXCHANGE_ALGORITHM, IkeMessage.getSecurityProvider());
         DHPublicKey publicKey = (DHPublicKey) dhKeyFactory.generatePublic(publicKeySpec);
+        DHPrivateKey privateKey = (DHPrivateKey) dhKeyFactory.generatePrivate(privateKeySpec);
 
-        dhKeyAgreement.doPhase(publicKey, true /* Last phase */);
+        // Calculate shared secret
+        KeyAgreement dhKeyAgreement =
+                KeyAgreement.getInstance(KEY_EXCHANGE_ALGORITHM, IkeMessage.getSecurityProvider());
+        dhKeyAgreement.init(privateKey);
+        dhKeyAgreement.doPhase(publicKey, true/** Last phase */);
+
         return dhKeyAgreement.generateSecret();
     }
 
@@ -267,6 +256,6 @@
      */
     @Override
     public String getTypeString() {
-        return "KE";
+        return "KE Payload";
     }
 }
diff --git a/src/java/com/android/ike/ikev2/message/IkeMessage.java b/src/java/com/android/ike/ikev2/message/IkeMessage.java
new file mode 100644
index 0000000..5b63ee7
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeMessage.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static com.android.ike.ikev2.message.IkePayload.PayloadType;
+
+import android.annotation.IntDef;
+import android.util.Pair;
+
+import com.android.ike.ikev2.IkeSessionOptions;
+import com.android.ike.ikev2.SaRecord.IkeSaRecord;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.exceptions.UnsupportedCriticalPayloadException;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+import java.security.Provider;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+
+/**
+ * IkeMessage represents an IKE message.
+ *
+ * <p>It contains all attributes and provides methods for encoding, decoding, encrypting and
+ * decrypting.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class IkeMessage {
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        MESSAGE_TYPE_IKE_INIT_RESP,
+        MESSAGE_TYPE_IKE_AUTH_RESP,
+        MESSAGE_TYPE_DELETE_IKE_REQ,
+        MESSAGE_TYPE_DELETE_IKE_RESP,
+        MESSAGE_TYPE_REKEY_IKE_REQ,
+        MESSAGE_TYPE_REKEY_IKE_RESP,
+        MESSAGE_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD,
+        MESSAGE_TYPE_INVALID_MAJOR_VERSION,
+        MESSAGE_TYPE_INVALID_SYNTAX
+    })
+    public @interface MessageType {}
+
+    // Message type for decoded IkeMessage.
+    public static final int PROCEDURE_TYPE_BASE = 0;
+
+    public static final int MESSAGE_TYPE_IKE_INIT_RESP = PROCEDURE_TYPE_BASE + 1;
+    public static final int MESSAGE_TYPE_IKE_AUTH_RESP = PROCEDURE_TYPE_BASE + 2;
+    public static final int MESSAGE_TYPE_DELETE_IKE_REQ = PROCEDURE_TYPE_BASE + 3;
+    public static final int MESSAGE_TYPE_DELETE_IKE_RESP = PROCEDURE_TYPE_BASE + 4;
+    public static final int MESSAGE_TYPE_REKEY_IKE_REQ = PROCEDURE_TYPE_BASE + 5;
+    public static final int MESSAGE_TYPE_REKEY_IKE_RESP = PROCEDURE_TYPE_BASE + 6;
+
+    public static final int NOTIFICATION_TYPE_BASE = PROCEDURE_TYPE_BASE + 100;
+    public static final int MESSAGE_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD =
+            NOTIFICATION_TYPE_BASE + IkeNotifyPayload.NOTIFY_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
+    public static final int MESSAGE_TYPE_INVALID_MAJOR_VERSION =
+            NOTIFICATION_TYPE_BASE + IkeNotifyPayload.NOTIFY_TYPE_INVALID_MAJOR_VERSION;
+    public static final int MESSAGE_TYPE_INVALID_SYNTAX =
+            NOTIFICATION_TYPE_BASE + IkeNotifyPayload.NOTIFY_TYPE_INVALID_SYNTAX;
+
+    private static IIkeMessageHelper sIkeMessageHelper = new IkeMessageHelper();
+    // Currently use Bouncy Castle as crypto security provider
+    static final Provider SECURITY_PROVIDER = new BouncyCastleProvider();
+
+    public final IkeHeader ikeHeader;
+    public final List<IkePayload> ikePayloadList;
+    /**
+     * Conctruct an instance of IkeMessage. It is called by decode or for building outbound message.
+     *
+     * @param header the header of this IKE message
+     * @param payloadList the list of decoded IKE payloads in this IKE message
+     */
+    public IkeMessage(IkeHeader header, List<IkePayload> payloadList) {
+        ikeHeader = header;
+        ikePayloadList = payloadList;
+    }
+
+    /**
+     * Get security provider for IKE library
+     *
+     * <p>Use BouncyCastleProvider as the default security provider.
+     *
+     * @return the security provider of IKE library.
+     */
+    public static Provider getSecurityProvider() {
+        // TODO: Move this getter out of IKE message package since not only this package uses it.
+        return SECURITY_PROVIDER;
+    }
+
+    /**
+     * Decode unencrypted IKE message body and create an instance of IkeMessage.
+     *
+     * <p>This method catches all RuntimeException during decoding incoming IKE packet.
+     *
+     * @param header the IKE header that is decoded but not validated.
+     * @param inputPacket the byte array contains the whole IKE message.
+     * @return the IkeMessage instance.
+     * @throws IkeException if there is any protocol error.
+     */
+    public static IkeMessage decode(IkeHeader header, byte[] inputPacket) throws IkeException {
+        return sIkeMessageHelper.decode(header, inputPacket);
+    }
+
+    /**
+     * Decrypt and decode encrypted IKE message body and create an instance of IkeMessage.
+     *
+     * @param ikeSessionOptions IkeSessionOptions that contains cryptographic algorithm set.
+     * @param ikeSaRecord ikeSaRecord where this packet is sent on.
+     * @param ikeHeader header of IKE packet.
+     * @param packet IKE packet as a byte array.
+     * @return decoded IKE message.
+     * @throws IkeException for decoding errors.
+     * @throws GeneralSecurityException if there is any error during integrity check or decryption.
+     */
+    public static IkeMessage decode(
+            IkeSessionOptions ikeSessionOptions,
+            IkeSaRecord ikeSaRecord,
+            IkeHeader ikeHeader,
+            byte[] packet)
+            throws IkeException, GeneralSecurityException {
+        return sIkeMessageHelper.decode(ikeSessionOptions, ikeSaRecord, ikeHeader, packet);
+    }
+
+    private static List<IkePayload> decodePayloadList(
+            @PayloadType int firstPayloadType, boolean isResp, byte[] unencryptedPayloads)
+            throws IkeException {
+        ByteBuffer inputBuffer = ByteBuffer.wrap(unencryptedPayloads);
+        int currentPayloadType = firstPayloadType;
+        // For supported payload
+        List<IkePayload> supportedPayloadList = new LinkedList<>();
+        // For unsupported critical payload
+        List<Integer> unsupportedCriticalPayloadList = new LinkedList<>();
+
+        while (currentPayloadType != IkePayload.PAYLOAD_TYPE_NO_NEXT) {
+            Pair<IkePayload, Integer> pair =
+                    IkePayloadFactory.getIkePayload(currentPayloadType, isResp, inputBuffer);
+            IkePayload payload = pair.first;
+
+            if (!(payload instanceof IkeUnsupportedPayload)) {
+                supportedPayloadList.add(payload);
+            } else if (payload.isCritical) {
+                unsupportedCriticalPayloadList.add(payload.payloadType);
+            }
+            // Simply ignore unsupported uncritical payload.
+
+            currentPayloadType = pair.second;
+        }
+
+        if (inputBuffer.remaining() > 0) {
+            throw new InvalidSyntaxException(
+                    "Malformed IKE Payload: Unexpected bytes at the end of packet.");
+        }
+
+        if (unsupportedCriticalPayloadList.size() > 0) {
+            throw new UnsupportedCriticalPayloadException(unsupportedCriticalPayloadList);
+        }
+        return supportedPayloadList;
+    }
+
+    /**
+     * Encode unencrypted IKE message.
+     *
+     * @return encoded IKE message in byte array.
+     */
+    public byte[] encode() {
+        return sIkeMessageHelper.encode(this);
+    }
+
+    /**
+     * Encrypt and encode packet.
+     *
+     * @param ikeSessionOptions IkeSessionOptions that contains cryptographic algorithm set.
+     * @param ikeSaRecord ikeSaRecord where this packet is sent on.
+     * @return encoded IKE message in byte array.
+     */
+    public byte[] encode(IkeSessionOptions ikeSessionOptions, IkeSaRecord ikeSaRecord) {
+        return sIkeMessageHelper.encode(ikeSessionOptions, ikeSaRecord, this);
+    }
+
+    /**
+     * Encode all payloads to a byte array.
+     *
+     * @return byte array contains all encoded payloads
+     */
+    private byte[] encodePayloads() {
+        if (ikePayloadList.isEmpty()) {
+            return new byte[0];
+        }
+
+        int payloadLengthSum = 0;
+        for (IkePayload payload : ikePayloadList) {
+            payloadLengthSum += payload.getPayloadLength();
+        }
+
+        ByteBuffer byteBuffer = ByteBuffer.allocate(payloadLengthSum);
+
+        for (int i = 0; i < ikePayloadList.size() - 1; i++) {
+            ikePayloadList
+                    .get(i)
+                    .encodeToByteBuffer(ikePayloadList.get(i + 1).payloadType, byteBuffer);
+        }
+        ikePayloadList
+                .get(ikePayloadList.size() - 1)
+                .encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, byteBuffer);
+
+        return byteBuffer.array();
+    }
+
+    /** Package */
+    @VisibleForTesting
+    byte[] attachEncodedHeader(byte[] encodedIkeBody) {
+        ByteBuffer outputBuffer =
+                ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH + encodedIkeBody.length);
+        ikeHeader.encodeToByteBuffer(outputBuffer, encodedIkeBody.length);
+        outputBuffer.put(encodedIkeBody);
+        return outputBuffer.array();
+    }
+
+    @MessageType
+    public int getMessageType() {
+        return sIkeMessageHelper.getMessageType(this);
+    }
+
+    /**
+     * IIkeMessageHelper provides interface for decoding, encoding and processing IKE packet.
+     *
+     * <p>IkeMessageHelper exists so that the interface is injectable for testing.
+     */
+    @VisibleForTesting
+    public interface IIkeMessageHelper {
+        /**
+         * Check message type of decoded IKE message.
+         *
+         * @param ikeMessage IKE message to be checked.
+         * @return message type.
+         */
+        @MessageType
+        int getMessageType(IkeMessage ikeMessage);
+
+        /**
+         * Encode IKE message.
+         *
+         * @param ikeMessage message need to be encoded.
+         * @return encoded IKE message in byte array.
+         */
+        byte[] encode(IkeMessage ikeMessage);
+
+        /**
+         * Encrypt and encode IKE message.
+         *
+         * @param ikeSessionOptions ikeSessionOptions that contains cryptographic algorithm set.
+         * @param ikeSaRecord ikeSaRecord where this packet is sent on.
+         * @param ikeMessage message need to be encoded.
+         * @return encoded IKE message in byte array.
+         */
+        byte[] encode(
+                IkeSessionOptions ikeSessionOptions,
+                IkeSaRecord ikeSaRecord,
+                IkeMessage ikeMessage);
+
+        /**
+         * Decode unencrypted packet.
+         *
+         * @param ikeHeader header of IKE packet.
+         * @param packet IKE packet as a byte array.
+         * @return decoded IKE message.
+         * @throws IkeException for decoding errors.
+         */
+        IkeMessage decode(IkeHeader ikeHeader, byte[] packet) throws IkeException;
+
+        /**
+         * Decrypt and decode packet.
+         *
+         * @param ikeSessionOptions ikeSessionOptions that contains cryptographic algorithm set.
+         * @param ikeSaRecord ikeSaRecord where this packet is sent on.
+         * @param ikeHeader header of IKE packet.
+         * @param packet IKE packet as a byte array.
+         * @return decoded IKE message.
+         * @throws IkeException for decoding errors.
+         */
+        IkeMessage decode(
+                IkeSessionOptions ikeSessionOptions,
+                IkeSaRecord ikeSaRecord,
+                IkeHeader ikeHeader,
+                byte[] packet)
+                throws IkeException, GeneralSecurityException;
+    }
+
+    /** IkeMessageHelper provides methods for decoding, encoding and processing IKE packet. */
+    public static final class IkeMessageHelper implements IIkeMessageHelper {
+        @Override
+        public byte[] encode(IkeMessage ikeMessage) {
+            byte[] encodedIkeBody = ikeMessage.encodePayloads();
+            return ikeMessage.attachEncodedHeader(encodedIkeBody);
+        }
+
+        @Override
+        public byte[] encode(
+                IkeSessionOptions ikeSessionOptions,
+                IkeSaRecord ikeSaRecord,
+                IkeMessage ikeMessage) {
+            // TODO: Extract crypto attributes and call encrypt()
+            return null;
+        }
+
+        //TODO: Create and use a container class for crypto algorithms and keys.
+        private byte[] encryptAndEncode(
+                IkeHeader ikeHeader,
+                @PayloadType int firstPayload,
+                byte[] unencryptedPayloads,
+                Mac integrityMac,
+                int checksumLen,
+                Cipher encryptCipher,
+                SecretKey eKey) {
+            IkeSkPayload skPayload =
+                    new IkeSkPayload(
+                            ikeHeader,
+                            firstPayload,
+                            unencryptedPayloads,
+                            integrityMac,
+                            checksumLen,
+                            encryptCipher,
+                            eKey);
+
+            ByteBuffer outputBuffer =
+                    ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH + skPayload.getPayloadLength());
+            ikeHeader.encodeToByteBuffer(outputBuffer, skPayload.getPayloadLength());
+            skPayload.encodeToByteBuffer(firstPayload, outputBuffer);
+
+            return outputBuffer.array();
+        }
+
+        @Override
+        public IkeMessage decode(IkeHeader header, byte[] inputPacket) throws IkeException {
+            header.checkInboundValidOrThrow(inputPacket.length);
+
+            byte[] unencryptedPayloads =
+                    Arrays.copyOfRange(
+                            inputPacket, IkeHeader.IKE_HEADER_LENGTH, inputPacket.length);
+
+            try {
+                List<IkePayload> supportedPayloadList =
+                        decodePayloadList(
+                                header.nextPayloadType, header.isResponseMsg, unencryptedPayloads);
+                return new IkeMessage(header, supportedPayloadList);
+            } catch (NegativeArraySizeException | BufferUnderflowException e) {
+                // Invalid length error when parsing payload bodies.
+                throw new InvalidSyntaxException("Malformed IKE Payload");
+            }
+        }
+
+        @Override
+        public IkeMessage decode(
+                IkeSessionOptions ikeSessionOptions,
+                IkeSaRecord ikeSaRecord,
+                IkeHeader ikeHeader,
+                byte[] packet)
+                throws IkeException, GeneralSecurityException {
+            // TODO: Extract crypto params and call private decode method.
+            return null;
+        }
+
+        private IkeMessage decode(
+                IkeHeader header,
+                byte[] inputPacket,
+                Mac integrityMac,
+                int checksumLen,
+                Cipher decryptCipher,
+                SecretKey dKey)
+                throws IkeException, GeneralSecurityException {
+
+            header.checkInboundValidOrThrow(inputPacket.length);
+
+            if (header.nextPayloadType != IkePayload.PAYLOAD_TYPE_SK) {
+                // TODO: b/123372339 Handle message containing unprotected payloads.
+                throw new UnsupportedOperationException("Message contains unprotected payloads");
+            }
+
+            try {
+                Pair<IkeSkPayload, Integer> pair =
+                        IkePayloadFactory.getIkeSkPayload(
+                                inputPacket, integrityMac, checksumLen, decryptCipher, dKey);
+                IkeSkPayload skPayload = pair.first;
+                int firstPayloadType = pair.second;
+
+                List<IkePayload> supportedPayloadList =
+                        decodePayloadList(
+                                firstPayloadType,
+                                header.isResponseMsg,
+                                skPayload.getUnencryptedPayloads());
+
+                return new IkeMessage(header, supportedPayloadList);
+            } catch (NegativeArraySizeException | BufferUnderflowException e) {
+                // Invalid length error when parsing payload bodies.
+                throw new InvalidSyntaxException("Malformed IKE Payload");
+            }
+        }
+
+        @Override
+        @MessageType
+        public int getMessageType(IkeMessage ikeMessage) {
+            // TODO: Implement it.
+            return 0;
+        }
+    }
+
+    /**
+     * For setting mocked IIkeMessageHelper for testing
+     *
+     * @param helper the mocked IIkeMessageHelper
+     */
+    public static void setIkeMessageHelper(IIkeMessageHelper helper) {
+        sIkeMessageHelper = helper;
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayload.java b/src/java/com/android/ike/ikev2/message/IkeNoncePayload.java
similarity index 93%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayload.java
rename to src/java/com/android/ike/ikev2/message/IkeNoncePayload.java
index 70fc824..3792e93 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeNoncePayload.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
 
 import java.nio.ByteBuffer;
 import java.security.SecureRandom;
@@ -53,7 +52,7 @@
      * @param critical indicates if it is a critical payload.
      * @param payloadBody the nonce data
      */
-    IkeNoncePayload(boolean critical, byte[] payloadBody) throws IkeProtocolException {
+    IkeNoncePayload(boolean critical, byte[] payloadBody) throws IkeException {
         super(PAYLOAD_TYPE_NONCE, critical);
         if (payloadBody.length < MIN_NONCE_LEN || payloadBody.length > MAX_NONCE_LEN) {
             throw new InvalidSyntaxException(
@@ -103,6 +102,6 @@
      */
     @Override
     public String getTypeString() {
-        return "Nonce";
+        return "Nonce Payload";
     }
 }
diff --git a/src/java/com/android/ike/ikev2/message/IkeNotifyPayload.java b/src/java/com/android/ike/ikev2/message/IkeNotifyPayload.java
new file mode 100644
index 0000000..ee6fe47
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeNotifyPayload.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import android.annotation.IntDef;
+import android.util.ArraySet;
+
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Set;
+
+/**
+ * IkeNotifyPayload represents a Notify Payload.
+ *
+ * <p>As instructed by RFC 7296, for IKE SA concerned Notify Payload, Protocol ID and SPI Size must
+ * be zero. Unrecognized notify message type must be ignored but should be logged.
+ *
+ * <p>Critical bit for this payload must be ignored in received packet and must not be set in
+ * outbound packet.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296">RFC 7296, Internet Key Exchange Protocol
+ *     Version 2 (IKEv2)</a>
+ */
+public final class IkeNotifyPayload extends IkePayload {
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({
+        NOTIFY_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD,
+        NOTIFY_TYPE_INVALID_MAJOR_VERSION,
+        NOTIFY_TYPE_INVALID_SYNTAX,
+        NOTIFY_TYPE_NO_PROPOSAL_CHOSEN,
+        NOTIFY_TYPE_INVALID_SELECTORS,
+        NOTIFY_TYPE_CHILD_SA_NOT_FOUND,
+        NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP,
+        NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP,
+        NOTIFY_TYPE_REKEY_SA
+    })
+    public @interface NotifyType {}
+
+    public static final int NOTIFY_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD = 1;
+    public static final int NOTIFY_TYPE_INVALID_MAJOR_VERSION = 5;
+    public static final int NOTIFY_TYPE_INVALID_SYNTAX = 7;
+    public static final int NOTIFY_TYPE_NO_PROPOSAL_CHOSEN = 14;
+    public static final int NOTIFY_TYPE_AUTHENTICATION_FAILED = 24;
+    public static final int NOTIFY_TYPE_INVALID_SELECTORS = 39;
+    public static final int NOTIFY_TYPE_CHILD_SA_NOT_FOUND = 44;
+
+    public static final int NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP = 16388;
+    public static final int NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP = 16389;
+    public static final int NOTIFY_TYPE_REKEY_SA = 16393;
+    // TODO: List all supported notify types.
+
+    private static final int NOTIFY_HEADER_LEN = 4;
+
+    private static final String NAT_DETECTION_DIGEST_ALGORITHM = "SHA-1";
+
+    private static final Set<Integer> VALID_NOTIFY_TYPES_FOR_CHILD_SA;
+
+    static {
+        VALID_NOTIFY_TYPES_FOR_CHILD_SA = new ArraySet<>();
+        VALID_NOTIFY_TYPES_FOR_CHILD_SA.add(NOTIFY_TYPE_INVALID_SELECTORS);
+        VALID_NOTIFY_TYPES_FOR_CHILD_SA.add(NOTIFY_TYPE_CHILD_SA_NOT_FOUND);
+        VALID_NOTIFY_TYPES_FOR_CHILD_SA.add(NOTIFY_TYPE_REKEY_SA);
+    }
+
+    public final int protocolId;
+    public final byte spiSize;
+    public final int notifyType;
+    public final int spi;
+    public final byte[] notifyData;
+
+    /**
+     * Construct an instance of IkeNotifyPayload in the context of IkePayloadFactory
+     *
+     * @param critical indicates if this payload is critical. Ignored in supported payload as
+     *     instructed by the RFC 7296.
+     * @param payloadBody payload body in byte array
+     * @throws IkeException if there is any error
+     */
+    IkeNotifyPayload(boolean isCritical, byte[] payloadBody) throws IkeException {
+        super(PAYLOAD_TYPE_NOTIFY, isCritical);
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
+
+        protocolId = Byte.toUnsignedInt(inputBuffer.get());
+        spiSize = inputBuffer.get();
+        notifyType = Short.toUnsignedInt(inputBuffer.getShort());
+
+        // Validate syntax of spiSize, protocolId and notifyType.
+        // Reference: <https://tools.ietf.org/html/rfc7296#page-100>
+        if (spiSize == SPI_LEN_IPSEC) {
+            // For message concerning existing Child SA
+            validateNotifyPayloadForExistingChildSa();
+            spi = inputBuffer.getInt();
+
+        } else if (spiSize == SPI_LEN_NOT_INCLUDED) {
+            // For message concerning IKE SA or for new Child SA that to be negotiated.
+            validateNotifyPayloadForIkeAndNewChild();
+            spi = SPI_NOT_INCLUDED;
+
+        } else {
+            throw new InvalidSyntaxException("Invalid SPI Size: " + spiSize);
+        }
+
+        notifyData = new byte[payloadBody.length - NOTIFY_HEADER_LEN];
+        inputBuffer.get(notifyData);
+    }
+
+    private void validateNotifyPayloadForExistingChildSa() throws InvalidSyntaxException {
+        if (protocolId != PROTOCOL_ID_AH && protocolId != PROTOCOL_ID_ESP) {
+            throw new InvalidSyntaxException(
+                    "Expected Procotol ID AH(2) or ESP(3): Protocol ID is " + protocolId);
+        }
+
+        if (!VALID_NOTIFY_TYPES_FOR_CHILD_SA.contains(notifyType)) {
+            throw new InvalidSyntaxException(
+                    "Expected Notify Type for existing Child SA: Notify Type is " + notifyType);
+        }
+    }
+
+    private void validateNotifyPayloadForIkeAndNewChild() throws InvalidSyntaxException {
+        if (protocolId != PROTOCOL_ID_UNSET) {
+            throw new InvalidSyntaxException(
+                    "Expected Procotol ID unset: Protocol ID is " + protocolId);
+        }
+
+        if (notifyType == NOTIFY_TYPE_INVALID_SELECTORS
+                || notifyType == NOTIFY_TYPE_CHILD_SA_NOT_FOUND) {
+            throw new InvalidSyntaxException(
+                    "Expected Notify Type concerning IKE SA or new Child SA under negotiation"
+                            + ": Notify Type is "
+                            + notifyType);
+        }
+    }
+
+    /**
+     * Generate NAT DETECTION notification data.
+     *
+     * <p>This method calculates NAT DETECTION notification data which is a SHA-1 digest of the IKE
+     * initiator's SPI, IKE responder's SPI, IP address and port. Source address and port should be
+     * used for generating NAT_DETECTION_SOURCE_IP data. Destination address and port should be used
+     * for generating NAT_DETECTION_DESTINATION_IP data.
+     *
+     * @param initiatorIkeSpi the SPI of IKE initiator
+     * @param responderIkeSpi the SPI of IKE responder
+     * @param ipAddress the IP address
+     * @param port the port
+     * @return the generated NAT DETECTION notification data as a byte array.
+     * @throws NoSuchAlgorithmException when "SHA-1" is not supported by the security provider.
+     */
+    public static byte[] generateNatDetectionData(
+            long initiatorIkeSpi, long responderIkeSpi, InetAddress ipAddress, int port)
+            throws NoSuchAlgorithmException {
+        byte[] rawIpAddr = ipAddress.getAddress();
+
+        ByteBuffer byteBuffer =
+                ByteBuffer.allocate(2 * SPI_LEN_IKE + rawIpAddr.length + IP_PORT_LEN);
+        byteBuffer
+                .putLong(initiatorIkeSpi)
+                .putLong(responderIkeSpi)
+                .put(rawIpAddr)
+                .putShort((short) port);
+
+        MessageDigest natDetectionDataDigest =
+                MessageDigest.getInstance(
+                        NAT_DETECTION_DIGEST_ALGORITHM, IkeMessage.getSecurityProvider());
+        return natDetectionDataDigest.digest(byteBuffer.array());
+    }
+
+    /**
+     * Encode Notify payload to ByteBuffer.
+     *
+     * @param nextPayload type of payload that follows this payload.
+     * @param byteBuffer destination ByteBuffer that stores encoded payload.
+     */
+    @Override
+    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
+        byteBuffer.put((byte) protocolId).put(spiSize).putShort((short) notifyType);
+        if (spiSize == SPI_LEN_IPSEC) {
+            byteBuffer.putInt(spi);
+        }
+        byteBuffer.put(notifyData);
+    }
+
+    /**
+     * Get entire payload length.
+     *
+     * @return entire payload length.
+     */
+    @Override
+    protected int getPayloadLength() {
+        return GENERIC_HEADER_LENGTH + NOTIFY_HEADER_LEN + spiSize + notifyData.length;
+    }
+
+    protected IkeNotifyPayload(
+            @ProtocolId int protocolId,
+            byte spiSize,
+            int spi,
+            @NotifyType int notifyType,
+            byte[] notifyData) {
+        super(PAYLOAD_TYPE_NOTIFY, false);
+        this.protocolId = protocolId;
+        this.spiSize = spiSize;
+        this.spi = spi;
+        this.notifyType = notifyType;
+        this.notifyData = notifyData;
+    }
+
+    /**
+     * Construct IkeNotifyPayload concerning either an IKE SA or Child SA that is going to be
+     * negotiated.
+     *
+     * @param notifyType the notify type concerning IKE SA
+     * @param notifytData status or error data transmitted. Values for this field are notify type
+     *     specific.
+     */
+    public IkeNotifyPayload(@NotifyType int notifyType, byte[] notifyData) {
+        this(PROTOCOL_ID_UNSET, SPI_LEN_NOT_INCLUDED, SPI_NOT_INCLUDED, notifyType, notifyData);
+        try {
+            validateNotifyPayloadForIkeAndNewChild();
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Construct IkeNotifyPayload concerning existing Child SA
+     *
+     * @param notifyType the notify type concerning Child SA
+     * @param notifytData status or error data transmitted. Values for this field are notify type
+     *     specific.
+     */
+    public IkeNotifyPayload(
+            @ProtocolId int protocolId, int spi, @NotifyType int notifyType, byte[] notifyData) {
+        this(protocolId, SPI_LEN_IPSEC, spi, notifyType, notifyData);
+        try {
+            validateNotifyPayloadForExistingChildSa();
+        } catch (InvalidSyntaxException e) {
+            throw new IllegalArgumentException(e);
+        }
+    }
+
+    /**
+     * Return the payload type as a String.
+     *
+     * @return the payload type as a String.
+     */
+    @Override
+    public String getTypeString() {
+        return "Notify Payload";
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkePayload.java b/src/java/com/android/ike/ikev2/message/IkePayload.java
similarity index 63%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkePayload.java
rename to src/java/com/android/ike/ikev2/message/IkePayload.java
index 9ea54c1..2474bb6 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkePayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkePayload.java
@@ -14,16 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import android.annotation.IntDef;
-import android.util.SparseArray;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
 
 /**
  * IkePayload is an abstract class that represents the common information for all IKE payload types.
@@ -51,7 +48,6 @@
         PAYLOAD_TYPE_SA,
         PAYLOAD_TYPE_KE,
         PAYLOAD_TYPE_CERT,
-        PAYLOAD_TYPE_CERT_REQUEST,
         PAYLOAD_TYPE_AUTH,
         PAYLOAD_TYPE_ID_INITIATOR,
         PAYLOAD_TYPE_ID_RESPONDER,
@@ -61,10 +57,7 @@
         PAYLOAD_TYPE_VENDOR,
         PAYLOAD_TYPE_TS_INITIATOR,
         PAYLOAD_TYPE_TS_RESPONDER,
-        PAYLOAD_TYPE_SK,
-        PAYLOAD_TYPE_CP,
-        PAYLOAD_TYPE_EAP,
-        PAYLOAD_TYPE_SKF
+        PAYLOAD_TYPE_SK
     })
     public @interface PayloadType {}
 
@@ -78,10 +71,8 @@
     public static final int PAYLOAD_TYPE_ID_INITIATOR = 35;
     /** Identification Payload for IKE SA Responder */
     public static final int PAYLOAD_TYPE_ID_RESPONDER = 36;
-    /** Certificate Payload */
+    /** Certification Payload */
     public static final int PAYLOAD_TYPE_CERT = 37;
-    /** Certificate Request Payload */
-    public static final int PAYLOAD_TYPE_CERT_REQUEST = 38;
     /** Authentication Payload */
     public static final int PAYLOAD_TYPE_AUTH = 39;
     /** Nonce Payload */
@@ -98,12 +89,6 @@
     public static final int PAYLOAD_TYPE_TS_RESPONDER = 45;
     /** Encrypted and Authenticated Payload */
     public static final int PAYLOAD_TYPE_SK = 46;
-    /** Configuration Payload */
-    public static final int PAYLOAD_TYPE_CP = 47;
-    /** EAP Payload */
-    public static final int PAYLOAD_TYPE_EAP = 48;
-    /** Encrypted and Authenticated Fragment */
-    public static final int PAYLOAD_TYPE_SKF = 53;
 
     // TODO: List all payload types.
 
@@ -121,16 +106,6 @@
     public static final int PROTOCOL_ID_AH = 2;
     public static final int PROTOCOL_ID_ESP = 3;
 
-    private static final SparseArray<String> PROTOCOL_TO_STR;
-
-    static {
-        PROTOCOL_TO_STR = new SparseArray<>();
-        PROTOCOL_TO_STR.put(PROTOCOL_ID_UNSET, "Protocol Unset");
-        PROTOCOL_TO_STR.put(PROTOCOL_ID_IKE, "IKE");
-        PROTOCOL_TO_STR.put(PROTOCOL_ID_AH, "AH");
-        PROTOCOL_TO_STR.put(PROTOCOL_ID_ESP, "ESP");
-    }
-
     public static final byte SPI_LEN_NOT_INCLUDED = 0;
     public static final byte SPI_LEN_IPSEC = 4;
     public static final byte SPI_LEN_IKE = 8;
@@ -159,56 +134,6 @@
     }
 
     /**
-     * A helper method to quickly obtain payloads with the input payload type in the provided
-     * payload list.
-     *
-     * <p>This method will not check if this payload type can be repeatable in an IKE message
-     * because it does not know the context of the provided payload list. Caller should call this
-     * method if they are expecting more than one payloads in the list.
-     *
-     * @param payloadType the payloadType to look for.
-     * @param payloadClass the class of the desired payload.
-     * @param searchList the payload list to do the search.
-     * @return a list of IkePayloads with the payloadType.
-     */
-    public static <T extends IkePayload> List<T> getPayloadListForTypeInProvidedList(
-            @IkePayload.PayloadType int payloadType,
-            Class<T> payloadClass,
-            List<IkePayload> searchList) {
-        List<T> payloadList = new LinkedList<>();
-
-        for (IkePayload payload : searchList) {
-            if (payloadType == payload.payloadType) {
-                payloadList.add(payloadClass.cast(payload));
-            }
-        }
-
-        return payloadList;
-    }
-
-    /**
-     * A helper method to quickly obtain the payload with the input payload type in the provided
-     * payload list.
-     *
-     * <p>This method will not check if this payload type can be repeatable in an IKE message
-     * because it does not know the context of the provided payload list. Caller should call this
-     * method if they are expecting no more than one payloads in the list.
-     *
-     * @param payloadType the payloadType to look for.
-     * @param payloadClass the class of the desired payload.
-     * @param searchList the payload list to do the search.
-     * @return the IkePayload with the payloadType.
-     */
-    public static <T extends IkePayload> T getPayloadForTypeInProvidedList(
-            @IkePayload.PayloadType int payloadType,
-            Class<T> payloadClass,
-            List<IkePayload> searchList) {
-        List<T> payloadList =
-                getPayloadListForTypeInProvidedList(payloadType, payloadClass, searchList);
-        return payloadList.isEmpty() ? null : payloadList.get(0);
-    }
-
-    /**
      * Encode generic payload header to ByteBuffer.
      *
      * @param nextPayload type of payload that follows this payload.
@@ -223,11 +148,6 @@
                 .putShort((short) payloadLength);
     }
 
-    /** Retuns protocol type as String. */
-    public static String getProtocolTypeString(@ProtocolId int protocol) {
-        return PROTOCOL_TO_STR.get(protocol);
-    }
-
     /**
      * Encode payload to ByteBuffer.
      *
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java b/src/java/com/android/ike/ikev2/message/IkePayloadFactory.java
similarity index 73%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java
rename to src/java/com/android/ike/ikev2/message/IkePayloadFactory.java
index 2f191d4..bea87ca 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkePayloadFactory.java
+++ b/src/java/com/android/ike/ikev2/message/IkePayloadFactory.java
@@ -14,20 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
-import android.annotation.Nullable;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
 import android.util.Pair;
 
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
 
 import java.nio.ByteBuffer;
 import java.security.GeneralSecurityException;
 
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+
 /**
  * IkePayloadFactory is used for creating IkePayload according to is type.
  *
@@ -58,7 +59,7 @@
         @Override
         public IkePayload decodeIkePayload(
                 int payloadType, boolean isCritical, boolean isResp, byte[] payloadBody)
-                throws IkeProtocolException {
+                throws IkeException {
             switch (payloadType) {
                     // TODO: Add cases for creating supported payloads.
                 case IkePayload.PAYLOAD_TYPE_SA:
@@ -85,43 +86,10 @@
                     return new IkeTsPayload(isCritical, payloadBody, true);
                 case IkePayload.PAYLOAD_TYPE_TS_RESPONDER:
                     return new IkeTsPayload(isCritical, payloadBody, false);
-                case IkePayload.PAYLOAD_TYPE_CP:
-                    return new IkeConfigPayload(isCritical, payloadBody);
-                case IkePayload.PAYLOAD_TYPE_EAP:
-                    return new IkeEapPayload(isCritical, payloadBody);
                 default:
                     return new IkeUnsupportedPayload(payloadType, isCritical);
             }
         }
-
-        @Override
-        public IkeSkPayload decodeIkeSkPayload(
-                boolean isSkf,
-                boolean critical,
-                byte[] message,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher decryptCipher,
-                byte[] integrityKey,
-                byte[] decryptionKey)
-                throws IkeProtocolException, GeneralSecurityException {
-            if (isSkf) {
-                return new IkeSkfPayload(
-                        critical,
-                        message,
-                        integrityMac,
-                        decryptCipher,
-                        integrityKey,
-                        decryptionKey);
-            } else {
-                return new IkeSkPayload(
-                        critical,
-                        message,
-                        integrityMac,
-                        decryptCipher,
-                        integrityKey,
-                        decryptionKey);
-            }
-        }
     }
 
     /**
@@ -134,7 +102,7 @@
      * @return a Pair including IkePayload and next payload type.
      */
     protected static Pair<IkePayload, Integer> getIkePayload(
-            int payloadType, boolean isResp, ByteBuffer input) throws IkeProtocolException {
+            int payloadType, boolean isResp, ByteBuffer input) throws IkeException {
         int nextPayloadType = (int) input.get();
         // read critical bit
         boolean isCritical = isCriticalPayload(input.get());
@@ -161,24 +129,22 @@
     /**
      * Construct an instance of IkeSkPayload by decrypting the received message.
      *
-     * @param isSkf indicates if this is a SKF Payload.
      * @param message the byte array contains the whole IKE message.
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param decryptCipher the negotiated encryption algorithm.
-     * @param integrityKey the negotiated integrity algorithm key.
-     * @param decryptionKey the negotiated decryption key.
+     * @param integrityMac the initialized Mac for integrity check.
+     * @param checksumLen the checksum length of negotiated integrity algorithm.
+     * @param decryptCipher the uninitialized Cipher for doing decryption.
+     * @param dKey the decryption key.
      * @return a pair including IkePayload and next payload type.
-     * @throws IkeProtocolException for decoding errors.
+     * @throws IkeException for decoding errors.
      * @throws GeneralSecurityException if there is any error during integrity check or decryption.
      */
     protected static Pair<IkeSkPayload, Integer> getIkeSkPayload(
-            boolean isSkf,
             byte[] message,
-            IkeMacIntegrity integrityMac,
-            IkeCipher decryptCipher,
-            byte[] integrityKey,
-            byte[] decryptionKey)
-            throws IkeProtocolException, GeneralSecurityException {
+            Mac integrityMac,
+            int checksumLen,
+            Cipher decryptCipher,
+            SecretKey dKey)
+            throws IkeException, GeneralSecurityException {
         ByteBuffer input =
                 ByteBuffer.wrap(
                         message,
@@ -207,15 +173,13 @@
         }
 
         IkeSkPayload payload =
-                sDecoderInstance.decodeIkeSkPayload(
-                        isSkf,
+                new IkeSkPayload(
                         isCritical,
                         message,
                         integrityMac,
+                        checksumLen,
                         decryptCipher,
-                        integrityKey,
-                        decryptionKey);
-
+                        dKey);
         return new Pair(payload, nextPayloadType);
     }
 
@@ -229,16 +193,6 @@
     interface IIkePayloadDecoder {
         IkePayload decodeIkePayload(
                 int payloadType, boolean isCritical, boolean isResp, byte[] payloadBody)
-                throws IkeProtocolException;
-
-        IkeSkPayload decodeIkeSkPayload(
-                boolean isSkf,
-                boolean critical,
-                byte[] message,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher decryptCipher,
-                byte[] integrityKey,
-                byte[] decryptionKey)
-                throws IkeProtocolException, GeneralSecurityException;
+                throws IkeException;
     }
 }
diff --git a/src/java/com/android/ike/ikev2/message/IkeSaPayload.java b/src/java/com/android/ike/ikev2/message/IkeSaPayload.java
new file mode 100644
index 0000000..c0651ae
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeSaPayload.java
@@ -0,0 +1,1224 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static com.android.ike.ikev2.SaProposal.DhGroup;
+import static com.android.ike.ikev2.SaProposal.EncryptionAlgorithm;
+import static com.android.ike.ikev2.SaProposal.IntegrityAlgorithm;
+import static com.android.ike.ikev2.SaProposal.PseudorandomFunction;
+
+import android.annotation.IntDef;
+import android.util.ArraySet;
+import android.util.Pair;
+
+import com.android.ike.ikev2.SaProposal;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.exceptions.NoValidProposalChosenException;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * IkeSaPayload represents a Security Association payload. It contains one or more {@link Proposal}.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class IkeSaPayload extends IkePayload {
+    public final boolean isSaResponse;
+    public final List<Proposal> proposalList;
+    /**
+     * Construct an instance of IkeSaPayload for decoding an inbound packet.
+     *
+     * @param critical indicates if this payload is critical. Ignored in supported payload as
+     *     instructed by the RFC 7296.
+     * @param isResp indicates if this payload is in a response message.
+     * @param payloadBody the encoded payload body in byte array.
+     */
+    IkeSaPayload(boolean critical, boolean isResp, byte[] payloadBody) throws IkeException {
+        super(IkePayload.PAYLOAD_TYPE_SA, critical);
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
+        proposalList = new LinkedList<>();
+        while (inputBuffer.hasRemaining()) {
+            Proposal proposal = Proposal.readFrom(inputBuffer);
+            proposalList.add(proposal);
+        }
+
+        // An SA response must have exactly one SA proposal.
+        if (isResp && proposalList.size() != 1) {
+            throw new InvalidSyntaxException(
+                    "Expected only one negotiated proposal from SA response: "
+                            + "Multiple negotiated proposals found.");
+        }
+        isSaResponse = isResp;
+    }
+
+    /**
+     * Construct an instance of IkeSaPayload for building outbound packet.
+     *
+     * <p>The length of spis must be the same as saProposals.
+     *
+     * @param isResp indicates if this payload is in a response message.
+     * @param isIkeSa indicates if this payload is for IKE SA or Child SA
+     * @param spiSize the size of attached SPIs.
+     * @param spis the array of all attached SPIs.
+     * @param saProposals the array of all SA Proposals.
+     */
+    public IkeSaPayload(
+            boolean isResp, boolean isIkeSa, byte spiSize, long[] spis, SaProposal[] saProposals) {
+        super(IkePayload.PAYLOAD_TYPE_SA, false);
+
+        if (saProposals.length < 1
+                || isResp && (saProposals.length > 1)
+                || saProposals.length != spis.length) {
+            throw new IllegalArgumentException("Invalid SA payload.");
+        }
+
+        // TODO: Check that saProposals.length <= 255 in IkeSessionOptions and ChildSessionOptions
+        isSaResponse = isResp;
+
+        proposalList = new ArrayList<Proposal>(saProposals.length);
+        int protocolId = isIkeSa ? PROTOCOL_ID_IKE : PROTOCOL_ID_ESP;
+        for (int i = 0; i < saProposals.length; i++) {
+            // Proposal number must start from 1.
+            Proposal proposal =
+                    new Proposal(
+                            (byte) (i + 1) /*proposal number*/,
+                            protocolId,
+                            spiSize,
+                            spis[i],
+                            saProposals[i],
+                            false /*does not have unrecognized Transform*/);
+            proposalList.add(proposal);
+        }
+    }
+
+    /**
+     * Construct an instance of IkeSaPayload for building outbound IKE initial setup request.
+     *
+     * <p>According to RFC 7296, for an initial IKE SA negotiation, no SPI is included in SA
+     * Proposal. IKE library, as a client, only supports requesting this initial negotiation.
+     *
+     * @param saProposals the array of all SA Proposals.
+     */
+    public IkeSaPayload(SaProposal[] saProposals) {
+        this(
+                false /*is request*/,
+                true /*is IKE SA*/,
+                (byte) 0,
+                new long[saProposals.length],
+                saProposals);
+    }
+
+    /**
+     * Validate and return the negotiated SA proposal from the received SA payload.
+     *
+     * @param reqSaPayload SA payload from SA initiator to validate against.
+     * @return the validated negotiated SA proposal.
+     * @throws NoValidProposalChosenException if received SA proposal is invalid.
+     */
+    public SaProposal getVerifiedNegotiatedProposal(IkeSaPayload reqSaPayload)
+            throws NoValidProposalChosenException {
+        if (!isSaResponse) {
+            throw new UnsupportedOperationException(
+                    "Cannot get negotiated SA proposal from a request message.");
+        }
+
+        // If negotiated proposal has an unrecognized Transform, throw an exception.
+        Proposal respProposal = proposalList.get(0);
+        if (respProposal.hasUnrecognizedTransform) {
+            throw new NoValidProposalChosenException(
+                    "Negotiated proposal has unrecognized Transform.");
+        }
+
+        // In SA request payload, the first proposal MUST be 1, and subsequent proposals MUST be one
+        // more than the previous proposal. In SA response payload, the negotiated proposal number
+        // MUST match the selected proposal number in SA request Payload.
+        int negotiatedProposalNum = respProposal.number;
+        List<Proposal> reqProposalList = reqSaPayload.proposalList;
+        if (negotiatedProposalNum < 1 || negotiatedProposalNum > reqProposalList.size()) {
+            throw new NoValidProposalChosenException(
+                    "Negotiated proposal has invalid proposal number.");
+        }
+
+        Proposal reqProposal = reqProposalList.get(negotiatedProposalNum - 1);
+        if (!respProposal.isNegotiatedFrom(reqProposal)) {
+            throw new NoValidProposalChosenException("Invalid negotiated proposal.");
+        }
+        return respProposal.saProposal;
+    }
+
+    @VisibleForTesting
+    interface TransformDecoder {
+        Transform[] decodeTransforms(int count, ByteBuffer inputBuffer) throws IkeException;
+    }
+
+    // TODO: Add another constructor for building outbound message.
+
+    /**
+     * Proposal represents a set contains cryptographic algorithms and key generating materials. It
+     * contains multiple {@link Transform}.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.1">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     *     <p>Proposals with an unrecognized Protocol ID, containing an unrecognized Transform Type
+     *     or lacking a necessary Transform Type shall be ignored when processing a received SA
+     *     Payload.
+     */
+    public static final class Proposal {
+        private static final byte LAST_PROPOSAL = 0;
+        private static final byte NOT_LAST_PROPOSAL = 2;
+
+        private static final int PROPOSAL_RESERVED_FIELD_LEN = 1;
+        private static final int PROPOSAL_HEADER_LEN = 8;
+
+        @VisibleForTesting
+        static TransformDecoder sTransformDecoder =
+                new TransformDecoder() {
+                    @Override
+                    public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer)
+                            throws IkeException {
+                        Transform[] transformArray = new Transform[count];
+                        for (int i = 0; i < count; i++) {
+                            Transform transform = Transform.readFrom(inputBuffer);
+                            if (transform.isSupported) {
+                                transformArray[i] = transform;
+                            }
+                        }
+                        return transformArray;
+                    }
+                };
+
+        public final byte number;
+        /** All supported protocol will fall into {@link ProtocolId} */
+        public final int protocolId;
+
+        public final byte spiSize;
+        public final long spi;
+
+        public final SaProposal saProposal;
+
+        public final boolean hasUnrecognizedTransform;
+
+        // TODO: Validate this proposal
+
+        @VisibleForTesting
+        Proposal(
+                byte number,
+                int protocolId,
+                byte spiSize,
+                long spi,
+                SaProposal saProposal,
+                boolean hasUnrecognizedTransform) {
+            this.number = number;
+            this.protocolId = protocolId;
+            this.spiSize = spiSize;
+            this.spi = spi;
+            this.saProposal = saProposal;
+            this.hasUnrecognizedTransform = hasUnrecognizedTransform;
+        }
+
+        @VisibleForTesting
+        static Proposal readFrom(ByteBuffer inputBuffer) throws IkeException {
+            byte isLast = inputBuffer.get();
+            if (isLast != LAST_PROPOSAL && isLast != NOT_LAST_PROPOSAL) {
+                throw new InvalidSyntaxException(
+                        "Invalid value of Last Proposal Substructure: " + isLast);
+            }
+            // Skip RESERVED byte
+            inputBuffer.get(new byte[PROPOSAL_RESERVED_FIELD_LEN]);
+
+            int length = Short.toUnsignedInt(inputBuffer.getShort());
+            byte number = inputBuffer.get();
+            int protocolId = Byte.toUnsignedInt(inputBuffer.get());
+
+            byte spiSize = inputBuffer.get();
+            int transformCount = Byte.toUnsignedInt(inputBuffer.get());
+
+            // TODO: Add check: spiSize must be 0 in initial IKE SA negotiation
+            // spiSize should be either 8 for IKE or 4 for IPsec.
+            long spi = SPI_NOT_INCLUDED;
+            switch (spiSize) {
+                case SPI_LEN_NOT_INCLUDED:
+                    // No SPI attached for IKE initial exchange.
+                    break;
+                case SPI_LEN_IPSEC:
+                    spi = Integer.toUnsignedLong(inputBuffer.getInt());
+                    break;
+                case SPI_LEN_IKE:
+                    spi = inputBuffer.getLong();
+                    break;
+                default:
+                    throw new InvalidSyntaxException(
+                            "Invalid value of spiSize in Proposal Substructure: " + spiSize);
+            }
+
+            Transform[] transformArray =
+                    sTransformDecoder.decodeTransforms(transformCount, inputBuffer);
+            // TODO: Validate that sum of all Transforms' lengths plus Proposal header length equals
+            // to Proposal's length.
+
+            List<EncryptionTransform> encryptAlgoList = new LinkedList<>();
+            List<PrfTransform> prfList = new LinkedList<>();
+            List<IntegrityTransform> integAlgoList = new LinkedList<>();
+            List<DhGroupTransform> dhGroupList = new LinkedList<>();
+            List<EsnTransform> esnList = new LinkedList<>();
+
+            boolean hasUnrecognizedTransform = false;
+
+            for (Transform transform : transformArray) {
+                switch (transform.type) {
+                    case Transform.TRANSFORM_TYPE_ENCR:
+                        encryptAlgoList.add((EncryptionTransform) transform);
+                        break;
+                    case Transform.TRANSFORM_TYPE_PRF:
+                        prfList.add((PrfTransform) transform);
+                        break;
+                    case Transform.TRANSFORM_TYPE_INTEG:
+                        integAlgoList.add((IntegrityTransform) transform);
+                        break;
+                    case Transform.TRANSFORM_TYPE_DH:
+                        dhGroupList.add((DhGroupTransform) transform);
+                        break;
+                    case Transform.TRANSFORM_TYPE_ESN:
+                        esnList.add((EsnTransform) transform);
+                        break;
+                    default:
+                        hasUnrecognizedTransform = true;
+                }
+            }
+
+            SaProposal saProposal =
+                    new SaProposal(
+                            protocolId,
+                            encryptAlgoList.toArray(
+                                    new EncryptionTransform[encryptAlgoList.size()]),
+                            prfList.toArray(new PrfTransform[prfList.size()]),
+                            integAlgoList.toArray(new IntegrityTransform[integAlgoList.size()]),
+                            dhGroupList.toArray(new DhGroupTransform[dhGroupList.size()]),
+                            esnList.toArray(new EsnTransform[esnList.size()]));
+
+            return new Proposal(
+                    number, protocolId, spiSize, spi, saProposal, hasUnrecognizedTransform);
+        }
+        // TODO: Add another contructor for encoding.
+
+        /** Package private */
+        boolean isNegotiatedFrom(Proposal reqProposal) {
+            if (protocolId != reqProposal.protocolId || number != reqProposal.number) {
+                return false;
+            }
+            return saProposal.isNegotiatedFrom(reqProposal.saProposal);
+        }
+
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            Transform[] allTransforms = saProposal.getAllTransforms();
+            byte isLastIndicator = isLast ? LAST_PROPOSAL : NOT_LAST_PROPOSAL;
+
+            byteBuffer
+                    .put(isLastIndicator)
+                    .put(new byte[PROPOSAL_RESERVED_FIELD_LEN])
+                    .putShort((short) getProposalLength())
+                    .put(number)
+                    .put((byte) protocolId)
+                    .put(spiSize)
+                    .put((byte) allTransforms.length);
+
+            switch (spiSize) {
+                case SPI_LEN_NOT_INCLUDED:
+                    // No SPI attached for IKE initial exchange.
+                    break;
+                case SPI_LEN_IPSEC:
+                    byteBuffer.putInt((int) spi);
+                    break;
+                case SPI_LEN_IKE:
+                    byteBuffer.putLong((long) spi);
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Invalid value of spiSize in Proposal Substructure: " + spiSize);
+            }
+
+            // Encode all Transform.
+            for (int i = 0; i < allTransforms.length; i++) {
+                // The last transform has the isLast flag set to true.
+                allTransforms[i].encodeToByteBuffer(i == allTransforms.length - 1, byteBuffer);
+            }
+        }
+
+        protected int getProposalLength() {
+            int len = PROPOSAL_HEADER_LEN + spiSize;
+
+            Transform[] allTransforms = saProposal.getAllTransforms();
+            for (Transform t : allTransforms) len += t.getTransformLength();
+            return len;
+        }
+    }
+
+    @VisibleForTesting
+    interface AttributeDecoder {
+        List<Attribute> decodeAttributes(int length, ByteBuffer inputBuffer) throws IkeException;
+    }
+
+    /**
+     * Transform is an abstract base class that represents the common information for all Transform
+     * types. It may contain one or more {@link Attribute}.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     *     <p>Transforms with unrecognized Transform ID or containing unrecognized Attribute Type
+     *     shall be ignored when processing received SA payload.
+     */
+    public abstract static class Transform {
+
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({
+            TRANSFORM_TYPE_ENCR,
+            TRANSFORM_TYPE_PRF,
+            TRANSFORM_TYPE_INTEG,
+            TRANSFORM_TYPE_DH,
+            TRANSFORM_TYPE_ESN
+        })
+        public @interface TransformType {}
+
+        public static final int TRANSFORM_TYPE_ENCR = 1;
+        public static final int TRANSFORM_TYPE_PRF = 2;
+        public static final int TRANSFORM_TYPE_INTEG = 3;
+        public static final int TRANSFORM_TYPE_DH = 4;
+        public static final int TRANSFORM_TYPE_ESN = 5;
+
+        private static final byte LAST_TRANSFORM = 0;
+        private static final byte NOT_LAST_TRANSFORM = 3;
+
+        // Length of reserved field of a Transform.
+        private static final int TRANSFORM_RESERVED_FIELD_LEN = 1;
+
+        // Length of the Transform that with no Attribute.
+        protected static final int BASIC_TRANSFORM_LEN = 8;
+
+        // TODO: Add constants for supported algorithms
+
+        @VisibleForTesting
+        static AttributeDecoder sAttributeDecoder =
+                new AttributeDecoder() {
+                    public List<Attribute> decodeAttributes(int length, ByteBuffer inputBuffer)
+                            throws IkeException {
+                        List<Attribute> list = new LinkedList<>();
+                        int parsedLength = BASIC_TRANSFORM_LEN;
+                        while (parsedLength < length) {
+                            Pair<Attribute, Integer> pair = Attribute.readFrom(inputBuffer);
+                            parsedLength += pair.second;
+                            list.add(pair.first);
+                        }
+                        // TODO: Validate that parsedLength equals to length.
+                        return list;
+                    }
+                };
+
+        // Only supported type falls into {@link TransformType}
+        public final int type;
+        public final int id;
+        public final boolean isSupported;
+
+        /** Construct an instance of Transform for building an outbound packet. */
+        protected Transform(int type, int id) {
+            this.type = type;
+            this.id = id;
+            if (!isSupportedTransformId(id)) {
+                throw new IllegalArgumentException(
+                        "Unsupported " + getTransformTypeString() + " Algorithm ID: " + id);
+            }
+            this.isSupported = true;
+        }
+
+        /** Construct an instance of Transform for decoding an inbound packet. */
+        protected Transform(int type, int id, List<Attribute> attributeList) {
+            this.type = type;
+            this.id = id;
+            this.isSupported =
+                    isSupportedTransformId(id) && !hasUnrecognizedAttribute(attributeList);
+        }
+
+        @VisibleForTesting
+        static Transform readFrom(ByteBuffer inputBuffer) throws IkeException {
+            byte isLast = inputBuffer.get();
+            if (isLast != LAST_TRANSFORM && isLast != NOT_LAST_TRANSFORM) {
+                throw new InvalidSyntaxException(
+                        "Invalid value of Last Transform Substructure: " + isLast);
+            }
+
+            // Skip RESERVED byte
+            inputBuffer.get(new byte[TRANSFORM_RESERVED_FIELD_LEN]);
+
+            int length = Short.toUnsignedInt(inputBuffer.getShort());
+            int type = Byte.toUnsignedInt(inputBuffer.get());
+
+            // Skip RESERVED byte
+            inputBuffer.get(new byte[TRANSFORM_RESERVED_FIELD_LEN]);
+
+            int id = Short.toUnsignedInt(inputBuffer.getShort());
+
+            // Decode attributes
+            List<Attribute> attributeList = sAttributeDecoder.decodeAttributes(length, inputBuffer);
+
+            validateAttributeUniqueness(attributeList);
+
+            switch (type) {
+                case TRANSFORM_TYPE_ENCR:
+                    return new EncryptionTransform(id, attributeList);
+                case TRANSFORM_TYPE_PRF:
+                    return new PrfTransform(id, attributeList);
+                case TRANSFORM_TYPE_INTEG:
+                    return new IntegrityTransform(id, attributeList);
+                case TRANSFORM_TYPE_DH:
+                    return new DhGroupTransform(id, attributeList);
+                case TRANSFORM_TYPE_ESN:
+                    return new EsnTransform(id, attributeList);
+                default:
+                    return new UnrecognizedTransform(type, id, attributeList);
+            }
+        }
+
+        // Throw InvalidSyntaxException if there are multiple Attributes of the same type
+        private static void validateAttributeUniqueness(List<Attribute> attributeList)
+                throws IkeException {
+            Set<Integer> foundTypes = new ArraySet<>();
+            for (Attribute attr : attributeList) {
+                if (!foundTypes.add(attr.type)) {
+                    throw new InvalidSyntaxException(
+                            "There are multiple Attributes of the same type. ");
+                }
+            }
+        }
+
+        // Check if there is Attribute with unrecognized type.
+        protected abstract boolean hasUnrecognizedAttribute(List<Attribute> attributeList);
+
+        // Check if this Transform ID is supported.
+        protected abstract boolean isSupportedTransformId(int id);
+
+        // Encode Transform to a ByteBuffer.
+        protected abstract void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer);
+
+        // Get entire Transform length.
+        protected abstract int getTransformLength();
+
+        protected void encodeBasicTransformToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            byte isLastIndicator = isLast ? LAST_TRANSFORM : NOT_LAST_TRANSFORM;
+            byteBuffer
+                    .put(isLastIndicator)
+                    .put(new byte[TRANSFORM_RESERVED_FIELD_LEN])
+                    .putShort((short) getTransformLength())
+                    .put((byte) type)
+                    .put(new byte[TRANSFORM_RESERVED_FIELD_LEN])
+                    .putShort((short) id);
+        }
+
+        /**
+         * Get Tranform Type as a String.
+         *
+         * @return Tranform Type as a String.
+         */
+        public abstract String getTransformTypeString();
+
+        // TODO: Add abstract getTransformIdString() to return specific algorithm/dhGroup name
+    }
+
+    /**
+     * EncryptionTransform represents an encryption algorithm. It may contain an Atrribute
+     * specifying the key length.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     */
+    public static final class EncryptionTransform extends Transform {
+        private static final int KEY_LEN_UNSPECIFIED = 0;
+
+        // When using encryption algorithm with variable-length keys, mSpecifiedKeyLength MUST be
+        // set and a KeyLengthAttribute MUST be attached. Otherwise, mSpecifiedKeyLength MUST NOT be
+        // set and KeyLengthAttribute MUST NOT be attached.
+        private final int mSpecifiedKeyLength;
+
+        /**
+         * Contruct an instance of EncryptionTransform with fixed key length for building an
+         * outbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         */
+        public EncryptionTransform(@EncryptionAlgorithm int id) {
+            this(id, KEY_LEN_UNSPECIFIED);
+        }
+
+        /**
+         * Contruct an instance of EncryptionTransform with variable key length for building an
+         * outbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         * @param specifiedKeyLength the specified key length of this encryption algorithm.
+         */
+        public EncryptionTransform(@EncryptionAlgorithm int id, int specifiedKeyLength) {
+            super(Transform.TRANSFORM_TYPE_ENCR, id);
+
+            mSpecifiedKeyLength = specifiedKeyLength;
+            try {
+                validateKeyLength();
+            } catch (InvalidSyntaxException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+
+        /**
+         * Contruct an instance of EncryptionTransform for decoding an inbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         * @param attributeList the decoded list of Attribute.
+         * @throws InvalidSyntaxException for syntax error.
+         */
+        protected EncryptionTransform(int id, List<Attribute> attributeList)
+                throws InvalidSyntaxException {
+            super(Transform.TRANSFORM_TYPE_ENCR, id, attributeList);
+            if (!isSupported) {
+                mSpecifiedKeyLength = KEY_LEN_UNSPECIFIED;
+            } else {
+                if (attributeList.size() == 0) {
+                    mSpecifiedKeyLength = KEY_LEN_UNSPECIFIED;
+                } else {
+                    KeyLengthAttribute attr = getKeyLengthAttribute(attributeList);
+                    mSpecifiedKeyLength = attr.keyLength;
+                }
+                validateKeyLength();
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, id, mSpecifiedKeyLength);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof EncryptionTransform)) return false;
+
+            EncryptionTransform other = (EncryptionTransform) o;
+            return (type == other.type
+                    && id == other.id
+                    && mSpecifiedKeyLength == other.mSpecifiedKeyLength);
+        }
+
+        @Override
+        protected boolean isSupportedTransformId(int id) {
+            return SaProposal.isSupportedEncryptionAlgorithm(id);
+        }
+
+        @Override
+        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
+            for (Attribute attr : attributeList) {
+                if (attr instanceof UnrecognizedAttribute) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private KeyLengthAttribute getKeyLengthAttribute(List<Attribute> attributeList) {
+            for (Attribute attr : attributeList) {
+                if (attr.type == Attribute.ATTRIBUTE_TYPE_KEY_LENGTH) {
+                    return (KeyLengthAttribute) attr;
+                }
+            }
+            throw new IllegalArgumentException("Cannot find Attribute with Key Length type");
+        }
+
+        private void validateKeyLength() throws InvalidSyntaxException {
+            switch (id) {
+                case SaProposal.ENCRYPTION_ALGORITHM_3DES:
+                    if (mSpecifiedKeyLength != KEY_LEN_UNSPECIFIED) {
+                        throw new InvalidSyntaxException(
+                                "Must not set Key Length value for this "
+                                        + getTransformTypeString()
+                                        + " Algorithm ID: "
+                                        + id);
+                    }
+                    return;
+                case SaProposal.ENCRYPTION_ALGORITHM_AES_CBC:
+                    /* fall through */
+                case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8:
+                    /* fall through */
+                case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12:
+                    /* fall through */
+                case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16:
+                    if (mSpecifiedKeyLength == KEY_LEN_UNSPECIFIED) {
+                        throw new InvalidSyntaxException(
+                                "Must set Key Length value for this "
+                                        + getTransformTypeString()
+                                        + " Algorithm ID: "
+                                        + id);
+                    }
+                    if (mSpecifiedKeyLength != SaProposal.KEY_LEN_AES_128
+                            && mSpecifiedKeyLength != SaProposal.KEY_LEN_AES_192
+                            && mSpecifiedKeyLength != SaProposal.KEY_LEN_AES_256) {
+                        throw new InvalidSyntaxException(
+                                "Invalid key length for this "
+                                        + getTransformTypeString()
+                                        + " Algorithm ID: "
+                                        + id);
+                    }
+                    return;
+                default:
+                    // Won't hit here.
+                    throw new IllegalArgumentException(
+                            "Unrecognized Encryption Algorithm ID: " + id);
+            }
+        }
+
+        @Override
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
+
+            if (mSpecifiedKeyLength != KEY_LEN_UNSPECIFIED) {
+                new KeyLengthAttribute(mSpecifiedKeyLength).encodeToByteBuffer(byteBuffer);
+            }
+        }
+
+        @Override
+        protected int getTransformLength() {
+            int len = BASIC_TRANSFORM_LEN;
+
+            if (mSpecifiedKeyLength != KEY_LEN_UNSPECIFIED) {
+                len += new KeyLengthAttribute(mSpecifiedKeyLength).getAttributeLength();
+            }
+
+            return len;
+        }
+
+        @Override
+        public String getTransformTypeString() {
+            return "Encryption Algorithm";
+        }
+    }
+
+    /**
+     * PrfTransform represents an pseudorandom function.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     */
+    public static final class PrfTransform extends Transform {
+        /**
+         * Contruct an instance of PrfTransform for building an outbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         */
+        public PrfTransform(@PseudorandomFunction int id) {
+            super(Transform.TRANSFORM_TYPE_PRF, id);
+        }
+
+        /**
+         * Contruct an instance of PrfTransform for decoding an inbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         * @param attributeList the decoded list of Attribute.
+         * @throws InvalidSyntaxException for syntax error.
+         */
+        protected PrfTransform(int id, List<Attribute> attributeList)
+                throws InvalidSyntaxException {
+            super(Transform.TRANSFORM_TYPE_PRF, id, attributeList);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, id);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof PrfTransform)) return false;
+
+            PrfTransform other = (PrfTransform) o;
+            return (type == other.type && id == other.id);
+        }
+
+        @Override
+        protected boolean isSupportedTransformId(int id) {
+            return SaProposal.isSupportedPseudorandomFunction(id);
+        }
+
+        @Override
+        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
+            return !attributeList.isEmpty();
+        }
+
+        @Override
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
+        }
+
+        @Override
+        protected int getTransformLength() {
+            return BASIC_TRANSFORM_LEN;
+        }
+
+        @Override
+        public String getTransformTypeString() {
+            return "Pseudorandom Function";
+        }
+    }
+
+    /**
+     * IntegrityTransform represents an integrity algorithm.
+     *
+     * <p>Proposing integrity algorithm for ESP SA is optional. Omitting the IntegrityTransform is
+     * equivalent to including it with a value of NONE. When multiple integrity algorithms are
+     * provided, choosing any of them are acceptable.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     */
+    public static final class IntegrityTransform extends Transform {
+        /**
+         * Contruct an instance of IntegrityTransform for building an outbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         */
+        public IntegrityTransform(@IntegrityAlgorithm int id) {
+            super(Transform.TRANSFORM_TYPE_INTEG, id);
+        }
+
+        /**
+         * Contruct an instance of IntegrityTransform for decoding an inbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         * @param attributeList the decoded list of Attribute.
+         * @throws InvalidSyntaxException for syntax error.
+         */
+        protected IntegrityTransform(int id, List<Attribute> attributeList)
+                throws InvalidSyntaxException {
+            super(Transform.TRANSFORM_TYPE_INTEG, id, attributeList);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, id);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof IntegrityTransform)) return false;
+
+            IntegrityTransform other = (IntegrityTransform) o;
+            return (type == other.type && id == other.id);
+        }
+
+        @Override
+        protected boolean isSupportedTransformId(int id) {
+            return SaProposal.isSupportedIntegrityAlgorithm(id);
+        }
+
+        @Override
+        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
+            return !attributeList.isEmpty();
+        }
+
+        @Override
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
+        }
+
+        @Override
+        protected int getTransformLength() {
+            return BASIC_TRANSFORM_LEN;
+        }
+
+        @Override
+        public String getTransformTypeString() {
+            return "Integrity Algorithm";
+        }
+    }
+
+    /**
+     * DhGroupTransform represents a Diffie-Hellman Group
+     *
+     * <p>Proposing DH group for non-first Child SA is optional. Omitting the DhGroupTransform is
+     * equivalent to including it with a value of NONE. When multiple DH groups are provided,
+     * choosing any of them are acceptable.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     */
+    public static final class DhGroupTransform extends Transform {
+        /**
+         * Contruct an instance of DhGroupTransform for building an outbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         */
+        public DhGroupTransform(@DhGroup int id) {
+            super(Transform.TRANSFORM_TYPE_DH, id);
+        }
+
+        /**
+         * Contruct an instance of DhGroupTransform for decoding an inbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         * @param attributeList the decoded list of Attribute.
+         * @throws InvalidSyntaxException for syntax error.
+         */
+        protected DhGroupTransform(int id, List<Attribute> attributeList)
+                throws InvalidSyntaxException {
+            super(Transform.TRANSFORM_TYPE_DH, id, attributeList);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, id);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof DhGroupTransform)) return false;
+
+            DhGroupTransform other = (DhGroupTransform) o;
+            return (type == other.type && id == other.id);
+        }
+
+        @Override
+        protected boolean isSupportedTransformId(int id) {
+            return SaProposal.isSupportedDhGroup(id);
+        }
+
+        @Override
+        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
+            return !attributeList.isEmpty();
+        }
+
+        @Override
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
+        }
+
+        @Override
+        protected int getTransformLength() {
+            return BASIC_TRANSFORM_LEN;
+        }
+
+        @Override
+        public String getTransformTypeString() {
+            return "Diffie-Hellman Group";
+        }
+    }
+
+    /**
+     * EsnTransform represents ESN policy that indicates if IPsec SA uses tranditional 32-bit
+     * sequence numbers or extended(64-bit) sequence numbers.
+     *
+     * <p>Currently IKE library only supports negotiating IPsec SA that do not use extended sequence
+     * numbers. The Transform ID of EsnTransform in outbound packets is not user configurable.
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     */
+    public static final class EsnTransform extends Transform {
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({ESN_POLICY_NO_EXTENDED, ESN_POLICY_EXTENDED})
+        public @interface EsnPolicy {}
+
+        public static final int ESN_POLICY_NO_EXTENDED = 0;
+        public static final int ESN_POLICY_EXTENDED = 1;
+
+        /**
+         * Construct an instance of EsnTransform indicates using no-extended sequence numbers for
+         * building an outbound packet.
+         */
+        public EsnTransform() {
+            super(Transform.TRANSFORM_TYPE_ESN, ESN_POLICY_NO_EXTENDED);
+        }
+
+        /**
+         * Contruct an instance of EsnTransform for decoding an inbound packet.
+         *
+         * @param id the IKE standard Transform ID.
+         * @param attributeList the decoded list of Attribute.
+         * @throws InvalidSyntaxException for syntax error.
+         */
+        protected EsnTransform(int id, List<Attribute> attributeList)
+                throws InvalidSyntaxException {
+            super(Transform.TRANSFORM_TYPE_ESN, id, attributeList);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, id);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof EsnTransform)) return false;
+
+            EsnTransform other = (EsnTransform) o;
+            return (type == other.type && id == other.id);
+        }
+
+        @Override
+        protected boolean isSupportedTransformId(int id) {
+            return (id == ESN_POLICY_NO_EXTENDED || id == ESN_POLICY_EXTENDED);
+        }
+
+        @Override
+        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
+            return !attributeList.isEmpty();
+        }
+
+        @Override
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
+        }
+
+        @Override
+        protected int getTransformLength() {
+            return BASIC_TRANSFORM_LEN;
+        }
+
+        @Override
+        public String getTransformTypeString() {
+            return "Extended Sequence Numbers";
+        }
+    }
+
+    /**
+     * UnrecognizedTransform represents a Transform with unrecognized Transform Type.
+     *
+     * <p>Proposals containing an UnrecognizedTransform should be ignored.
+     */
+    protected static final class UnrecognizedTransform extends Transform {
+        protected UnrecognizedTransform(int type, int id, List<Attribute> attributeList) {
+            super(type, id, attributeList);
+        }
+
+        @Override
+        protected boolean isSupportedTransformId(int id) {
+            return false;
+        }
+
+        @Override
+        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
+            return !attributeList.isEmpty();
+        }
+
+        @Override
+        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
+            throw new UnsupportedOperationException(
+                    "It is not supported to encode a Transform with" + getTransformTypeString());
+        }
+
+        @Override
+        protected int getTransformLength() {
+            throw new UnsupportedOperationException(
+                    "It is not supported to get length of a Transform with "
+                            + getTransformTypeString());
+        }
+
+        /**
+         * Return Tranform Type of Unrecognized Transform as a String.
+         *
+         * @return Tranform Type of Unrecognized Transform as a String.
+         */
+        @Override
+        public String getTransformTypeString() {
+            return "Unrecognized Transform Type.";
+        }
+    }
+
+    /**
+     * Attribute is an abtract base class for completing the specification of some {@link
+     * Transform}.
+     *
+     * <p>Attribute is either in Type/Value format or Type/Length/Value format. For TV format,
+     * Attribute length is always 4 bytes containing value for 2 bytes. While for TLV format,
+     * Attribute length is determined by length field.
+     *
+     * <p>Currently only Key Length type is supported
+     *
+     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.5">RFC 7296, Internet Key
+     *     Exchange Protocol Version 2 (IKEv2)</a>
+     */
+    public abstract static class Attribute {
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef({ATTRIBUTE_TYPE_KEY_LENGTH})
+        public @interface AttributeType {}
+
+        // Support only one Attribute type: Key Length. Should use Type/Value format.
+        public static final int ATTRIBUTE_TYPE_KEY_LENGTH = 14;
+
+        // Mask to extract the left most AF bit to indicate Attribute Format.
+        private static final int ATTRIBUTE_FORMAT_MASK = 0x8000;
+        // Mask to extract 15 bits after the AF bit to indicate Attribute Type.
+        private static final int ATTRIBUTE_TYPE_MASK = 0x7fff;
+
+        // Package private mask to indicate that Type-Value (TV) Attribute Format is used.
+        static final int ATTRIBUTE_FORMAT_TV = ATTRIBUTE_FORMAT_MASK;
+
+        // Package private
+        static final int TV_ATTRIBUTE_VALUE_LEN = 2;
+        static final int TV_ATTRIBUTE_TOTAL_LEN = 4;
+        static final int TVL_ATTRIBUTE_HEADER_LEN = TV_ATTRIBUTE_TOTAL_LEN;
+
+        // Only Key Length type belongs to AttributeType
+        public final int type;
+
+        /** Construct an instance of an Attribute when decoding message. */
+        protected Attribute(int type) {
+            this.type = type;
+        }
+
+        @VisibleForTesting
+        static Pair<Attribute, Integer> readFrom(ByteBuffer inputBuffer) throws IkeException {
+            short formatAndType = inputBuffer.getShort();
+            int format = formatAndType & ATTRIBUTE_FORMAT_MASK;
+            int type = formatAndType & ATTRIBUTE_TYPE_MASK;
+
+            int length = 0;
+            byte[] value = new byte[0];
+            if (format == ATTRIBUTE_FORMAT_TV) {
+                // Type/Value format
+                length = TV_ATTRIBUTE_TOTAL_LEN;
+                value = new byte[TV_ATTRIBUTE_VALUE_LEN];
+            } else {
+                // Type/Length/Value format
+                if (type == ATTRIBUTE_TYPE_KEY_LENGTH) {
+                    throw new InvalidSyntaxException("Wrong format in Transform Attribute");
+                }
+
+                length = Short.toUnsignedInt(inputBuffer.getShort());
+                int valueLen = length - TVL_ATTRIBUTE_HEADER_LEN;
+                // IkeMessage will catch exception if valueLen is negative.
+                value = new byte[valueLen];
+            }
+
+            inputBuffer.get(value);
+
+            switch (type) {
+                case ATTRIBUTE_TYPE_KEY_LENGTH:
+                    return new Pair(new KeyLengthAttribute(value), length);
+                default:
+                    return new Pair(new UnrecognizedAttribute(type, value), length);
+            }
+        }
+
+        // Encode Attribute to a ByteBuffer.
+        protected abstract void encodeToByteBuffer(ByteBuffer byteBuffer);
+
+        // Get entire Attribute length.
+        protected abstract int getAttributeLength();
+    }
+
+    /** KeyLengthAttribute represents a Key Length type Attribute */
+    public static final class KeyLengthAttribute extends Attribute {
+        public final int keyLength;
+
+        protected KeyLengthAttribute(byte[] value) {
+            this(Short.toUnsignedInt(ByteBuffer.wrap(value).getShort()));
+        }
+
+        protected KeyLengthAttribute(int keyLength) {
+            super(ATTRIBUTE_TYPE_KEY_LENGTH);
+            this.keyLength = keyLength;
+        }
+
+        @Override
+        protected void encodeToByteBuffer(ByteBuffer byteBuffer) {
+            byteBuffer
+                    .putShort((short) (ATTRIBUTE_FORMAT_TV | ATTRIBUTE_TYPE_KEY_LENGTH))
+                    .putShort((short) keyLength);
+        }
+
+        @Override
+        protected int getAttributeLength() {
+            return TV_ATTRIBUTE_TOTAL_LEN;
+        }
+    }
+
+    /**
+     * UnrecognizedAttribute represents a Attribute with unrecoginzed Attribute Type.
+     *
+     * <p>Transforms containing UnrecognizedAttribute should be ignored.
+     */
+    protected static final class UnrecognizedAttribute extends Attribute {
+        protected UnrecognizedAttribute(int type, byte[] value) {
+            super(type);
+        }
+
+        @Override
+        protected void encodeToByteBuffer(ByteBuffer byteBuffer) {
+            throw new UnsupportedOperationException(
+                    "It is not supported to encode an unrecognized Attribute.");
+        }
+
+        @Override
+        protected int getAttributeLength() {
+            throw new UnsupportedOperationException(
+                    "It is not supported to get length of an unrecognized Attribute.");
+        }
+    }
+
+    /**
+     * Encode SA payload to ByteBUffer.
+     *
+     * @param nextPayload type of payload that follows this payload.
+     * @param byteBuffer destination ByteBuffer that stores encoded payload.
+     */
+    @Override
+    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
+
+        for (int i = 0; i < proposalList.size(); i++) {
+            // The last proposal has the isLast flag set to true.
+            proposalList.get(i).encodeToByteBuffer(i == proposalList.size() - 1, byteBuffer);
+        }
+    }
+
+    /**
+     * Get entire payload length.
+     *
+     * @return entire payload length.
+     */
+    @Override
+    protected int getPayloadLength() {
+        int len = GENERIC_HEADER_LENGTH;
+
+        for (Proposal p : proposalList) len += p.getProposalLength();
+
+        return len;
+    }
+
+    /**
+     * Return the payload type as a String.
+     *
+     * @return the payload type as a String.
+     */
+    @Override
+    public String getTypeString() {
+        return "SA Payload";
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/message/IkeSkPayload.java b/src/java/com/android/ike/ikev2/message/IkeSkPayload.java
new file mode 100644
index 0000000..d753ee8
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeSkPayload.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import com.android.ike.ikev2.exceptions.IkeException;
+
+import java.nio.ByteBuffer;
+import java.security.GeneralSecurityException;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+
+/**
+ * IkeSkPayload represents a Encrypted Payload.
+ *
+ * <p>It contains other payloads in encrypted form. It is must be the last payload in the message.
+ * It should be the only payload in this implementation.
+ *
+ * <p>Critical bit must be ignored when doing decoding.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#page-105">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class IkeSkPayload extends IkePayload {
+
+    private final IkeEncryptedPayloadBody mIkeEncryptedPayloadBody;
+
+    /**
+     * Construct an instance of IkeSkPayload from decrypting an incoming packet.
+     *
+     * @param critical indicates if it is a critical payload.
+     * @param message the byte array contains the whole IKE message.
+     * @param integrityMac the initialized Mac for integrity check.
+     * @param checksumLen the checksum length of negotiated integrity algorithm.
+     * @param decryptCipher the uninitialized Cipher for doing decryption.
+     * @param dKey the decryption key.
+     */
+    IkeSkPayload(
+            boolean critical,
+            byte[] message,
+            Mac integrityMac,
+            int checksumLen,
+            Cipher decryptCipher,
+            SecretKey dKey)
+            throws IkeException, GeneralSecurityException {
+        super(PAYLOAD_TYPE_SK, critical);
+
+        mIkeEncryptedPayloadBody =
+                new IkeEncryptedPayloadBody(
+                        message, integrityMac, checksumLen, decryptCipher, dKey);
+    }
+
+    /**
+     * Construct an instance of IkeSkPayload for building outbound packet.
+     *
+     * @param ikeHeader the IKE header.
+     * @param firstPayloadType the type of first payload nested in SkPayload.
+     * @param unencryptedPayloads the encoded payload list to protect.
+     * @param integrityMac the initialized Mac for calculating integrity checksum
+     * @param checksumLen the checksum length of negotiated integrity algorithm.
+     * @param encryptCipher the uninitialized Cipher for doing encryption.
+     * @param eKey the encryption key.
+     */
+    IkeSkPayload(
+            IkeHeader ikeHeader,
+            @PayloadType int firstPayloadType,
+            byte[] unencryptedPayloads,
+            Mac integrityMac,
+            int checksumLen,
+            Cipher encryptCipher,
+            SecretKey eKey) {
+        super(PAYLOAD_TYPE_SK, false);
+
+        mIkeEncryptedPayloadBody =
+                new IkeEncryptedPayloadBody(
+                        ikeHeader,
+                        firstPayloadType,
+                        unencryptedPayloads,
+                        integrityMac,
+                        checksumLen,
+                        encryptCipher,
+                        eKey);
+    }
+
+    /**
+     * Return unencrypted payload list
+     *
+     * @return unencrypted payload list in a byte array.
+     */
+    public byte[] getUnencryptedPayloads() {
+        return mIkeEncryptedPayloadBody.getUnencryptedData();
+    }
+
+    // TODO: Add another constructor for AEAD protected payload.
+
+    /**
+     * Encode this payload to a ByteBuffer.
+     *
+     * @param nextPayload type of payload that follows this payload.
+     * @param byteBuffer destination ByteBuffer that stores encoded payload.
+     */
+    @Override
+    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
+        byteBuffer.put(mIkeEncryptedPayloadBody.encode());
+    }
+
+    /**
+     * Get entire payload length.
+     *
+     * @return entire payload length.
+     */
+    @Override
+    protected int getPayloadLength() {
+        return GENERIC_HEADER_LENGTH + mIkeEncryptedPayloadBody.getLength();
+    }
+
+    /**
+     * Return the payload type as a String.
+     *
+     * @return the payload type as a String.
+     */
+    @Override
+    public String getTypeString() {
+        return "Encrypted and Authenticated Payload";
+    }
+}
diff --git a/src/java/com/android/ike/ikev2/message/IkeTsPayload.java b/src/java/com/android/ike/ikev2/message/IkeTsPayload.java
new file mode 100644
index 0000000..8231e29
--- /dev/null
+++ b/src/java/com/android/ike/ikev2/message/IkeTsPayload.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import com.android.ike.ikev2.IkeTrafficSelector;
+import com.android.ike.ikev2.exceptions.IkeException;
+
+import java.nio.ByteBuffer;
+
+/**
+ * IkeTsPayload represents an Traffic Selector Initiator Payload or an Traffic Selector Responder
+ * Payload.
+ *
+ * <p>Traffic Selector Initiator Payload and Traffic Selector Responder Payload have same format but
+ * different payload types. They describe the address ranges and port ranges of Child SA initiator
+ * and Child SA responder.
+ *
+ * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.13">RFC 7296, Internet Key Exchange
+ *     Protocol Version 2 (IKEv2)</a>
+ */
+public final class IkeTsPayload extends IkePayload {
+    // Length of reserved field in octets.
+    private static final int TS_HEADER_RESERVED_LEN = 3;
+
+    /** Number of Traffic Selectors */
+    public final int numTs;
+    public final IkeTrafficSelector[] trafficSelectors;
+
+    IkeTsPayload(boolean critical, byte[] payloadBody, boolean isInitiator) throws IkeException {
+        super((isInitiator ? PAYLOAD_TYPE_TS_INITIATOR : PAYLOAD_TYPE_TS_RESPONDER), critical);
+
+        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
+        numTs = Byte.toUnsignedInt(inputBuffer.get());
+        // Skip RESERVED byte
+        inputBuffer.get(new byte[TS_HEADER_RESERVED_LEN]);
+
+        // Decode Traffic Selectors
+        byte[] tsBytes = new byte[inputBuffer.remaining()];
+        inputBuffer.get(tsBytes);
+        trafficSelectors = IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+    }
+
+    /**
+     * Encode Traffic Selector Payload to ByteBuffer.
+     *
+     * @param nextPayload type of payload that follows this payload.
+     * @param byteBuffer destination ByteBuffer that stores encoded payload.
+     */
+    @Override
+    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+        throw new UnsupportedOperationException(
+                "It is not supported to encode a " + getTypeString());
+        //TODO: Implement it.
+    }
+
+    /**
+     * Get entire payload length.
+     *
+     * @return entire payload length.
+     */
+    @Override
+    protected int getPayloadLength() {
+        throw new UnsupportedOperationException(
+                "It is not supported to get payload length of " + getTypeString());
+        //TODO: Implement it.
+    }
+
+    /**
+     * Return the payload type as a String.
+     *
+     * @return the payload type as a String.
+     */
+    @Override
+    public String getTypeString() {
+        switch (payloadType) {
+            case PAYLOAD_TYPE_ID_INITIATOR:
+                return "Traffic Selector Initiator Payload";
+            case PAYLOAD_TYPE_ID_RESPONDER:
+                return "Traffic Selector Responder Payload";
+            default:
+                // Won't reach here.
+                throw new IllegalArgumentException(
+                        "Invalid Payload Type for Traffic Selector Payload.");
+        }
+    }
+}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeUnsupportedPayload.java b/src/java/com/android/ike/ikev2/message/IkeUnsupportedPayload.java
similarity index 95%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeUnsupportedPayload.java
rename to src/java/com/android/ike/ikev2/message/IkeUnsupportedPayload.java
index ecfe1e9..4506621 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeUnsupportedPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeUnsupportedPayload.java
@@ -14,10 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import java.nio.ByteBuffer;
-
 /**
  * IkeUnsupportedPayload represents anunsupported payload.
  *
@@ -66,6 +65,6 @@
      */
     @Override
     public String getTypeString() {
-        return String.valueOf(payloadType);
+        return "Unsupported Payload";
     }
 }
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeVendorPayload.java b/src/java/com/android/ike/ikev2/message/IkeVendorPayload.java
similarity index 96%
rename from src/java/com/android/internal/net/ipsec/ike/message/IkeVendorPayload.java
rename to src/java/com/android/ike/ikev2/message/IkeVendorPayload.java
index d346407..8599653 100644
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeVendorPayload.java
+++ b/src/java/com/android/ike/ikev2/message/IkeVendorPayload.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import java.nio.ByteBuffer;
 
@@ -71,6 +71,6 @@
      */
     @Override
     public String getTypeString() {
-        return "Vendor";
+        return "Vendor ID Payload";
     }
 }
diff --git a/src/java/com/android/internal/net/utils/BigIntegerUtils.java b/src/java/com/android/ike/ikev2/utils/BigIntegerUtils.java
similarity index 98%
rename from src/java/com/android/internal/net/utils/BigIntegerUtils.java
rename to src/java/com/android/ike/ikev2/utils/BigIntegerUtils.java
index 09dad74..6104834 100644
--- a/src/java/com/android/internal/net/utils/BigIntegerUtils.java
+++ b/src/java/com/android/ike/ikev2/utils/BigIntegerUtils.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.internal.net.utils;
+package com.android.ike.ikev2.utils;
 
 import java.math.BigInteger;
 
diff --git a/src/java/com/android/internal/net/crypto/KeyGenerationUtils.java b/src/java/com/android/internal/net/crypto/KeyGenerationUtils.java
deleted file mode 100644
index c9ade7d..0000000
--- a/src/java/com/android/internal/net/crypto/KeyGenerationUtils.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.crypto;
-
-import java.nio.ByteBuffer;
-
-/**
- * KeyGenerationUtils is a util class that contains utils for key generation needed by IKEv2 and
- * EAP.
- */
-public class KeyGenerationUtils {
-    /**
-     * Returns the derived pseudorandom number with the specified length by iteratively applying a
-     * PRF.
-     *
-     * <p>prf+(K, S) outputs a pseudorandom stream by using the PRF iteratively. In this way it can
-     * generate long enough keying material containing all the keys.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.13">RFC 7296 Internet Key
-     *     Exchange Protocol Version 2 (IKEv2) 2.13. Generating Keying Material </a>
-     * @param byteSigner the PRF used to sign the given data using the given key.
-     * @param keyBytes the key to sign data.
-     * @param dataToSign the data to be signed.
-     * @param keyMaterialLen the length of keying materials to be generated.
-     * @return the byte array of keying materials
-     */
-    public static byte[] prfPlus(
-            ByteSigner byteSigner, byte[] keyBytes, byte[] dataToSign, int keyMaterialLen) {
-        ByteBuffer keyMatBuffer = ByteBuffer.allocate(keyMaterialLen);
-
-        byte[] previousMac = new byte[0];
-        final int padLen = 1;
-        byte padValue = 1;
-
-        while (keyMatBuffer.remaining() > 0) {
-            ByteBuffer dataToSignBuffer =
-                    ByteBuffer.allocate(previousMac.length + dataToSign.length + padLen);
-            dataToSignBuffer.put(previousMac).put(dataToSign).put(padValue);
-
-            previousMac = byteSigner.signBytes(keyBytes, dataToSignBuffer.array());
-
-            keyMatBuffer.put(
-                    previousMac, 0, Math.min(previousMac.length, keyMatBuffer.remaining()));
-
-            padValue++;
-        }
-
-        return keyMatBuffer.array();
-    }
-
-    /**
-     * ByteSigner is an interface to be used for implementing the byte-signing for generating keys
-     * using {@link KeyGenerationUtils#prfPlus(ByteSigner, byte[], byte[], int)}.
-     */
-    public interface ByteSigner {
-        /**
-         * Signs the given data using the key given.
-         *
-         * <p>Caller is responsible for providing a valid key according to their use cases.
-         *
-         * @param keyBytes the key to sign data.
-         * @param dataToSign the data to be signed.
-         * @return the signed value.
-         */
-        byte[] signBytes(byte[] keyBytes, byte[] dataToSign);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/EapAuthenticator.java b/src/java/com/android/internal/net/eap/EapAuthenticator.java
deleted file mode 100644
index a6869d7..0000000
--- a/src/java/com/android/internal/net/eap/EapAuthenticator.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-import com.android.internal.net.utils.Log;
-
-import java.security.SecureRandom;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeoutException;
-
-/**
- * EapAuthenticator represents an EAP peer implementation.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- * Protocol (EAP)</a>
- */
-public class EapAuthenticator extends Handler {
-    private static final String EAP_TAG = "EAP";
-    private static final boolean LOG_SENSITIVE = false;
-    public static final Log LOG = new Log(EAP_TAG, LOG_SENSITIVE);
-
-    private static final String TAG = EapAuthenticator.class.getSimpleName();
-    private static final long DEFAULT_TIMEOUT_MILLIS = 7000L;
-
-    private final Executor mWorkerPool;
-    private final EapStateMachine mStateMachine;
-    private final IEapCallback mCb;
-    private final long mTimeoutMillis;
-    private boolean mCallbackFired = false;
-
-    /**
-     * Constructor for EapAuthenticator
-     *
-     * @param looper Looper for running a message loop
-     * @param cb IEapCallback for callbacks to the client
-     * @param context Context for this EapAuthenticator
-     * @param eapSessionConfig Configuration for an EapAuthenticator
-     */
-    public EapAuthenticator(
-            Looper looper,
-            IEapCallback cb,
-            Context context,
-            EapSessionConfig eapSessionConfig) {
-        this(
-                looper,
-                cb,
-                new EapStateMachine(context, eapSessionConfig, new SecureRandom()),
-                Executors.newSingleThreadExecutor(),
-                DEFAULT_TIMEOUT_MILLIS);
-    }
-
-    @VisibleForTesting
-    EapAuthenticator(
-            Looper looper,
-            IEapCallback cb,
-            EapStateMachine eapStateMachine,
-            Executor executor,
-            long timeoutMillis) {
-        super(looper);
-
-        mCb = cb;
-        mStateMachine = eapStateMachine;
-        mWorkerPool = executor;
-        mTimeoutMillis = timeoutMillis;
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        // No messages processed here. Only runnables. Drop all messages.
-    }
-
-    /**
-     * Processes the given msgBytes within the context of the current EAP Session.
-     *
-     * <p>If the given message is successfully processed, the relevant {@link IEapCallback} function
-     * is used. Otherwise, {@link IEapCallback#onError(Throwable)} is called.
-     *
-     * @param msgBytes the byte-array encoded EAP message to be processed
-     */
-    public void processEapMessage(byte[] msgBytes) {
-        // reset
-        mCallbackFired = false;
-
-        postDelayed(
-                () -> {
-                    if (!mCallbackFired) {
-                        // Fire failed callback
-                        mCallbackFired = true;
-                        LOG.e(TAG, "Timeout occurred in EapStateMachine");
-                        mCb.onError(new TimeoutException("Timeout while processing message"));
-                    }
-                },
-                EapAuthenticator.this,
-                mTimeoutMillis);
-
-        // proxy to worker thread for async processing
-        mWorkerPool.execute(
-                () -> {
-                    // Any unhandled exceptions within the state machine are caught here to make
-                    // sure that the caller does not wait for the full timeout duration before being
-                    // notified of a failure.
-                    EapResult processResponse;
-                    try {
-                        processResponse = mStateMachine.process(msgBytes);
-                    } catch (Exception ex) {
-                        LOG.e(TAG, "Exception thrown while processing message", ex);
-                        processResponse = new EapError(ex);
-                    }
-
-                    final EapResult finalProcessResponse = processResponse;
-                    EapAuthenticator.this.post(
-                            () -> {
-                                // No synchronization needed, since Handler serializes
-                                if (!mCallbackFired) {
-                                    LOG.i(
-                                            TAG,
-                                            "EapStateMachine returned "
-                                                    + finalProcessResponse
-                                                            .getClass()
-                                                            .getSimpleName());
-
-                                    if (finalProcessResponse instanceof EapResponse) {
-                                        mCb.onResponse(((EapResponse) finalProcessResponse).packet);
-                                    } else if (finalProcessResponse instanceof EapError) {
-                                        EapError eapError = (EapError) finalProcessResponse;
-                                        LOG.e(
-                                                TAG,
-                                                "EapError returned with cause=" + eapError.cause);
-                                        mCb.onError(eapError.cause);
-                                    } else if (finalProcessResponse instanceof EapSuccess) {
-                                        EapSuccess eapSuccess = (EapSuccess) finalProcessResponse;
-                                        LOG.d(
-                                                TAG,
-                                                "EapSuccess with"
-                                                        + " MSK=" + LOG.pii(eapSuccess.msk)
-                                                        + " EMSK=" + LOG.pii(eapSuccess.msk));
-                                        mCb.onSuccess(eapSuccess.msk, eapSuccess.emsk);
-                                    } else { // finalProcessResponse instanceof EapFailure
-                                        mCb.onFail();
-                                    }
-
-                                    mCallbackFired = true;
-
-                                    // Ensure delayed timeout runnable does not fire
-                                    EapAuthenticator.this.removeCallbacksAndMessages(
-                                            EapAuthenticator.this);
-                                }
-                            });
-                });
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/EapResult.java b/src/java/com/android/internal/net/eap/EapResult.java
deleted file mode 100644
index 894dd47..0000000
--- a/src/java/com/android/internal/net/eap/EapResult.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.exceptions.InvalidEapResponseException;
-import com.android.internal.net.eap.message.EapMessage;
-
-/**
- * EapResult represents the return type R for a process operation within the EapStateMachine.
- */
-public abstract class EapResult {
-
-    /**
-     * EapSuccess represents a success response from the EapStateMachine.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication
-     * Protocol (EAP)</a>
-     */
-    public static class EapSuccess extends EapResult {
-        public final byte[] msk;
-        public final byte[] emsk;
-
-        public EapSuccess(@NonNull byte[] msk, @NonNull byte[] emsk) {
-            if (msk == null || emsk == null) {
-                throw new IllegalArgumentException("msk and emsk must not be null");
-            }
-            this.msk = msk;
-            this.emsk = emsk;
-        }
-    }
-
-    /**
-     * EapFailure represents a failure response from the EapStateMachine.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication
-     * Protocol (EAP)</a>
-     */
-    public static class EapFailure extends EapResult {}
-
-    /**
-     * EapResponse represents an outgoing message from the EapStateMachine.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication
-     * Protocol (EAP)</a>
-     */
-    public static class EapResponse extends EapResult {
-        public final byte[] packet;
-
-        @VisibleForTesting
-        protected EapResponse(byte[] packet) {
-            this.packet = packet;
-        }
-
-        /**
-         * Constructs and returns an EapResult for the given EapMessage.
-         *
-         * <p>If the given EapMessage is not of type EAP-Response, an EapError object will be
-         * returned.
-         *
-         * @param message the EapMessage to be encoded in the EapResponse instance.
-         * @return an EapResponse instance for the given message. If message.eapCode != {@link
-         * EapMessage#EAP_CODE_RESPONSE}, an EapError instance is returned.
-         */
-        public static EapResult getEapResponse(@NonNull EapMessage message) {
-            if (message == null) {
-                throw new IllegalArgumentException("EapMessage should not be null");
-            } else if (message.eapCode != EapMessage.EAP_CODE_RESPONSE) {
-                return new EapError(new InvalidEapResponseException(
-                        "Cannot construct an EapResult from a non-EAP-Response message"));
-            }
-
-            return new EapResponse(message.encode());
-        }
-    }
-
-    /**
-     * EapError represents an error that occurred in the EapStateMachine.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc3748">RFC 3748, Extensible Authentication
-     * Protocol (EAP)</a>
-     */
-    public static class EapError extends EapResult {
-        public final Exception cause;
-
-        /**
-         * Constructs an EapError instance for the given cause.
-         *
-         * @param cause the Exception that caused the EapError to be returned from the
-         *              EapStateMachine
-         */
-        public EapError(Exception cause) {
-            this.cause = cause;
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/IEapCallback.java b/src/java/com/android/internal/net/eap/IEapCallback.java
deleted file mode 100644
index fae3edf..0000000
--- a/src/java/com/android/internal/net/eap/IEapCallback.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-/**
- * IEapCallback represents a Callback interface to be implemented by clients of the
- * {@link EapAuthenticator}.
- *
- * <p>Exactly one of these callbacks will be called for each message processed by the
- * {@link EapAuthenticator}.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- * Protocol (EAP)</a>
- */
-public interface IEapCallback {
-    /**
-     * Callback used to indicate that the EAP Authentication session was successful.
-     *
-     * @param msk The Master Session Key (MSK) generated in the session
-     * @param emsk The Extended Master Session Key (EMSK) generated in the session
-     */
-    void onSuccess(byte[] msk, byte[] emsk);
-
-    /**
-     * Callback used to indicate that the EAP Authentication Session was unsuccessful.
-     */
-    void onFail();
-
-    /**
-     * Callback used to return an EAP-Response message for the message being processed.
-     *
-     * @param eapMsg byte-array encoded EAP-Response message to be sent to the Authentication server
-     */
-    void onResponse(byte[] eapMsg);
-
-    /**
-     * Callback used to indicate that there was an error processing the current EAP message.
-     *
-     * @param cause The cause of the processing error
-     */
-    void onError(Throwable cause);
-}
diff --git a/src/java/com/android/internal/net/eap/crypto/Fips186_2Prf.java b/src/java/com/android/internal/net/eap/crypto/Fips186_2Prf.java
deleted file mode 100644
index fb1268c..0000000
--- a/src/java/com/android/internal/net/eap/crypto/Fips186_2Prf.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.eap.crypto;
-
-import static com.android.internal.net.utils.BigIntegerUtils.bigIntegerToUnsignedByteArray;
-import static com.android.internal.net.utils.BigIntegerUtils.unsignedByteArrayToBigInteger;
-
-import com.android.org.bouncycastle.crypto.digests.SHA1Digest;
-
-import java.math.BigInteger;
-import java.nio.ByteBuffer;
-
-/**
- * This class implements the Pseudo-Random Number Generator as specified by FIPS 186-2, change
- * notice 1, as required by EAP-SIM (RFC 4186) and EAP-AKA (RFC 4187).
- *
- * <p>Simplifying constraints allow for some parameters to be permanently fixed: The "b" parameter
- * is specified to always be 160 by RFC 4186. Likewise, the seed must be 20 bytes and therefore can
- * never exceed 2^b.
- */
-public class Fips186_2Prf {
-    private static final int SEED_LEN_BYTES = 20;
-    private static final int SHA_OUTPUT_LEN_BYTES = 40;
-
-    /**
-     * Gets the next random based on the PRF described in FIPS 186-2, Change Notice 1.
-     *
-     * @param seed the seed value
-     * @param outputLenBytes the output byte count required. Will run multiple iterations as needed.
-     * @return the byte-array random result
-     */
-    public byte[] getRandom(byte[] seed, int outputLenBytes) {
-        if (seed.length != SEED_LEN_BYTES) {
-            throw new IllegalArgumentException("Invalid seed length. Must be 160b (20B)");
-        }
-
-        BigInteger xkey = unsignedByteArrayToBigInteger(seed);
-        BigInteger exp_b = new BigInteger("2").pow(SEED_LEN_BYTES * 8);
-
-        ByteBuffer buffer = ByteBuffer.allocate(outputLenBytes);
-
-        // RFC 4186, Appendix B, Step 3:
-        //     M is the number of generation runs, based on the desired output bytes (rounded up)
-        //     EAP SIM/AKA require at least 16 (K_ENCR) + 16 (K_AUTH) + 64 (MSK) + 64 (EMSK) bytes
-        //     (total 160 Bytes)
-        int numIterations = (outputLenBytes + SHA_OUTPUT_LEN_BYTES - 1) / SHA_OUTPUT_LEN_BYTES;
-        for (int j = 0; j < numIterations; j++) {
-            for (int i = 0; i < 2; i++) {
-                // RFC 4186, Appendix B, Step 3.1 XSEED_j = 0
-                //     (XSEED_j unused, omitted)
-
-                // RFC 4186, Appendix B, Step 3.2a: XVAL = (XKEY + XSEED_j) mod 2^b
-                //     (XSEED_j unused, omitted)
-                BigInteger xval = xkey.mod(exp_b);
-
-                // RFC 4186, Appendix B, Step 3.2b:
-                //     w_i = G(t, XVAL)
-                byte[] w_i = new byte[SEED_LEN_BYTES];
-                Sha1_186_2_FunctionG digest = new Sha1_186_2_FunctionG();
-                digest.update(
-                        bigIntegerToUnsignedByteArray(xval, SEED_LEN_BYTES), 0, SEED_LEN_BYTES);
-                digest.doFinal(w_i, 0);
-
-                // RFC 4186, Appendix B, Step 3.2c:
-                //     XKEY = (1 + XKEY + w_i) mod 2^b
-                xkey = xkey.add(BigInteger.ONE).add(unsignedByteArrayToBigInteger(w_i));
-                xkey = xkey.mod(exp_b);
-
-                // RFC 4186, Appendix B, Step 3.3:
-                //     x_j = w_0|w_1
-                buffer.put(w_i, 0, Math.min(buffer.remaining(), w_i.length));
-            }
-        }
-
-        return buffer.array();
-    }
-
-    /**
-     * This inner class represents the modifications to the SHA1 digest required for FIPS 186-2 PRFs
-     *
-     * <p>FIPS 186-2 requires the use of a hashing function with exactly the same transforms as
-     * SHA1, but with a slightly different padding (all 0s instead of appending additional metadata
-     * for entropy).
-     *
-     * <p>Specifically, this function extends BouncyCastle's SHA1Digest in order to override the
-     * finish method, preventing the additional padding bytes from being appended (leaving them all
-     * 0).
-     */
-    private static class Sha1_186_2_FunctionG extends SHA1Digest {
-        // IV (t) specified by SHA-1; Use default.
-
-        @Override
-        public void finish() {
-            // Don't do any other processing. We only care about the processBlock() functionality.
-            processBlock();
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSigner.java b/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSigner.java
deleted file mode 100644
index db6e4b3..0000000
--- a/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSigner.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.crypto;
-
-import com.android.internal.net.crypto.KeyGenerationUtils;
-import com.android.internal.net.crypto.KeyGenerationUtils.ByteSigner;
-
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * HmacSha256ByteSigner is a {@link ByteSigner} to be used for computing HMAC-SHA-256 values for
- * specific keys and data.
- */
-public class HmacSha256ByteSigner implements KeyGenerationUtils.ByteSigner {
-    private static final String TAG = HmacSha256ByteSigner.class.getSimpleName();
-    private static final String MAC_ALGORITHM_STRING = "HmacSHA256";
-    private static final HmacSha256ByteSigner sInstance = new HmacSha256ByteSigner();
-
-    /**
-     * Gets instance of HmacSha256ByteSigner.
-     *
-     * @return HmacSha256ByteSigner instance.
-     */
-    public static HmacSha256ByteSigner getInstance() {
-        return sInstance;
-    }
-
-    @Override
-    public byte[] signBytes(byte[] keyBytes, byte[] dataToSign) {
-        try {
-            Mac mac = Mac.getInstance(MAC_ALGORITHM_STRING);
-            mac.init(new SecretKeySpec(keyBytes, MAC_ALGORITHM_STRING));
-            return mac.doFinal(dataToSign);
-        } catch (NoSuchAlgorithmException | InvalidKeyException ex) {
-            throw new IllegalArgumentException(ex);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/crypto/ParityBitUtil.java b/src/java/com/android/internal/net/eap/crypto/ParityBitUtil.java
deleted file mode 100644
index 6413ade..0000000
--- a/src/java/com/android/internal/net/eap/crypto/ParityBitUtil.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.crypto;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * This class sets parity-bits for a given byte-array as specified by the MSCHAPv2 standard.
- *
- * @see <a href="https://tools.ietf.org/html/rfc2759">RFC 2759, Microsoft PPP CHAP Extensions,
- *     Version 2 (MSCHAPv2)</a>
- */
-public class ParityBitUtil {
-    private static final int INPUT_LENGTH = 7;
-    private static final int OUTPUT_LENGTH = 8;
-    private static final int BITS_PER_BYTE = 8;
-    private static final int BITS_PER_PARITY_BIT = 7;
-    private static final byte MASK = (byte) 0xFE;
-
-    /**
-     * Computes and returns a byte[] with the odd-parity bits set.
-     *
-     * <p>Parity bits are set for the 8th, 16th, 24th, etc. bits as the LSB for each byte.
-     *
-     * @param input byte[] the input data requiring parity bits
-     * @return byte[] the input byte[] with its parity-bits set
-     * @throws IllegalArgumentException iff the given data array does not contain 7 bytes
-     */
-    public static byte[] addParityBits(byte[] input) {
-        if (input.length != INPUT_LENGTH) {
-            throw new IllegalArgumentException("Data must be 7B long");
-        }
-        byte[] output = new byte[OUTPUT_LENGTH];
-
-        long allBits = byteArrayToLong(input) << 1; // make room for parity bit
-
-        // allBits stores input bits as [b56, ..., b1, 0]. Consuming allBits in reverse populates
-        // output with a right shift
-        for (int i = output.length - 1; i >= 0; i--) {
-            output[i] = getByteWithParityBit((byte) allBits);
-            allBits >>= BITS_PER_PARITY_BIT;
-        }
-
-        return output;
-    }
-
-    @VisibleForTesting
-    static byte getByteWithParityBit(byte b) {
-        // Parity bits per RFC 2759#8.6
-        byte parity =
-                (byte) ((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1));
-
-        // If we have an odd number of bits, b1 should be 0.
-        // If we have an even number of bits, b1 should be 1.
-        byte parityBit = (byte) (~parity & 1);
-        return (byte) ((b & MASK) | parityBit);
-    }
-
-    @VisibleForTesting
-    static long byteArrayToLong(byte[] input) {
-        long result = 0;
-        for (int i = 0; i < input.length; i++) {
-            result = (result << BITS_PER_BYTE) | Byte.toUnsignedInt(input[i]);
-        }
-        return result;
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/EapInvalidPacketLengthException.java b/src/java/com/android/internal/net/eap/exceptions/EapInvalidPacketLengthException.java
deleted file mode 100644
index ca6d4da..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/EapInvalidPacketLengthException.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions;
-
-import com.android.internal.net.eap.message.EapMessage;
-
-/**
- * This exception is thrown when the Packet Length for an {@link EapMessage} is invalid.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- *     Protocol (EAP)</a>
- */
-public class EapInvalidPacketLengthException extends EapSilentException {
-    /**
-     * Construct an instance of EapInvalidPacketLengthException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapInvalidPacketLengthException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapInvalidPacketLengthException with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapInvalidPacketLengthException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/EapInvalidRequestException.java b/src/java/com/android/internal/net/eap/exceptions/EapInvalidRequestException.java
deleted file mode 100644
index 8dee31a..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/EapInvalidRequestException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions;
-
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-
-/**
- * EapInvalidRequestException is thrown when invalid EapMessages are attempted to be processed by
- * the {@link EapStateMachine}.
- */
-public class EapInvalidRequestException extends Exception {
-    /**
-     * Construct an instance of EapInvalidRequestException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapInvalidRequestException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapInvalidRequestException with the specified message and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapInvalidRequestException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/EapSilentException.java b/src/java/com/android/internal/net/eap/exceptions/EapSilentException.java
deleted file mode 100644
index 3cb9211..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/EapSilentException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions;
-
-/**
- * EapSilentException represents a category of EAP errors that should be silently discarded by
- * authenticators and peers.
- *
- * <p>EapSilentException is so-named due to its role in the EAP standard. RFC 3748 requires that
- * several error cases be "silently discarded". In these cases, no EAP-Response message will be sent
- * to the Authenticator. However, when thrown SilentExceptions will still signal an EAP failure to
- * the IKE library calling it, resulting in an Authentication failure.
- *
- * Each type of silent error should implement its own subclass.
- */
-public abstract class EapSilentException extends Exception {
-    /**
-     * Construct an instance of EapSilentException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapSilentException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSilentException with the specified message and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSilentException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/InvalidEapCodeException.java b/src/java/com/android/internal/net/eap/exceptions/InvalidEapCodeException.java
deleted file mode 100644
index 17a0c4d..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/InvalidEapCodeException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions;
-
-import com.android.internal.net.eap.message.EapMessage;
-
-/**
- * This exception is thrown when the EAP Code for an {@link EapMessage} is invalid.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- *     Protocol (EAP)</a>
- */
-public class InvalidEapCodeException extends EapSilentException {
-    /**
-     * Construct an instance of InvalidEapCodeException with the specified code.
-     *
-     * @param code The invalid code type
-     */
-    public InvalidEapCodeException(int code) {
-        super("Invalid Code included in EapMessage: " + code);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/InvalidEapResponseException.java b/src/java/com/android/internal/net/eap/exceptions/InvalidEapResponseException.java
deleted file mode 100644
index c0a12e2..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/InvalidEapResponseException.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions;
-
-/**
- * InvalidEapResponseException is thrown when an invalid EapResponse is attempted to be constructed.
- *
- * <p>EapResponses can only be constructed from EapMessages with the EAP Code for Responses (2).
- */
-public class InvalidEapResponseException extends Exception {
-
-    /**
-     * Construct an instance of InvalidEapResponseException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public InvalidEapResponseException(String message) {
-        super(message);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/UnsupportedEapTypeException.java b/src/java/com/android/internal/net/eap/exceptions/UnsupportedEapTypeException.java
deleted file mode 100644
index f128385..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/UnsupportedEapTypeException.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions;
-
-import com.android.internal.net.eap.message.EapData.EapType;
-import com.android.internal.net.eap.message.EapMessage;
-
-/**
- * UnsupportedEapTypeException is thrown when an {@link EapMessage} is constructed with an
- * unsupported {@link EapType} value.
- */
-public class UnsupportedEapTypeException extends EapSilentException {
-    public final int eapIdentifier;
-
-    /**
-     * Construct an instance of UnsupportedEapTypeException with the specified detail message.
-     *
-     * @param eapIdentifier the EAP Identifier for the message that contained the unsupported
-     *                      EapType
-     * @param message the detail message.
-     */
-    public UnsupportedEapTypeException(int eapIdentifier, String message) {
-        super(message);
-        this.eapIdentifier = eapIdentifier;
-    }
-
-    /**
-     * Construct an instance of UnsupportedEapTypeException with the specified message and cause.
-     *
-     * @param eapIdentifier the EAP Identifier for the message that contained the unsupported
-     *                      EapType
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public UnsupportedEapTypeException(int eapIdentifier, String message, Throwable cause) {
-        super(message, cause);
-        this.eapIdentifier = eapIdentifier;
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/mschapv2/EapMsChapV2ParsingException.java b/src/java/com/android/internal/net/eap/exceptions/mschapv2/EapMsChapV2ParsingException.java
deleted file mode 100644
index 09f1fae..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/mschapv2/EapMsChapV2ParsingException.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.mschapv2;
-
-/**
- * EapMsChapV2ParsingException is thrown when an invalid MS-CHAPv2 Type Data is attempted to be
- * processed.
- */
-public class EapMsChapV2ParsingException extends Exception {
-    /**
-     * Construct an instance of EapMsChapV2ParsingException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapMsChapV2ParsingException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapMsChapV2ParsingException with the specified message and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapMsChapV2ParsingException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapAkaInvalidAuthenticationResponse.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapAkaInvalidAuthenticationResponse.java
deleted file mode 100644
index 7310d78..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapAkaInvalidAuthenticationResponse.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-/**
- * EapAkaInvalidAuthenticationResponse is thrown when a UICC Challenge is processed during an
- * EAP-AKA session and an invalid response format is returned.
- */
-public class EapAkaInvalidAuthenticationResponse extends EapSimAkaAuthenticationFailureException {
-    /**
-     * Construct an instance of EapAkaInvalidAuthenticationResponse with the specified detail
-     * message.
-     *
-     * @param message the detail message.
-     */
-    public EapAkaInvalidAuthenticationResponse(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapAkaInvalidAuthenticationResponse with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapAkaInvalidAuthenticationResponse(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaAuthenticationFailureException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaAuthenticationFailureException.java
deleted file mode 100644
index 699f22e..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaAuthenticationFailureException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-/**
- * EapSimAkaAuthenticationFailureException is thrown when an invalid Uicc Challenge is processed
- * during an EAP-SIM or EAP-AKA session.
- */
-public class EapSimAkaAuthenticationFailureException extends Exception {
-    /**
-     * Construct an instance of EapSimAkaAuthenticationFailureException with the specified detail
-     * message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimAkaAuthenticationFailureException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimAkaAuthenticationFailureException with the specified message
-     * and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimAkaAuthenticationFailureException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaIdentityUnavailableException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaIdentityUnavailableException.java
deleted file mode 100644
index 6a42171..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaIdentityUnavailableException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import android.telephony.TelephonyManager;
-
-/**
- * EapSimAkaIdentityUnavailableException is thrown when the client's IMSI is unavailable from
- * {@link TelephonyManager#getSubscriberId()}.
- */
-public class EapSimAkaIdentityUnavailableException extends Exception {
-    /**
-     * Construct an instance of EapSimAkaIdentityUnavailableException with the specified detail
-     * message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimAkaIdentityUnavailableException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimAkaIdentityUnavailableException with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimAkaIdentityUnavailableException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidAtPaddingException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidAtPaddingException.java
deleted file mode 100644
index 34a8f04..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidAtPaddingException.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPadding;
-
-/**
- * EapSimAkaInvalidAtPaddingException is thrown when an {@link AtPadding} with invalid padding is
- * parsed. Per RFC 4186#10.12 and RFC 4187#10.12, all padding bytes must be 0x00.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186#section-10.12">RFC 4186, EAP-SIM, Section
- * 10.12</a>
- * @see <a href="https://tools.ietf.org/html/rfc4187#section-10.12">RFC 4187, EAP-AKA, Section
- * 10.12</a>
- */
-public class EapSimAkaInvalidAtPaddingException extends EapSimAkaInvalidAttributeException {
-    /**
-     * Construct an instance of EapSimAkaInvalidAtPaddingException with the specified detail
-     * message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimAkaInvalidAtPaddingException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimAkaInvalidAtPaddingException with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimAkaInvalidAtPaddingException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidAttributeException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidAttributeException.java
deleted file mode 100644
index eff0c0c..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidAttributeException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-
-/**
- * EapSimAkaInvalidAttributeException is thrown when an invalid {@link EapSimAkaAttribute} is
- * attempted to be parsed.
- */
-public class EapSimAkaInvalidAttributeException extends Exception {
-    /**
-     * Construct an instance of EapSimAkaInvalidAttributeException with the specified detail
-     * message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimAkaInvalidAttributeException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimAkaInvalidAttributeException with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimAkaInvalidAttributeException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidLengthException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidLengthException.java
deleted file mode 100644
index c484b11..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaInvalidLengthException.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import android.telephony.TelephonyManager;
-
-/**
- * EapSimAkaInvalidLengthException is thrown when
- * {@link TelephonyManager#getIccAuthentication(int, int, String)} returns responses with the wrong
- * lengths.
- */
-public class EapSimAkaInvalidLengthException extends Exception {
-    /**
-     * Construct an instance of EapSimAkaInvalidLengthException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimAkaInvalidLengthException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimAkaInvalidLengthException with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimAkaInvalidLengthException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaUnsupportedAttributeException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaUnsupportedAttributeException.java
deleted file mode 100644
index 1128917..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimAkaUnsupportedAttributeException.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-
-/**
- * EapSimAkaUnsupportedAttributeException is thrown when an unsupported {@link EapSimAkaAttribute}
- * is attempted to be decoded.
- *
- * <p>Attributes are supported or not supported per the EAP method being used. For example, an
- * {@link AtVersionList} attribute would be considered "supported" when decoded from an EAP-SIM
- * context, but would be considered "unsupported" from an EAP-AKA context.
- */
-public class EapSimAkaUnsupportedAttributeException extends Exception {
-    /**
-     * Construct an instance of EapSimAkaUnsupportedAttributeException with the specified detail
-     * message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimAkaUnsupportedAttributeException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimAkaUnsupportedAttributeException with the specified message
-     * and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimAkaUnsupportedAttributeException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimInvalidAtRandException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimInvalidAtRandException.java
deleted file mode 100644
index c1b9200..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimInvalidAtRandException.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim;
-
-/**
- * EapSimInvalidAtRandException is thrown when an {@link AtRandSim} with an invalid number of RAND
- * values is parsed. When this error is encountered, an EAP-Response/SIM/Client-Error response must
- * be used. Note that there MUST BE 2 or 3 RAND values for the AtRandSim to be considered valid.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186#section-10.9">RFC 4186, EAP-SIM, Section
- * 10.9</a>
- */
-public class EapSimInvalidAtRandException extends EapSimAkaInvalidAttributeException {
-    /**
-     * Construct an instance of EapSimInvalidAtRandException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimInvalidAtRandException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimInvalidAtRandException with the specified message and
-     * cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimInvalidAtRandException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimInvalidTypeDataException.java b/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimInvalidTypeDataException.java
deleted file mode 100644
index a6a2d45..0000000
--- a/src/java/com/android/internal/net/eap/exceptions/simaka/EapSimInvalidTypeDataException.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.exceptions.simaka;
-
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-
-/**
- * EapSimInvalidTypeDataException is thrown when invalid {@link EapSimTypeData} are attempted to be
- * parsed.
- */
-public class EapSimInvalidTypeDataException extends Exception {
-    /**
-     * Construct an instance of EapSimInvalidTypeDataException with the specified detail message.
-     *
-     * @param message the detail message.
-     */
-    public EapSimInvalidTypeDataException(String message) {
-        super(message);
-    }
-
-    /**
-     * Construct an instance of EapSimInvalidTypeDataException with the specified message and cause.
-     *
-     * @param message the detail message.
-     * @param cause the cause.
-     */
-    public EapSimInvalidTypeDataException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/EapData.java b/src/java/com/android/internal/net/eap/message/EapData.java
deleted file mode 100644
index 86dc43b..0000000
--- a/src/java/com/android/internal/net/eap/message/EapData.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * EapData represents the data-bytes of an EAP-Packet.
- *
- * <p>EapData objects will always have a Type-value and the Type-Data bytes that follow.
- *
- * EapData objects should be parsed from the Type and Type-Data sections of an EAP Packet, as shown
- * below:
- *
- * +-----------------+-----------------+----------------------------------+
- * |   Code (1B)     | Identifier (1B) |           Length (2B)            |
- * +-----------------+-----------------+----------------------------------+
- * |    Type (1B)    |  Type-Data ...
- * +-----------------+-----
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- * Protocol (EAP)</a>
- */
-public class EapData {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        EAP_IDENTITY,
-        EAP_NOTIFICATION,
-        EAP_NAK,
-        EAP_TYPE_SIM,
-        EAP_TYPE_AKA,
-        EAP_TYPE_MSCHAP_V2,
-        EAP_TYPE_AKA_PRIME
-    })
-    public @interface EapType {}
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            EAP_TYPE_SIM,
-            EAP_TYPE_AKA,
-            EAP_TYPE_MSCHAP_V2,
-            EAP_TYPE_AKA_PRIME
-    })
-    public @interface EapMethod {}
-
-    // EAP Type values defined by IANA
-    // https://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml
-    public static final int EAP_IDENTITY = 1;
-    public static final int EAP_NOTIFICATION = 2;
-    public static final int EAP_NAK = 3;
-    // EAP_MD5_CHALLENGE unsupported, allowable based on RFC 3748, Section 5.4
-    public static final int EAP_TYPE_SIM = 18;
-    public static final int EAP_TYPE_AKA = 23;
-    public static final int EAP_TYPE_MSCHAP_V2 = 26;
-    public static final int EAP_TYPE_AKA_PRIME = 50;
-
-    public static final Map<Integer, String> EAP_TYPE_STRING = new HashMap<>();
-    static {
-        EAP_TYPE_STRING.put(EAP_IDENTITY, "Identity");
-        EAP_TYPE_STRING.put(EAP_NOTIFICATION, "Notification");
-        EAP_TYPE_STRING.put(EAP_NAK, "Nak");
-        EAP_TYPE_STRING.put(EAP_TYPE_SIM, "EAP-SIM");
-        EAP_TYPE_STRING.put(EAP_TYPE_AKA, "EAP-AKA");
-        EAP_TYPE_STRING.put(EAP_TYPE_MSCHAP_V2, "EAP-MSCHAP-V2");
-        EAP_TYPE_STRING.put(EAP_TYPE_AKA_PRIME, "EAP-AKA-PRIME");
-    }
-
-    private static final Set<Integer> SUPPORTED_TYPES = new HashSet<>();
-    static {
-        SUPPORTED_TYPES.add(EAP_IDENTITY);
-        SUPPORTED_TYPES.add(EAP_NOTIFICATION);
-        SUPPORTED_TYPES.add(EAP_NAK);
-
-        // supported EAP Method types
-        SUPPORTED_TYPES.add(EAP_TYPE_SIM);
-        SUPPORTED_TYPES.add(EAP_TYPE_AKA);
-        SUPPORTED_TYPES.add(EAP_TYPE_MSCHAP_V2);
-        SUPPORTED_TYPES.add(EAP_TYPE_AKA_PRIME);
-    }
-
-    @EapType public final int eapType;
-    public final byte[] eapTypeData;
-
-    public static final EapData NOTIFICATION_DATA = new EapData(EAP_NOTIFICATION, new byte[0]);
-
-    /**
-     * Constructs a new EapData instance.
-     *
-     * @param eapType the {@link EapType} for this EapData instance
-     * @param eapTypeData the Type-Data for this EapData instance
-     * @throws IllegalArgumentException if eapTypeData is null or if
-     *         {@link EapData#isSupportedEapType} is false for the given eapType
-     */
-    public EapData(@EapType int eapType, @NonNull byte[] eapTypeData) {
-        this.eapType = eapType;
-        this.eapTypeData = eapTypeData;
-
-        validate();
-    }
-
-    /**
-     * Gets the length of this EapData object.
-     *
-     * @return int for the number of bytes this EapData object represents
-     */
-    public int getLength() {
-        // length of byte-array + 1 (for 1B type field)
-        return eapTypeData.length + 1;
-    }
-
-    /**
-     * Returns whether this instance is equal to the given Object o.
-     *
-     * @param o the Object to be tested for equality
-     * @return true iff this instance is equal to the given o
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || !(o instanceof EapData)) {
-            return false;
-        }
-        EapData eapData = (EapData) o;
-        return eapType == eapData.eapType
-                && Arrays.equals(eapTypeData, eapData.eapTypeData);
-    }
-
-    /**
-     * Returns the hashCode value for this instance.
-     *
-     * @return the hashCode value for this instance
-     */
-    @Override
-    public int hashCode() {
-        return Objects.hash(eapType, Arrays.hashCode(eapTypeData));
-    }
-
-    /**
-     * Puts the byte-encoding for this EapData instance into the given ByteBuffer.
-     *
-     * @param b the ByteBuffer to write this EapData instance to
-     */
-    public void encodeToByteBuffer(ByteBuffer b) {
-        b.put((byte) eapType);
-        b.put(eapTypeData);
-    }
-
-    /**
-     * Returns whether the given eapType is a supported {@link EapType} value.
-     *
-     * @param eapType the value to be checked
-     * @return true iff the given eapType is a supported EAP Type
-     */
-    public static boolean isSupportedEapType(int eapType) {
-        return SUPPORTED_TYPES.contains(eapType);
-    }
-
-    private void validate() {
-        if (this.eapTypeData == null) {
-            throw new IllegalArgumentException("EapTypeData byte[] must be non-null");
-        }
-        if (!isSupportedEapType(this.eapType)) {
-            throw new IllegalArgumentException("eapType must be be a valid @EapType value");
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/EapMessage.java b/src/java/com/android/internal/net/eap/message/EapMessage.java
deleted file mode 100644
index bb1c632..0000000
--- a/src/java/com/android/internal/net/eap/message/EapMessage.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_NAK;
-import static com.android.internal.net.eap.message.EapData.NOTIFICATION_DATA;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidPacketLengthException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.InvalidEapCodeException;
-import com.android.internal.net.eap.exceptions.UnsupportedEapTypeException;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * EapMessage represents an EAP Message.
- *
- * <p>EapMessages will be of type:
- * <ul>
- *     <li>@{link EAP_CODE_REQUEST}</li>
- *     <li>@{link EAP_CODE_RESPONSE}</li>
- *     <li>@{link EAP_CODE_SUCCESS}</li>
- *     <li>@{link EAP_CODE_FAILURE}</li>
- * </ul>
- *
- * Per RFC 3748 Section 4, EAP-Request and EAP-Response packets should be in the format:
- *
- * +-----------------+-----------------+----------------------------------+
- * |    Code (1B)    | Identifier (1B) |           Length (2B)            |
- * +-----------------+-----------------+----------------------------------+
- * |    Type (1B)    |  Type-Data ...
- * +-----------------+-----
- *
- * EAP-Success and EAP-Failure packets should be in the format:
- *
- * +-----------------+-----------------+----------------------------------+
- * |   Code (1B)     | Identifier (1B) |       Length (2B) = '0004'       |
- * +-----------------+-----------------+----------------------------------+
- *
- * Note that Length includes the EAP Header bytes.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- * Protocol (EAP)</a>
- */
-public class EapMessage {
-    private static final String TAG = EapMessage.class.getSimpleName();
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-            EAP_CODE_REQUEST,
-            EAP_CODE_RESPONSE,
-            EAP_CODE_SUCCESS,
-            EAP_CODE_FAILURE
-    })
-    public @interface EapCode {}
-
-    public static final int EAP_CODE_REQUEST = 1;
-    public static final int EAP_CODE_RESPONSE = 2;
-    public static final int EAP_CODE_SUCCESS = 3;
-    public static final int EAP_CODE_FAILURE = 4;
-
-    public static final Map<Integer, String> EAP_CODE_STRING = new HashMap<>();
-    static {
-        EAP_CODE_STRING.put(EAP_CODE_REQUEST, "REQUEST");
-        EAP_CODE_STRING.put(EAP_CODE_RESPONSE, "RESPONSE");
-        EAP_CODE_STRING.put(EAP_CODE_SUCCESS, "SUCCESS");
-        EAP_CODE_STRING.put(EAP_CODE_FAILURE, "FAILURE");
-    }
-
-    public static final int EAP_HEADER_LENGTH = 4;
-
-    @EapCode public final int eapCode;
-    public final int eapIdentifier;
-    public final int eapLength;
-    public final EapData eapData;
-
-    public EapMessage(@EapCode int eapCode, int eapIdentifier, @Nullable EapData eapData)
-            throws EapSilentException {
-        this.eapCode = eapCode;
-        this.eapIdentifier = eapIdentifier;
-        this.eapLength = EAP_HEADER_LENGTH + ((eapData == null) ? 0 : eapData.getLength());
-        this.eapData = eapData;
-
-        validate();
-    }
-
-    /**
-     * Decodes and returns an EapMessage from the given byte array.
-     *
-     * @param packet byte array containing a byte-encoded EapMessage
-     * @return the EapMessage instance representing the given {@param packet}
-     * @throws EapSilentException for decoding errors that must be discarded silently
-     */
-    public static EapMessage decode(@NonNull byte[] packet) throws EapSilentException {
-        ByteBuffer buffer = ByteBuffer.wrap(packet);
-        int eapCode;
-        int eapIdentifier;
-        int eapLength;
-        EapData eapData;
-        try {
-            eapCode = Byte.toUnsignedInt(buffer.get());
-            eapIdentifier = Byte.toUnsignedInt(buffer.get());
-            eapLength = Short.toUnsignedInt(buffer.getShort());
-
-            if (eapCode == EAP_CODE_REQUEST || eapCode == EAP_CODE_RESPONSE) {
-                int eapType = Byte.toUnsignedInt(buffer.get());
-                if (!EapData.isSupportedEapType(eapType)) {
-                    LOG.e(TAG, "Decoding EAP packet with unsupported EAP-Type: " + eapType);
-                    throw new UnsupportedEapTypeException(eapIdentifier,
-                            "Unsupported eapType=" + eapType);
-                }
-
-                byte[] eapDataBytes = new byte[buffer.remaining()];
-                buffer.get(eapDataBytes);
-                eapData = new EapData(eapType, eapDataBytes);
-            } else {
-                eapData = null;
-            }
-        } catch (BufferUnderflowException ex) {
-            String msg = "EAP packet is missing required values";
-            LOG.e(TAG, msg, ex);
-            throw new EapInvalidPacketLengthException(msg, ex);
-        }
-
-        int eapDataLength = (eapData == null) ? 0 : eapData.getLength();
-        if (eapLength > EAP_HEADER_LENGTH + eapDataLength) {
-            String msg = "Packet is shorter than specified length";
-            LOG.e(TAG, msg);
-            throw new EapInvalidPacketLengthException(msg);
-        }
-
-        return new EapMessage(eapCode, eapIdentifier, eapData);
-    }
-
-    /**
-     * Converts this EapMessage instance to its byte-encoded representation.
-     *
-     * @return byte[] representing the byte-encoded EapMessage
-     */
-    public byte[] encode() {
-        ByteBuffer byteBuffer = ByteBuffer.allocate(eapLength);
-        byteBuffer.put((byte) eapCode);
-        byteBuffer.put((byte) eapIdentifier);
-        byteBuffer.putShort((short) eapLength);
-
-        if (eapData != null) {
-            eapData.encodeToByteBuffer(byteBuffer);
-        }
-
-        return byteBuffer.array();
-    }
-
-    /**
-     * Creates and returns an EAP-Response/Notification message for the given EAP Identifier wrapped
-     * in an EapResponse object.
-     *
-     * @param eapIdentifier the identifier for the message being responded to
-     * @return an EapResponse object containing an EAP-Response/Notification message with an
-     *         identifier matching the given identifier, or an EapError if an exception was thrown
-     */
-    public static EapResult getNotificationResponse(int eapIdentifier) {
-        try {
-            return EapResponse.getEapResponse(
-                    new EapMessage(EAP_CODE_RESPONSE, eapIdentifier, NOTIFICATION_DATA));
-        } catch (EapSilentException ex) {
-            // this should never happen - the only variable value is the identifier
-            LOG.wtf(TAG, "Failed to create Notification Response for message with identifier="
-                    + eapIdentifier);
-            return new EapError(ex);
-        }
-    }
-
-    /**
-     * Creates and returns an EAP-Response/Nak message for the given EAP Identifier wrapped in an
-     * EapResponse object.
-     *
-     * @param eapIdentifier the identifier for the message being responded to
-     * @param supportedEapTypes Collection of EAP Method types supported by the EAP Session
-     * @return an EapResponse object containing an EAP-Response/Nak message with an identifier
-     *         matching the given identifier, or an EapError if an exception was thrown
-     */
-    public static EapResult getNakResponse(
-            int eapIdentifier,
-            Collection<Integer> supportedEapTypes) {
-        try {
-            ByteBuffer buffer = ByteBuffer.allocate(supportedEapTypes.size());
-            for (int eapMethodType : supportedEapTypes) {
-                buffer.put((byte) eapMethodType);
-            }
-            EapData nakData = new EapData(EAP_NAK, buffer.array());
-
-            return EapResponse.getEapResponse(
-                    new EapMessage(EAP_CODE_RESPONSE, eapIdentifier, nakData));
-        } catch (EapSilentException ex) {
-            // this should never happen - the only variable value is the identifier
-            LOG.wtf(TAG,  "Failed to create Nak for message with identifier="
-                    + eapIdentifier);
-            return new EapError(ex);
-        }
-    }
-
-    private void validate() throws EapSilentException {
-        if (eapCode != EAP_CODE_REQUEST
-                && eapCode != EAP_CODE_RESPONSE
-                && eapCode != EAP_CODE_SUCCESS
-                && eapCode != EAP_CODE_FAILURE) {
-            LOG.e(TAG, "Invalid EAP Code: " + eapCode);
-            throw new InvalidEapCodeException(eapCode);
-        }
-
-        if ((eapCode == EAP_CODE_SUCCESS || eapCode == EAP_CODE_FAILURE)
-                && eapLength != EAP_HEADER_LENGTH) {
-            LOG.e(TAG, "Invalid length for EAP-Success/EAP-Failure. Length: " + eapLength);
-            throw new EapInvalidPacketLengthException(
-                    "EAP Success/Failure packets must be length 4");
-        }
-
-        if ((eapCode == EAP_CODE_REQUEST || eapCode == EAP_CODE_RESPONSE) && eapData == null) {
-            LOG.e(TAG, "No Type value included for EAP-Request/EAP-Response");
-            throw new EapInvalidPacketLengthException(
-                    "EAP Request/Response packets must include a Type value");
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeData.java b/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeData.java
deleted file mode 100644
index 985e0da..0000000
--- a/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeData.java
+++ /dev/null
@@ -1,600 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.EapMessage;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * EapMsChapV2TypeData represents the Type Data for an {@link EapMessage} during an EAP MSCHAPv2
- * session.
- */
-public class EapMsChapV2TypeData {
-    private static final int LABEL_VALUE_LENGTH = 2;
-    private static final String ASCII_CHARSET_NAME = "US-ASCII";
-    private static final String MESSAGE_PREFIX = "M=";
-    private static final String MESSAGE_LABEL = "M";
-
-    // EAP MSCHAPv2 OpCode values (EAP MSCHAPv2#2)
-    public static final int EAP_MSCHAP_V2_CHALLENGE = 1;
-    public static final int EAP_MSCHAP_V2_RESPONSE = 2;
-    public static final int EAP_MSCHAP_V2_SUCCESS = 3;
-    public static final int EAP_MSCHAP_V2_FAILURE = 4;
-    public static final int EAP_MSCHAP_V2_CHANGE_PASSWORD = 7;
-
-    public static final Map<Integer, String> EAP_OP_CODE_STRING = new HashMap<>();
-    static {
-        EAP_OP_CODE_STRING.put(EAP_MSCHAP_V2_CHALLENGE, "Challenge");
-        EAP_OP_CODE_STRING.put(EAP_MSCHAP_V2_RESPONSE, "Response");
-        EAP_OP_CODE_STRING.put(EAP_MSCHAP_V2_SUCCESS, "Success");
-        EAP_OP_CODE_STRING.put(EAP_MSCHAP_V2_FAILURE, "Failure");
-        EAP_OP_CODE_STRING.put(EAP_MSCHAP_V2_CHANGE_PASSWORD, "Change-Password");
-    }
-
-    private static final Set<Integer> SUPPORTED_OP_CODES = new HashSet<>();
-    static {
-        SUPPORTED_OP_CODES.add(EAP_MSCHAP_V2_CHALLENGE);
-        SUPPORTED_OP_CODES.add(EAP_MSCHAP_V2_RESPONSE);
-        SUPPORTED_OP_CODES.add(EAP_MSCHAP_V2_SUCCESS);
-        SUPPORTED_OP_CODES.add(EAP_MSCHAP_V2_FAILURE);
-    }
-
-    public final int opCode;
-
-    EapMsChapV2TypeData(int opCode) throws EapMsChapV2ParsingException {
-        this.opCode = opCode;
-
-        if (!SUPPORTED_OP_CODES.contains(opCode)) {
-            throw new EapMsChapV2ParsingException("Unsupported opCode provided: " + opCode);
-        }
-    }
-
-    /**
-     * Encodes this EapMsChapV2TypeData instance as a byte[].
-     *
-     * @return byte[] representing the encoded value of this EapMsChapV2TypeData instance.
-     */
-    public byte[] encode() {
-        throw new UnsupportedOperationException(
-                "encode() not supported by " + this.getClass().getSimpleName());
-    }
-
-    abstract static class EapMsChapV2VariableTypeData extends EapMsChapV2TypeData {
-        public final int msChapV2Id;
-        public final int msLength;
-
-        EapMsChapV2VariableTypeData(int opCode, int msChapV2Id, int msLength)
-                throws EapMsChapV2ParsingException {
-            super(opCode);
-
-            this.msChapV2Id = msChapV2Id;
-            this.msLength = msLength;
-        }
-    }
-
-    /**
-     * EapMsChapV2ChallengeRequest represents the EAP MSCHAPv2 Challenge Packet (EAP MSCHAPv2#2.1).
-     */
-    public static class EapMsChapV2ChallengeRequest extends EapMsChapV2VariableTypeData {
-        public static final int VALUE_SIZE = 16;
-        public static final int TYPE_DATA_HEADER_SIZE = 5;
-
-        public final byte[] challenge = new byte[VALUE_SIZE];
-        public final byte[] name;
-
-        EapMsChapV2ChallengeRequest(ByteBuffer buffer) throws EapMsChapV2ParsingException {
-            super(
-                    EAP_MSCHAP_V2_CHALLENGE,
-                    Byte.toUnsignedInt(buffer.get()),
-                    Short.toUnsignedInt(buffer.getShort()));
-
-            int valueSize = Byte.toUnsignedInt(buffer.get());
-            if (valueSize != VALUE_SIZE) {
-                throw new EapMsChapV2ParsingException("Challenge Value-Size must be 16");
-            }
-            buffer.get(challenge);
-
-            int nameLenBytes = msLength - VALUE_SIZE - TYPE_DATA_HEADER_SIZE;
-            if (nameLenBytes < 0) {
-                throw new EapMsChapV2ParsingException("Invalid MS-Length specified");
-            }
-
-            name = new byte[nameLenBytes];
-            buffer.get(name);
-        }
-
-        @VisibleForTesting
-        public EapMsChapV2ChallengeRequest(
-                int msChapV2Id, int msLength, byte[] challenge, byte[] name)
-                throws EapMsChapV2ParsingException {
-            super(EAP_MSCHAP_V2_CHALLENGE, msChapV2Id, msLength);
-
-            if (challenge.length != VALUE_SIZE) {
-                throw new EapMsChapV2ParsingException("Challenge length must be 16");
-            }
-
-            System.arraycopy(challenge, 0, this.challenge, 0, VALUE_SIZE);
-            this.name = name;
-        }
-    }
-
-    /**
-     * EapMsChapV2ChallengeResponse represents the EAP MSCHAPv2 Response Packet (EAP MSCHAPv2#2.2).
-     */
-    public static class EapMsChapV2ChallengeResponse extends EapMsChapV2VariableTypeData {
-        public static final int VALUE_SIZE = 49;
-        public static final int PEER_CHALLENGE_SIZE = 16;
-        public static final int RESERVED_BYTES = 8;
-        public static final int NT_RESPONSE_SIZE = 24;
-        public static final int TYPE_DATA_HEADER_SIZE = 5;
-
-        public final byte[] peerChallenge = new byte[PEER_CHALLENGE_SIZE];
-        public final byte[] ntResponse = new byte[NT_RESPONSE_SIZE];
-        public final int flags;
-        public final byte[] name;
-
-        public EapMsChapV2ChallengeResponse(
-                int msChapV2Id, byte[] peerChallenge, byte[] ntResponse, int flags, byte[] name)
-                throws EapMsChapV2ParsingException {
-            super(
-                    EAP_MSCHAP_V2_RESPONSE,
-                    msChapV2Id,
-                    TYPE_DATA_HEADER_SIZE + VALUE_SIZE + name.length);
-
-            if (peerChallenge.length != PEER_CHALLENGE_SIZE) {
-                throw new EapMsChapV2ParsingException("Peer-Challenge must be 16B");
-            } else if (ntResponse.length != NT_RESPONSE_SIZE) {
-                throw new EapMsChapV2ParsingException("NT-Response must be 24B");
-            } else if (flags != 0) {
-                throw new EapMsChapV2ParsingException("Flags must be 0x00");
-            }
-
-            System.arraycopy(peerChallenge, 0, this.peerChallenge, 0, PEER_CHALLENGE_SIZE);
-            System.arraycopy(ntResponse, 0, this.ntResponse, 0, NT_RESPONSE_SIZE);
-            this.flags = flags;
-            this.name = name;
-        }
-
-        @Override
-        public byte[] encode() {
-            ByteBuffer buffer = ByteBuffer.allocate(msLength);
-            buffer.put((byte) EAP_MSCHAP_V2_RESPONSE);
-            buffer.put((byte) msChapV2Id);
-            buffer.putShort((short) msLength);
-            buffer.put((byte) VALUE_SIZE);
-            buffer.put(peerChallenge);
-            buffer.put(new byte[RESERVED_BYTES]);
-            buffer.put(ntResponse);
-            buffer.put((byte) flags);
-            buffer.put(name);
-
-            return buffer.array();
-        }
-    }
-
-    /**
-     * EapMsChapV2SuccessRequest represents the EAP MSCHAPv2 Success Request Packet
-     * (EAP MSCHAPv2#2.3).
-     */
-    public static class EapMsChapV2SuccessRequest extends EapMsChapV2VariableTypeData {
-        private static final int AUTH_STRING_LEN_HEX = 40;
-        private static final int AUTH_STRING_LEN_BYTES = 20;
-        private static final int NUM_REQUIRED_ATTRIBUTES = 2;
-        private static final String AUTH_STRING_LABEL = "S";
-
-        public final byte[] authBytes = new byte[AUTH_STRING_LEN_BYTES];
-        public final String message;
-
-        EapMsChapV2SuccessRequest(ByteBuffer buffer) throws EapMsChapV2ParsingException {
-            super(
-                    EAP_MSCHAP_V2_SUCCESS,
-                    Byte.toUnsignedInt(buffer.get()),
-                    Short.toUnsignedInt(buffer.getShort()));
-
-            byte[] message = new byte[buffer.remaining()];
-            buffer.get(message);
-
-            // message formatting: "S=<auth_string> M=<message>"
-            Map<String, String> mappings =
-                    getMessageMappings(new String(message, Charset.forName(ASCII_CHARSET_NAME)));
-
-            if (!mappings.containsKey(AUTH_STRING_LABEL)
-                    || mappings.size() != NUM_REQUIRED_ATTRIBUTES) {
-                throw new EapMsChapV2ParsingException(
-                        "Auth message must be in the format: 'S=<auth_string> M=<message>'");
-            }
-
-            String authStringHex = mappings.get(AUTH_STRING_LABEL);
-            if (authStringHex.length() != AUTH_STRING_LEN_HEX) {
-                throw new EapMsChapV2ParsingException("Auth String must be 40 hex chars (20B)");
-            }
-            byte[] authBytes = hexStringToByteArray(authStringHex);
-            System.arraycopy(authBytes, 0, this.authBytes, 0, AUTH_STRING_LEN_BYTES);
-
-            this.message = mappings.get(MESSAGE_LABEL);
-        }
-
-        @VisibleForTesting
-        public EapMsChapV2SuccessRequest(
-                int msChapV2Id, int msLength, byte[] authBytes, String message)
-                throws EapMsChapV2ParsingException {
-            super(EAP_MSCHAP_V2_SUCCESS, msChapV2Id, msLength);
-
-            if (authBytes.length != AUTH_STRING_LEN_BYTES) {
-                throw new EapMsChapV2ParsingException("Auth String must be 20B");
-            }
-
-            System.arraycopy(authBytes, 0, this.authBytes, 0, AUTH_STRING_LEN_BYTES);
-            this.message = message;
-        }
-    }
-
-    /**
-     * EapMsChapV2SuccessResponse represents the EAP MSCHAPv2 Success Response Packet
-     * (EAP MSCHAPv2#2.4).
-     */
-    public static class EapMsChapV2SuccessResponse extends EapMsChapV2TypeData {
-        private EapMsChapV2SuccessResponse() throws EapMsChapV2ParsingException {
-            super(EAP_MSCHAP_V2_SUCCESS);
-        }
-
-        /**
-         * Constructs and returns a new EAP MSCHAPv2 Success Response type data.
-         *
-         * @return a new EapMsChapV2SuccessResponse instance
-         */
-        public static EapMsChapV2SuccessResponse getEapMsChapV2SuccessResponse() {
-            try {
-                return new EapMsChapV2SuccessResponse();
-            } catch (EapMsChapV2ParsingException ex) {
-                // This should never happen
-                LOG.wtf(
-                        EapMsChapV2SuccessResponse.class.getSimpleName(),
-                        "ParsingException thrown while creating EapMsChapV2SuccessResponse",
-                        ex);
-                return null;
-            }
-        }
-
-        @Override
-        public byte[] encode() {
-            return new byte[] {(byte) EAP_MSCHAP_V2_SUCCESS};
-        }
-    }
-
-    /**
-     * EapMsChapV2FailureRequest represents the EAP MSCHAPv2 Failure Request Packet
-     * (EAP MSCHAPv2#2.5).
-     */
-    public static class EapMsChapV2FailureRequest extends EapMsChapV2VariableTypeData {
-        private static final int NUM_REQUIRED_ATTRIBUTES = 5;
-        private static final int CHALLENGE_LENGTH = 16;
-        private static final String ERROR_LABEL = "E";
-        private static final String RETRY_LABEL = "R";
-        private static final String IS_RETRYABLE_FLAG = "1";
-        private static final String CHALLENGE_LABEL = "C";
-        private static final String PASSWORD_CHANGE_PROTOCOL_LABEL = "V";
-
-        // Error codes defined in EAP MSCHAPv2#2.5
-        public static final Map<Integer, String> EAP_ERROR_CODE_STRING = new HashMap<>();
-        static {
-            EAP_ERROR_CODE_STRING.put(646, "ERROR_RESTRICTED_LOGON_HOURS");
-            EAP_ERROR_CODE_STRING.put(647, "ERROR_ACCT_DISABLED");
-            EAP_ERROR_CODE_STRING.put(648, "ERROR_PASSWD_EXPIRED");
-            EAP_ERROR_CODE_STRING.put(649, "ERROR_NO_DIALIN_PERMISSION");
-            EAP_ERROR_CODE_STRING.put(691, "ERROR_AUTHENTICATION_FAILURE");
-            EAP_ERROR_CODE_STRING.put(709, "ERROR_CHANGING_PASSWORD");
-        }
-
-        public final int errorCode;
-        public final boolean isRetryable;
-        public final byte[] challenge;
-        public final int passwordChangeProtocol;
-        public final String message;
-
-        EapMsChapV2FailureRequest(ByteBuffer buffer)
-                throws EapMsChapV2ParsingException, NumberFormatException {
-            super(
-                    EAP_MSCHAP_V2_FAILURE,
-                    Byte.toUnsignedInt(buffer.get()),
-                    Short.toUnsignedInt(buffer.getShort()));
-
-            byte[] message = new byte[buffer.remaining()];
-            buffer.get(message);
-
-            // message formatting:
-            // "E=<error_code> R=<retry bit> C=<challenge> V=<password_change_protocol> M=<message>"
-            Map<String, String> mappings =
-                    getMessageMappings(new String(message, Charset.forName(ASCII_CHARSET_NAME)));
-            if (!mappings.containsKey(ERROR_LABEL)
-                    || !mappings.containsKey(RETRY_LABEL)
-                    || !mappings.containsKey(CHALLENGE_LABEL)
-                    || !mappings.containsKey(PASSWORD_CHANGE_PROTOCOL_LABEL)
-                    || mappings.size() != NUM_REQUIRED_ATTRIBUTES) {
-                throw new EapMsChapV2ParsingException(
-                        "Message must be formatted as: E=<error_code> R=<retry bit> C=<challenge>"
-                            + " V=<password_change_protocol> M=<message>");
-            }
-
-            this.errorCode = Integer.parseInt(mappings.get(ERROR_LABEL));
-            this.isRetryable = IS_RETRYABLE_FLAG.equals(mappings.get(RETRY_LABEL));
-            this.challenge = hexStringToByteArray(mappings.get(CHALLENGE_LABEL));
-            this.passwordChangeProtocol = Integer.parseInt(mappings.get(
-                    PASSWORD_CHANGE_PROTOCOL_LABEL));
-            this.message = mappings.get("M");
-
-            if (challenge.length != CHALLENGE_LENGTH) {
-                throw new EapMsChapV2ParsingException("Challenge must be 16B long");
-            }
-        }
-
-        @VisibleForTesting
-        public EapMsChapV2FailureRequest(
-                int msChapV2Id,
-                int msLength,
-                int errorCode,
-                boolean isRetryable,
-                byte[] challenge,
-                int passwordChangeProtocol,
-                String message)
-                throws EapMsChapV2ParsingException {
-            super(EAP_MSCHAP_V2_FAILURE, msChapV2Id, msLength);
-
-            this.errorCode = errorCode;
-            this.isRetryable = isRetryable;
-            this.challenge = challenge;
-            this.passwordChangeProtocol = passwordChangeProtocol;
-            this.message = message;
-
-            if (challenge.length != CHALLENGE_LENGTH) {
-                throw new EapMsChapV2ParsingException("Challenge length must be 16B");
-            }
-        }
-    }
-
-    /**
-     * EapMsChapV2FailureResponse represents the EAP MSCHAPv2 Failure Response Packet
-     * (EAP MSCHAPv2#2.6).
-     */
-    public static class EapMsChapV2FailureResponse extends EapMsChapV2TypeData {
-        private EapMsChapV2FailureResponse() throws EapMsChapV2ParsingException {
-            super(EAP_MSCHAP_V2_FAILURE);
-        }
-
-        /**
-         * Constructs and returns a new EAP MSCHAPv2 Failure Response type data.
-         *
-         * @return a new EapMsChapV2FailureResponse instance
-         */
-        public static EapMsChapV2FailureResponse getEapMsChapV2FailureResponse() {
-            try {
-                return new EapMsChapV2FailureResponse();
-            } catch (EapMsChapV2ParsingException ex) {
-                // This should never happen
-                LOG.wtf(
-                        EapMsChapV2SuccessResponse.class.getSimpleName(),
-                        "ParsingException thrown while creating EapMsChapV2FailureResponse",
-                        ex);
-                return null;
-            }
-        }
-
-        @Override
-        public byte[] encode() {
-            return new byte[] {(byte) EAP_MSCHAP_V2_FAILURE};
-        }
-    }
-
-    @VisibleForTesting
-    static Map<String, String> getMessageMappings(String message)
-            throws EapMsChapV2ParsingException {
-        Map<String, String> messageMappings = new HashMap<>();
-        int mPos = message.indexOf(MESSAGE_PREFIX);
-
-        String preMString;
-        if (mPos == -1) {
-            preMString = message;
-            messageMappings.put(MESSAGE_LABEL, "<omitted by authenticator>");
-        } else {
-            preMString = message.substring(0, mPos);
-            messageMappings.put(MESSAGE_LABEL, message.substring(mPos + MESSAGE_PREFIX.length()));
-        }
-
-        // preMString: "S=<auth string> " or "E=<error> R=r C=<challenge> V=<version> "
-        for (String value : preMString.split(" ")) {
-            String[] keyValue = value.split("=");
-            if (keyValue.length != LABEL_VALUE_LENGTH) {
-                throw new EapMsChapV2ParsingException(
-                        "Message must be formatted <label character>=<value>");
-            } else if (messageMappings.containsKey(keyValue[0])) {
-                throw new EapMsChapV2ParsingException(
-                        "Duplicated key-value pair in message: " + LOG.pii(message));
-            }
-            messageMappings.put(keyValue[0], keyValue[1]);
-        }
-
-        return messageMappings;
-    }
-
-    @VisibleForTesting
-    static byte[] hexStringToByteArray(String hexString)
-            throws EapMsChapV2ParsingException, NumberFormatException {
-        if (hexString.length() % 2 != 0) {
-            throw new EapMsChapV2ParsingException(
-                    "Hex string must contain an even number of characters");
-        }
-
-        byte[] dataBytes = new byte[hexString.length() / 2];
-        for (int i = 0; i < hexString.length(); i += 2) {
-            dataBytes[i / 2] = (byte) Integer.parseInt(hexString.substring(i, i + 2), 16);
-        }
-        return dataBytes;
-    }
-
-    /** Class for decoding EAP MSCHAPv2 type data. */
-    public static class EapMsChapV2TypeDataDecoder {
-        /**
-         * Returns the EAP MSCHAPv2 Op Code for the given EAP type data.
-         *
-         * @param eapTypeData byte[] type data to read the Op Code from
-         * @return the EAP MSCHAPv2 Op Code for the current type data
-         * @throws BufferUnderflowException iff eapTypeData.length == 0
-         */
-        public int getOpCode(byte[] eapTypeData) throws BufferUnderflowException {
-            return Byte.toUnsignedInt(ByteBuffer.wrap(eapTypeData).get());
-        }
-
-        /**
-         * Decodes and returns an EapMsChapV2ChallengeRequest for the specified eapTypeData.
-         *
-         * @param tag String for logging tag
-         * @param eapTypeData byte[] to be decoded as an EapMsChapV2ChallengeRequest instance
-         * @return DecodeResult wrapping an EapMsChapV2ChallengeRequest instance for the given
-         *     eapTypeData iff the eapTypeData is formatted correctly. Otherwise, the DecodeResult
-         *     wraps the appropriate EapError.
-         */
-        public DecodeResult<EapMsChapV2ChallengeRequest> decodeChallengeRequest(
-                String tag, byte[] eapTypeData) {
-            try {
-                ByteBuffer buffer = ByteBuffer.wrap(eapTypeData);
-                int opCode = Byte.toUnsignedInt(buffer.get());
-
-                if (opCode != EAP_MSCHAP_V2_CHALLENGE) {
-                    return new DecodeResult<>(
-                            new EapError(
-                                    new EapMsChapV2ParsingException(
-                                            "Received type data with invalid opCode: "
-                                                    + EAP_OP_CODE_STRING.getOrDefault(
-                                                            opCode, "Unknown (" + opCode + ")"))));
-                }
-
-                return new DecodeResult<>(new EapMsChapV2ChallengeRequest(buffer));
-            } catch (BufferUnderflowException | EapMsChapV2ParsingException ex) {
-                LOG.e(tag, "Error parsing EAP MSCHAPv2 Challenge Request type data", ex);
-                return new DecodeResult<>(new EapError(ex));
-            }
-        }
-
-        /**
-         * Decodes and returns an EapMsChapV2SuccessRequest for the specified eapTypeData.
-         *
-         * @param tag String for logging tag
-         * @param eapTypeData byte[] to be decoded as an EapMsChapV2SuccessRequest instance
-         * @return DecodeResult wrapping an EapMsChapV2SuccessRequest instance for the given
-         *     eapTypeData iff the eapTypeData is formatted correctly. Otherwise, the DecodeResult
-         *     wraps the appropriate EapError.
-         */
-        public DecodeResult<EapMsChapV2SuccessRequest> decodeSuccessRequest(
-                String tag, byte[] eapTypeData) {
-            try {
-                ByteBuffer buffer = ByteBuffer.wrap(eapTypeData);
-                int opCode = Byte.toUnsignedInt(buffer.get());
-
-                if (opCode != EAP_MSCHAP_V2_SUCCESS) {
-                    return new DecodeResult<>(
-                            new EapError(
-                                    new EapMsChapV2ParsingException(
-                                            "Received type data with invalid opCode: "
-                                                    + EAP_OP_CODE_STRING.getOrDefault(
-                                                            opCode, "Unknown (" + opCode + ")"))));
-                }
-
-                return new DecodeResult<>(new EapMsChapV2SuccessRequest(buffer));
-            } catch (BufferUnderflowException
-                    | NumberFormatException
-                    | EapMsChapV2ParsingException ex) {
-                LOG.e(tag, "Error parsing EAP MSCHAPv2 Success Request type data", ex);
-                return new DecodeResult<>(new EapError(ex));
-            }
-        }
-
-        /**
-         * Decodes and returns an EapMsChapV2FailureRequest for the specified eapTypeData.
-         *
-         * @param tag String for logging tag
-         * @param eapTypeData byte[] to be decoded as an EapMsChapV2FailureRequest instance
-         * @return DecodeResult wrapping an EapMsChapV2FailureRequest instance for the given
-         *     eapTypeData iff the eapTypeData is formatted correctly. Otherwise, the DecodeResult
-         *     wraps the appropriate EapError.
-         */
-        public DecodeResult<EapMsChapV2FailureRequest> decodeFailureRequest(
-                String tag, byte[] eapTypeData) {
-            try {
-                ByteBuffer buffer = ByteBuffer.wrap(eapTypeData);
-                int opCode = Byte.toUnsignedInt(buffer.get());
-
-                if (opCode != EAP_MSCHAP_V2_FAILURE) {
-                    return new DecodeResult<>(
-                            new EapError(
-                                    new EapMsChapV2ParsingException(
-                                            "Received type data with invalid opCode: "
-                                                    + EAP_OP_CODE_STRING.getOrDefault(
-                                                            opCode, "Unknown (" + opCode + ")"))));
-                }
-
-                return new DecodeResult<>(new EapMsChapV2FailureRequest(buffer));
-            } catch (BufferUnderflowException
-                    | NumberFormatException
-                    | EapMsChapV2ParsingException ex) {
-                LOG.e(tag, "Error parsing EAP MSCHAPv2 Failure Request type data", ex);
-                return new DecodeResult<>(new EapError(ex));
-            }
-        }
-
-        /**
-         * DecodeResult represents the result from calling a decode method within
-         * EapMsChapV2TypeDataDecoder. It will contain either an EapMsChapV2TypeData or an EapError.
-         *
-         * @param <T> The EapMsChapV2TypeData type that is wrapped in this DecodeResult
-         */
-        public static class DecodeResult<T extends EapMsChapV2TypeData> {
-            public final T eapTypeData;
-            public final EapError eapError;
-
-            public DecodeResult(T eapTypeData) {
-                this.eapTypeData = eapTypeData;
-                this.eapError = null;
-            }
-
-            public DecodeResult(EapError eapError) {
-                this.eapTypeData = null;
-                this.eapError = eapError;
-            }
-
-            /**
-             * Checks whether this instance represents a successful decode operation.
-             *
-             * @return true iff this DecodeResult represents a successfully decoded Type Data
-             */
-            public boolean isSuccessfulDecode() {
-                return eapTypeData != null;
-            }
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapAkaAttributeFactory.java b/src/java/com/android/internal/net/eap/message/simaka/EapAkaAttributeFactory.java
deleted file mode 100644
index 5b68781..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapAkaAttributeFactory.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTS;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_BIDDING;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RES;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.LENGTH_SCALING;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAuts;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes;
-
-import java.nio.ByteBuffer;
-
-/**
- * EapAkaAttributeFactory is used for creating EAP-AKA attributes according to their type.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication
- * Protocol for Authentication and Key Agreement (EAP-AKA)</a>
- * @see <a href="https://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml">EAP SIM/AKA
- * Attributes</a>
- */
-public class EapAkaAttributeFactory extends EapSimAkaAttributeFactory {
-    private static EapAkaAttributeFactory sInstance = new EapAkaAttributeFactory();
-
-    protected EapAkaAttributeFactory() {}
-
-    public static EapAkaAttributeFactory getInstance() {
-        return sInstance;
-    }
-
-    /**
-     * Decodes a single EapSimAkaAttribute object from the given ByteBuffer.
-     *
-     * <p>Decoding logic is based on Attribute definitions in RFC 4187#10.
-     *
-     * @param byteBuffer The ByteBuffer to parse the current attribute from
-     * @return The current EapSimAkaAttribute to be parsed, or EapSimAkaUnsupportedAttribute if the
-     *     given attributeType is skippable and unsupported
-     * @throws EapSimAkaInvalidAttributeException when a malformatted attribute is attempted to be
-     *     decoded
-     * @throws EapSimAkaUnsupportedAttributeException when an unsupported, unskippable Attribute is
-     *     attempted to be decoded
-     */
-    public EapSimAkaAttribute getAttribute(ByteBuffer byteBuffer)
-            throws EapSimAkaInvalidAttributeException, EapSimAkaUnsupportedAttributeException {
-        int attributeType = Byte.toUnsignedInt(byteBuffer.get());
-
-        // Length is given as a multiple of 4x bytes (RFC 4187#8.1)
-        int lengthInBytes = Byte.toUnsignedInt(byteBuffer.get()) * LENGTH_SCALING;
-
-        return getAttribute(attributeType, lengthInBytes, byteBuffer);
-    }
-
-    @Override
-    protected EapSimAkaAttribute getAttribute(
-            int attributeType, int lengthInBytes, ByteBuffer byteBuffer)
-            throws EapSimAkaInvalidAttributeException, EapSimAkaUnsupportedAttributeException {
-        switch (attributeType) {
-            case EAP_AT_RAND:
-                return new AtRandAka(lengthInBytes, byteBuffer);
-            case EAP_AT_AUTN:
-                return new AtAutn(lengthInBytes, byteBuffer);
-            case EAP_AT_RES:
-                return new AtRes(lengthInBytes, byteBuffer);
-            case EAP_AT_AUTS:
-                return new AtAuts(lengthInBytes, byteBuffer);
-            case EAP_AT_BIDDING:
-                return new AtBidding(lengthInBytes, byteBuffer);
-            default:
-                return super.getAttribute(attributeType, lengthInBytes, byteBuffer);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeAttributeFactory.java b/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeAttributeFactory.java
deleted file mode 100644
index 46f97e5..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeAttributeFactory.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF_INPUT;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.LENGTH_SCALING;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
-
-import java.nio.ByteBuffer;
-
-/**
- * EapAkaPrimeAttributeFactory is used for creating EAP-AKA' attributes according to their type.
- *
- * @see <a href="https://tools.ietf.org/html/rfc5448">RFC 5448, Improved Extensible Authentication
- *     Protocol Method for 3rd Generation Authentication and Key Agreement (EAP-AKA')</a>
- * @see <a href="https://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml">EAP SIM/AKA
- *     Attributes</a>
- */
-public class EapAkaPrimeAttributeFactory extends EapAkaAttributeFactory {
-    private static EapAkaPrimeAttributeFactory sInstance = new EapAkaPrimeAttributeFactory();
-
-    private EapAkaPrimeAttributeFactory() {}
-
-    public static EapAkaPrimeAttributeFactory getInstance() {
-        return sInstance;
-    }
-
-    /**
-     * Decodes a single EapSimAkaAttribute object from the given ByteBuffer.
-     *
-     * <p>Decoding logic is based on Attribute definitions in RFC 5448#10.
-     *
-     * @param byteBuffer The ByteBuffer to parse the current attribute from
-     * @return The current EapSimAkaAttribute to be parsed, or EapSimAkaUnsupportedAttribute if the
-     *     given attributeType is skippable and unsupported
-     * @throws EapSimAkaInvalidAttributeException when a malformatted attribute is attempted to be
-     *     decoded
-     * @throws EapSimAkaUnsupportedAttributeException when an unsupported, unskippable Attribute is
-     *     attempted to be decoded
-     */
-    @Override
-    public EapSimAkaAttribute getAttribute(ByteBuffer byteBuffer)
-            throws EapSimAkaInvalidAttributeException, EapSimAkaUnsupportedAttributeException {
-        int attributeType = Byte.toUnsignedInt(byteBuffer.get());
-
-        // Length is given as a multiple of 4x bytes (RFC 4187#8.1)
-        int lengthInBytes = Byte.toUnsignedInt(byteBuffer.get()) * LENGTH_SCALING;
-
-        switch (attributeType) {
-            case EAP_AT_KDF_INPUT:
-                return new AtKdfInput(lengthInBytes, byteBuffer);
-            case EAP_AT_KDF:
-                return new AtKdf(lengthInBytes, byteBuffer);
-            default:
-                return super.getAttribute(attributeType, lengthInBytes, byteBuffer);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java
deleted file mode 100644
index 23dcd02..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeData.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-
-import java.util.LinkedHashMap;
-import java.util.List;
-
-/**
- * EapAkaPrimeTypeData represents the Type Data for an {@link EapMessage} during an EAP-AKA'
- * session.
- */
-public class EapAkaPrimeTypeData extends EapAkaTypeData {
-    private static final EapAkaPrimeTypeDataDecoder sTypeDataDecoder =
-            new EapAkaPrimeTypeDataDecoder();
-
-    @VisibleForTesting
-    EapAkaPrimeTypeData(
-            int eapSubType, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-        super(eapSubType, attributeMap);
-    }
-
-    /**
-     * Creates and returns an EapAkaPrimeTypeData instance with the given subtype and attributes.
-     *
-     * @param eapSubtype the subtype for the EAP-AKA type data
-     * @param attributes the List of EapSimAkaAttributes to be included in this type data
-     */
-    public EapAkaPrimeTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
-        super(eapSubtype, attributes);
-    }
-
-    public static EapAkaPrimeTypeDataDecoder getEapAkaPrimeTypeDataDecoder() {
-        return sTypeDataDecoder;
-    }
-
-    /**
-     * EapAkaTypeDataDecoder will be used for decoding {@link EapAkaPrimeTypeData} objects.
-     */
-    public static class EapAkaPrimeTypeDataDecoder
-            extends EapSimAkaTypeDataDecoder<EapAkaTypeData> {
-        private static final String TAG = EapAkaPrimeTypeDataDecoder.class.getSimpleName();
-        private static final String EAP_METHOD = "EAP-AKA'";
-
-        protected EapAkaPrimeTypeDataDecoder() {
-            super(
-                    TAG,
-                    EAP_METHOD,
-                    SUPPORTED_SUBTYPES,
-                    EapAkaPrimeAttributeFactory.getInstance(),
-                    EAP_AKA_SUBTYPE_STRING);
-        }
-
-        /**
-         * Decodes the given byte-array into a DecodeResult object.
-         *
-         * <p>Note that <b>only 1 KDF value</b> is allowed. If multiple AT_KDF attributes are
-         * supplied, a {@link DecodeResult} wrapping a {@link AtClientErrorCode#UNABLE_TO_PROCESS}
-         * will be returned.
-         *
-         * @param typeData the byte-encoding of the EapAkaPrimeTypeData to be parsed
-         * @return a DecodeResult object. If the decoding is successful, this will encapsulate an
-         *     EapAkaPrimeTypeData instance representing the data stored in typeData. Otherwise, it
-         *     will contain the relevant AtClientErrorCode for the decoding error.
-         */
-        public DecodeResult<EapAkaTypeData> decode(@NonNull byte[] typeData) {
-            return super.decode(typeData);
-        }
-
-        @Override
-        protected EapAkaPrimeTypeData getInstance(
-                int eapSubtype, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-            return new EapAkaPrimeTypeData(eapSubtype, attributeMap);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java
deleted file mode 100644
index e3ce817..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeData.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.message.EapMessage;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * EapAkaTypeData represents the Type Data for an {@link EapMessage} during an EAP-AKA session.
- */
-public class EapAkaTypeData extends EapSimAkaTypeData {
-    private static final String TAG = EapAkaTypeData.class.getSimpleName();
-
-    // EAP-AKA Subtype values defined by IANA
-    // https://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xhtml
-    public static final int EAP_AKA_CHALLENGE = 1;
-    public static final int EAP_AKA_AUTHENTICATION_REJECT = 2;
-    public static final int EAP_AKA_SYNCHRONIZATION_FAILURE = 4;
-    public static final int EAP_AKA_IDENTITY = 5;
-    public static final int EAP_AKA_NOTIFICATION = 12;
-    public static final int EAP_AKA_REAUTHENTICATION = 13;
-    public static final int EAP_AKA_CLIENT_ERROR = 14;
-
-    public static final Map<Integer, String> EAP_AKA_SUBTYPE_STRING = new HashMap<>();
-    static {
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_CHALLENGE, "Challenge");
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_AUTHENTICATION_REJECT, "Authentication-Reject");
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_SYNCHRONIZATION_FAILURE, "Synchronization-Failure");
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_IDENTITY, "Identity");
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_NOTIFICATION, "Notification");
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_REAUTHENTICATION, "Re-authentication");
-        EAP_AKA_SUBTYPE_STRING.put(EAP_AKA_CLIENT_ERROR, "Client-Error");
-    }
-
-    protected static final Set<Integer> SUPPORTED_SUBTYPES = new HashSet<>();
-    static {
-        SUPPORTED_SUBTYPES.add(EAP_AKA_CHALLENGE);
-        SUPPORTED_SUBTYPES.add(EAP_AKA_AUTHENTICATION_REJECT);
-        SUPPORTED_SUBTYPES.add(EAP_AKA_SYNCHRONIZATION_FAILURE);
-        SUPPORTED_SUBTYPES.add(EAP_AKA_IDENTITY);
-        SUPPORTED_SUBTYPES.add(EAP_AKA_NOTIFICATION);
-        SUPPORTED_SUBTYPES.add(EAP_AKA_REAUTHENTICATION);
-        SUPPORTED_SUBTYPES.add(EAP_AKA_CLIENT_ERROR);
-    }
-
-    private static final EapAkaTypeDataDecoder sTypeDataDecoder = new EapAkaTypeDataDecoder();
-
-    @VisibleForTesting
-    public EapAkaTypeData(int eapSubType, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-        super(eapSubType, attributeMap);
-    }
-
-    /**
-     * Creates and returns an EapAkaTypeData instance with the given subtype and attributes.
-     *
-     * @param eapSubtype the subtype for the EAP-AKA type data
-     * @param attributes the List of EapSimAkaAttributes to be included in this type data
-     */
-    public EapAkaTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
-        super(eapSubtype, new LinkedHashMap<>());
-
-        if (!SUPPORTED_SUBTYPES.contains(eapSubtype)) {
-            throw new IllegalArgumentException("Invalid subtype for EAP-AKA: " + eapSubtype);
-        }
-
-        for (EapSimAkaAttribute attribute : attributes) {
-            if (attributeMap.containsKey(attribute.attributeType)) {
-                throw new IllegalArgumentException(
-                        "Duplicate attribute in attributes: " + attribute.attributeType);
-            }
-            attributeMap.put(attribute.attributeType, attribute);
-        }
-    }
-
-    public static EapAkaTypeDataDecoder getEapAkaTypeDataDecoder() {
-        return sTypeDataDecoder;
-    }
-
-    /**
-     * EapAkaTypeDataDecoder will be used for decoding {@link EapAkaTypeData} objects.
-     */
-    public static class EapAkaTypeDataDecoder extends EapSimAkaTypeDataDecoder<EapAkaTypeData> {
-        private static final String TAG = EapAkaTypeDataDecoder.class.getSimpleName();
-        private static final String EAP_METHOD = "EAP-AKA";
-
-        protected EapAkaTypeDataDecoder() {
-            super(
-                    TAG,
-                    EAP_METHOD,
-                    SUPPORTED_SUBTYPES,
-                    EapAkaAttributeFactory.getInstance(),
-                    EAP_AKA_SUBTYPE_STRING);
-        }
-
-        /**
-         * Decodes the given byte-array into a DecodeResult object.
-         *
-         * @param typeData the byte-encoding of the EapAkaTypeData to be parsed
-         * @return a DecodeResult object. If the decoding is successful, this will encapsulate an
-         *         EapAkaTypeData instance representing the data stored in typeData. Otherwise, it
-         *         will contain the relevant AtClientErrorCode for the decoding error.
-         */
-        public DecodeResult<EapAkaTypeData> decode(@NonNull byte[] typeData) {
-            return super.decode(typeData);
-        }
-
-        @Override
-        protected EapAkaTypeData getInstance(
-                int eapSubtype,
-                LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-            return new EapAkaTypeData(eapSubtype, attributeMap);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java
deleted file mode 100644
index 73d6752..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttribute.java
+++ /dev/null
@@ -1,1162 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAtPaddingException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimInvalidAtRandException;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * EapSimAkaAttribute represents a single EAP SIM/AKA Attribute.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186">RFC 4186, Extensible Authentication
- * Protocol for Subscriber Identity Modules (EAP-SIM)</a>
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication
- * Protocol for Authentication and Key Agreement (EAP-AKA)</a>
- * @see <a href="https://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml">EAP SIM/AKA
- * Attributes</a>
- */
-public abstract class EapSimAkaAttribute {
-    static final int LENGTH_SCALING = 4;
-
-    private static final int MIN_ATTR_LENGTH = 4;
-
-    public static final int SKIPPABLE_ATTRIBUTE_RANGE_START = 128;
-
-    // EAP non-Skippable Attribute values defined by IANA
-    // https://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xhtml
-    public static final int EAP_AT_RAND = 1;
-    public static final int EAP_AT_AUTN = 2;
-    public static final int EAP_AT_RES = 3;
-    public static final int EAP_AT_AUTS = 4;
-    public static final int EAP_AT_PADDING = 6;
-    public static final int EAP_AT_NONCE_MT = 7;
-    public static final int EAP_AT_PERMANENT_ID_REQ = 10;
-    public static final int EAP_AT_MAC = 11;
-    public static final int EAP_AT_NOTIFICATION = 12;
-    public static final int EAP_AT_ANY_ID_REQ = 13;
-    public static final int EAP_AT_IDENTITY = 14;
-    public static final int EAP_AT_VERSION_LIST = 15;
-    public static final int EAP_AT_SELECTED_VERSION = 16;
-    public static final int EAP_AT_FULLAUTH_ID_REQ = 17;
-    public static final int EAP_AT_COUNTER = 19;
-    public static final int EAP_AT_COUNTER_TOO_SMALL = 20;
-    public static final int EAP_AT_NONCE_S = 21;
-    public static final int EAP_AT_CLIENT_ERROR_CODE = 22;
-    public static final int EAP_AT_KDF_INPUT = 23;
-    public static final int EAP_AT_KDF = 24;
-
-    // EAP Skippable Attribute values defined by IANA
-    // https://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xhtml
-    public static final int EAP_AT_IV = 129;
-    public static final int EAP_AT_ENCR_DATA = 130;
-    public static final int EAP_AT_NEXT_PSEUDONYM = 132;
-    public static final int EAP_AT_NEXT_REAUTH_ID = 133;
-    public static final int EAP_AT_CHECKCODE = 134;
-    public static final int EAP_AT_RESULT_IND = 135;
-    public static final int EAP_AT_BIDDING = 136;
-
-    public static final Map<Integer, String> EAP_ATTRIBUTE_STRING = new HashMap<>();
-    static {
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_RAND, "AT_RAND");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_AUTN, "AT_AUTN");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_RES, "AT_RES");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_AUTS, "AT_AUTS");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_PADDING, "AT_PADDING");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_NONCE_MT, "AT_NONCE_MT");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_PERMANENT_ID_REQ, "AT_PERMANENT_ID_REQ");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_MAC, "AT_MAC");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_NOTIFICATION, "AT_NOTIFICATION");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_ANY_ID_REQ, "AT_ANY_ID_REQ");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_IDENTITY, "AT_IDENTITY");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_VERSION_LIST, "AT_VERSION_LIST");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_SELECTED_VERSION, "AT_SELECTED_VERSION");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_FULLAUTH_ID_REQ, "AT_FULLAUTH_ID_REQ");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_COUNTER, "AT_COUNTER");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_COUNTER_TOO_SMALL, "AT_COUNTER_TOO_SMALL");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_NONCE_S, "AT_NONCE_S");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_CLIENT_ERROR_CODE, "AT_CLIENT_ERROR_CODE");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_KDF_INPUT, "AT_KDF_INPUT");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_KDF, "AT_KDF");
-
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_IV, "AT_IV");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_ENCR_DATA, "AT_ENCR_DATA");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_NEXT_PSEUDONYM, "AT_NEXT_PSEUDONYM");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_NEXT_REAUTH_ID, "AT_NEXT_REAUTH_ID");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_CHECKCODE, "AT_CHECKCODE");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_RESULT_IND, "AT_RESULT_IND");
-        EAP_ATTRIBUTE_STRING.put(EAP_AT_BIDDING, "AT_BIDDING");
-    }
-
-    public final int attributeType;
-    public final int lengthInBytes;
-
-    protected EapSimAkaAttribute(int attributeType, int lengthInBytes)
-            throws EapSimAkaInvalidAttributeException {
-        this.attributeType = attributeType;
-        this.lengthInBytes = lengthInBytes;
-
-        if (lengthInBytes % LENGTH_SCALING != 0) {
-            throw new EapSimAkaInvalidAttributeException("Attribute length must be multiple of 4");
-        }
-    }
-
-    /**
-     * Encodes this EapSimAkaAttribute into the given ByteBuffer
-     *
-     * @param byteBuffer the ByteBuffer that this instance will be written to
-     */
-    public abstract void encode(ByteBuffer byteBuffer);
-
-    protected void encodeAttributeHeader(ByteBuffer byteBuffer) {
-        byteBuffer.put((byte) attributeType);
-        byteBuffer.put((byte) (lengthInBytes / LENGTH_SCALING));
-    }
-
-    void consumePadding(int bytesUsed, ByteBuffer byteBuffer) {
-        int paddingRemaining = lengthInBytes - bytesUsed;
-        byteBuffer.get(new byte[paddingRemaining]);
-    }
-
-    void addPadding(int bytesUsed, ByteBuffer byteBuffer) {
-        int paddingNeeded = lengthInBytes - bytesUsed;
-        byteBuffer.put(new byte[paddingNeeded]);
-    }
-
-    /**
-     * EapSimAkaUnsupportedAttribute represents any unsupported, skippable EAP-SIM attribute.
-     */
-    public static class EapSimAkaUnsupportedAttribute extends EapSimAkaAttribute {
-        // Attribute Type (1B) + Attribute Length (1B) = 2B Header
-        private static final int HEADER_BYTES = 2;
-
-        public final byte[] data;
-
-        public EapSimAkaUnsupportedAttribute(
-                int attributeType,
-                int lengthInBytes,
-                ByteBuffer byteBuffer) throws EapSimAkaInvalidAttributeException {
-            super(attributeType, lengthInBytes);
-
-            // Attribute not supported, but remaining attribute still needs to be saved
-            int remainingBytes = lengthInBytes - HEADER_BYTES;
-            data = new byte[remainingBytes];
-            byteBuffer.get(data);
-        }
-
-        @VisibleForTesting
-        public EapSimAkaUnsupportedAttribute(int attributeType, int lengthInBytes, byte[] data)
-                throws EapSimAkaInvalidAttributeException {
-            super(attributeType, lengthInBytes);
-            this.data = data;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(data);
-        }
-    }
-
-    /**
-     * AtVersionList represents the AT_VERSION_LIST attribute defined in RFC 4186#10.2
-     */
-    public static class AtVersionList extends EapSimAkaAttribute {
-        private static final int BYTES_PER_VERSION = 2;
-
-        public final List<Integer> versions = new ArrayList<>();
-
-        public AtVersionList(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_VERSION_LIST, lengthInBytes);
-
-            // number of bytes used to represent list (RFC 4186 Section 10.2)
-            int bytesInList = Short.toUnsignedInt(byteBuffer.getShort());
-            if (bytesInList % BYTES_PER_VERSION != 0) {
-                throw new EapSimAkaInvalidAttributeException(
-                        "Actual Version List Length must be multiple of 2");
-            }
-
-            int numVersions =  bytesInList / BYTES_PER_VERSION;
-            for (int i = 0; i < numVersions; i++) {
-                versions.add(Short.toUnsignedInt(byteBuffer.getShort()));
-            }
-
-            int bytesUsed = MIN_ATTR_LENGTH + (BYTES_PER_VERSION * versions.size());
-            consumePadding(bytesUsed, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtVersionList(int lengthInBytes, int... versions)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_VERSION_LIST, lengthInBytes);
-            for (int version : versions) {
-                this.versions.add(version);
-            }
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-
-            byteBuffer.putShort((short) (versions.size() * BYTES_PER_VERSION));
-            for (int i : versions) {
-                byteBuffer.putShort((short) i);
-            }
-
-            int bytesUsed = MIN_ATTR_LENGTH + (BYTES_PER_VERSION * versions.size());
-            addPadding(bytesUsed, byteBuffer);
-        }
-    }
-
-    /**
-     * AtSelectedVersion represents the AT_SELECTED_VERSION attribute defined in RFC 4186#10.3
-     */
-    public static class AtSelectedVersion extends EapSimAkaAttribute {
-        private static final String TAG = AtSelectedVersion.class.getSimpleName();
-        private static final int LENGTH = LENGTH_SCALING;
-
-        public static final int SUPPORTED_VERSION = 1;
-
-        public final int selectedVersion;
-
-        public AtSelectedVersion(int lengthInBytes, int selectedVersion)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_SELECTED_VERSION, LENGTH);
-            this.selectedVersion = selectedVersion;
-
-            if (lengthInBytes != LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-        }
-
-        @VisibleForTesting
-        public AtSelectedVersion(int selectedVersion) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_SELECTED_VERSION, LENGTH);
-            this.selectedVersion = selectedVersion;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.putShort((short) selectedVersion);
-        }
-
-        /**
-         * Constructs and returns an AtSelectedVersion for the only supported version of EAP-SIM
-         *
-         * @return an AtSelectedVersion for the supported version (1) of EAP-SIM
-         */
-        public static AtSelectedVersion getSelectedVersion() {
-            try {
-                return new AtSelectedVersion(LENGTH, SUPPORTED_VERSION);
-            } catch (EapSimAkaInvalidAttributeException ex) {
-                // this should never happen
-                LOG.wtf(TAG,
-                        "Error thrown while creating AtSelectedVersion with correct length", ex);
-                throw new AssertionError("Impossible exception encountered", ex);
-            }
-        }
-    }
-
-    /**
-     * AtNonceMt represents the AT_NONCE_MT attribute defined in RFC 4186#10.4
-     */
-    public static class AtNonceMt extends EapSimAkaAttribute {
-        private static final int LENGTH = 5 * LENGTH_SCALING;
-        private static final int RESERVED_BYTES = 2;
-
-        public static final int NONCE_MT_LENGTH = 16;
-
-        public final byte[] nonceMt = new byte[NONCE_MT_LENGTH];
-
-        public AtNonceMt(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_NONCE_MT, LENGTH);
-            if (lengthInBytes != LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            // next two bytes are reserved (RFC 4186 Section 10.4)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-            byteBuffer.get(nonceMt);
-        }
-
-        @VisibleForTesting
-        public AtNonceMt(byte[] nonceMt) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_NONCE_MT, LENGTH);
-
-            if (nonceMt.length != NONCE_MT_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("NonceMt length must be 16B");
-            }
-            System.arraycopy(nonceMt, 0, this.nonceMt, 0, NONCE_MT_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-            byteBuffer.put(nonceMt);
-        }
-    }
-
-    private abstract static class AtIdReq extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = LENGTH_SCALING;
-        private static final int RESERVED_BYTES = 2;
-
-        protected AtIdReq(int lengthInBytes, int attributeType, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(attributeType, ATTR_LENGTH);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            // next two bytes are reserved (RFC 4186 Section 10.5-10.7)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-        }
-
-        @VisibleForTesting
-        protected AtIdReq(int attributeType) throws EapSimAkaInvalidAttributeException {
-            super(attributeType, ATTR_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-        }
-    }
-
-    /**
-     * AtPermanentIdReq represents the AT_PERMANENT_ID_REQ attribute defined in RFC 4186#10.5 and
-     * RFC 4187#10.2
-     */
-    public static class AtPermanentIdReq extends AtIdReq {
-        public AtPermanentIdReq(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(lengthInBytes, EAP_AT_PERMANENT_ID_REQ, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtPermanentIdReq() throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_PERMANENT_ID_REQ);
-        }
-    }
-
-    /**
-     * AtAnyIdReq represents the AT_ANY_ID_REQ attribute defined in RFC 4186#10.6 and RFC 4187#10.3
-     */
-    public static class AtAnyIdReq extends AtIdReq {
-        public AtAnyIdReq(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(lengthInBytes, EAP_AT_ANY_ID_REQ, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtAnyIdReq() throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_ANY_ID_REQ);
-        }
-    }
-
-    /**
-     * AtFullauthIdReq represents the AT_FULLAUTH_ID_REQ attribute defined in RFC 4186#10.7 and RFC
-     * 4187#10.4
-     */
-    public static class AtFullauthIdReq extends AtIdReq {
-        public AtFullauthIdReq(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(lengthInBytes, EAP_AT_FULLAUTH_ID_REQ, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtFullauthIdReq() throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_FULLAUTH_ID_REQ);
-        }
-    }
-
-    /**
-     * AtIdentity represents the AT_IDENTITY attribute defined in RFC 4186#10.8 and RFC 4187#10.5
-     */
-    public static class AtIdentity extends EapSimAkaAttribute {
-        public final byte[] identity;
-
-        public AtIdentity(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_IDENTITY, lengthInBytes);
-
-            int identityLength = Short.toUnsignedInt(byteBuffer.getShort());
-            identity = new byte[identityLength];
-            byteBuffer.get(identity);
-
-            int bytesUsed = MIN_ATTR_LENGTH + identityLength;
-            consumePadding(bytesUsed, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtIdentity(int lengthInBytes, byte[] identity)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_IDENTITY, lengthInBytes);
-            this.identity = identity;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.putShort((short) identity.length);
-            byteBuffer.put(identity);
-
-            int bytesUsed = MIN_ATTR_LENGTH + identity.length;
-            addPadding(bytesUsed, byteBuffer);
-        }
-
-        /**
-         * Creates and returns an AtIdentity instance for the given identity.
-         *
-         * @param identity byte-array representing the identity for the AtIdentity
-         * @return AtIdentity instance for the given identity byte-array
-         */
-        public static AtIdentity getAtIdentity(byte[] identity)
-                throws EapSimAkaInvalidAttributeException {
-            int lengthInBytes = MIN_ATTR_LENGTH + identity.length;
-            if (lengthInBytes % LENGTH_SCALING != 0) {
-                lengthInBytes += LENGTH_SCALING - (lengthInBytes % LENGTH_SCALING);
-            }
-
-            return new AtIdentity(lengthInBytes, identity);
-        }
-    }
-
-    /**
-     * AtRandSim represents the AT_RAND attribute for EAP-SIM defined in RFC 4186#10.9
-     */
-    public static class AtRandSim extends EapSimAkaAttribute {
-        private static final int RAND_LENGTH = 16;
-        private static final int RESERVED_BYTES = 2;
-        private static final int MIN_RANDS = 2;
-        private static final int MAX_RANDS = 3;
-
-        public final List<byte[]> rands = new ArrayList<>(MAX_RANDS);
-
-        public AtRandSim(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_RAND, lengthInBytes);
-
-            // next two bytes are reserved (RFC 4186 Section 10.9)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-
-            int numRands = (lengthInBytes - MIN_ATTR_LENGTH) / RAND_LENGTH;
-            if (!isValidNumRands(numRands)) {
-                throw new EapSimInvalidAtRandException("Unexpected number of rands: " + numRands);
-            }
-
-            for (int i = 0; i < numRands; i++) {
-                byte[] rand = new byte[RAND_LENGTH];
-                byteBuffer.get(rand);
-
-                // check for rand being unique (RFC 4186 Section 10.9)
-                for (int j = 0; j < i; j++) {
-                    byte[] otherRand = rands.get(j);
-                    if (Arrays.equals(rand, otherRand)) {
-                        throw new EapSimAkaInvalidAttributeException("Received identical RANDs");
-                    }
-                }
-                rands.add(rand);
-            }
-        }
-
-        @VisibleForTesting
-        public AtRandSim(int lengthInBytes, byte[]... rands)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_RAND, lengthInBytes);
-
-            if (!isValidNumRands(rands.length)) {
-                throw new EapSimInvalidAtRandException("Unexpected number of rands: "
-                        + rands.length);
-            }
-            for (byte[] rand : rands) {
-                this.rands.add(rand);
-            }
-        }
-
-        private boolean isValidNumRands(int numRands) {
-            // numRands is valid iff 2 <= numRands <= 3
-            return MIN_RANDS <= numRands && numRands <= MAX_RANDS;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-
-            for (byte[] rand : rands) {
-                byteBuffer.put(rand);
-            }
-        }
-    }
-
-    /**
-     * AtRandAka represents the AT_RAND attribute for EAP-AKA defined in RFC 4187#10.6
-     */
-    public static class AtRandAka extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
-        private static final int RAND_LENGTH = 16;
-        private static final int RESERVED_BYTES = 2;
-
-        public final byte[] rand = new byte[RAND_LENGTH];
-
-        public AtRandAka(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_RAND, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Length must be 20B");
-            }
-
-            // next two bytes are reserved (RFC 4187#10.6)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-
-            byteBuffer.get(rand);
-        }
-
-        @VisibleForTesting
-        public AtRandAka(byte[] rand)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_RAND, ATTR_LENGTH);
-
-            if (rand.length != RAND_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Rand must be 16B");
-            }
-
-            System.arraycopy(rand, 0, this.rand, 0, RAND_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-            byteBuffer.put(rand);
-        }
-    }
-
-    /**
-     * AtPadding represents the AT_PADDING attribute defined in RFC 4186#10.12 and RFC 4187#10.12
-     */
-    public static class AtPadding extends EapSimAkaAttribute {
-        private static final int ATTR_HEADER = 2;
-
-        public AtPadding(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_PADDING, lengthInBytes);
-
-            int remainingBytes = lengthInBytes - ATTR_HEADER;
-            for (int i = 0; i < remainingBytes; i++) {
-                // Padding must be checked to all be 0x00 bytes (RFC 4186 Section 10.12)
-                if (byteBuffer.get() != 0) {
-                    throw new EapSimAkaInvalidAtPaddingException("Padding bytes must all be 0x00");
-                }
-            }
-        }
-
-        @VisibleForTesting
-        public AtPadding(int lengthInBytes) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_PADDING, lengthInBytes);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-
-            addPadding(ATTR_HEADER, byteBuffer);
-        }
-    }
-
-    /**
-     * AtMac represents the AT_MAC attribute defined in RFC 4186#10.14 and RFC 4187#10.15
-     */
-    public static class AtMac extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
-        private static final int RESERVED_BYTES = 2;
-
-        public static final int MAC_LENGTH = 4 * LENGTH_SCALING;
-
-        public final byte[] mac;
-
-        public AtMac(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_MAC, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            // next two bytes are reserved (RFC 4186 Section 10.14)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-
-            mac = new byte[MAC_LENGTH];
-            byteBuffer.get(mac);
-        }
-
-        // Used for calculating MACs. Per RFC 4186 Section 10.14, the MAC should be calculated over
-        // the entire packet, with the value field of the MAC attribute set to zero.
-        public AtMac() throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_MAC, ATTR_LENGTH);
-            mac = new byte[MAC_LENGTH];
-        }
-
-        public AtMac(byte[] mac) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_MAC, ATTR_LENGTH);
-            this.mac = mac;
-
-            if (mac.length != MAC_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid length for MAC");
-            }
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-            byteBuffer.put(mac);
-        }
-    }
-
-    /**
-     * AtCounter represents the AT_COUNTER attribute defined in RFC 4186#10.15 and RFC 4187#10.16
-     */
-    public static class AtCounter extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = LENGTH_SCALING;
-
-        public final int counter;
-
-        public AtCounter(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_COUNTER, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            this.counter = Short.toUnsignedInt(byteBuffer.getShort());
-        }
-
-        @VisibleForTesting
-        public AtCounter(int counter) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_COUNTER, ATTR_LENGTH);
-            this.counter = counter;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.putShort((short) counter);
-        }
-    }
-
-
-    /**
-     * AtCounterTooSmall represents the AT_COUNTER_TOO_SMALL attribute defined in RFC 4186#10.16 and
-     * RFC 4187#10.17
-     */
-    public static class AtCounterTooSmall extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = LENGTH_SCALING;
-        private static final int ATTR_HEADER = 2;
-
-        public AtCounterTooSmall(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_COUNTER_TOO_SMALL, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-            consumePadding(ATTR_HEADER, byteBuffer);
-        }
-
-        public AtCounterTooSmall() throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_COUNTER_TOO_SMALL, ATTR_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            addPadding(ATTR_HEADER, byteBuffer);
-        }
-    }
-
-    /**
-     * AtNonceS represents the AT_NONCE_S attribute defined in RFC 4186#10.17 and RFC 4187#10.18
-     *
-     * <p>This Nonce is generated by the server and used for fast re-authentication only.
-     */
-    public static class AtNonceS extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
-        private static final int NONCE_S_LENGTH = 4 * LENGTH_SCALING;
-        private static final int RESERVED_BYTES = 2;
-
-        public final byte[] nonceS = new byte[NONCE_S_LENGTH];
-
-        public AtNonceS(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_NONCE_S, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            // next two bytes are reserved (RFC 4186 Section 10.17)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-            byteBuffer.get(nonceS);
-        }
-
-        @VisibleForTesting
-        public AtNonceS(byte[] nonceS) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_NONCE_S, ATTR_LENGTH);
-
-            if (nonceS.length != NONCE_S_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("NonceS length must be 16B");
-            }
-
-            System.arraycopy(nonceS, 0, this.nonceS, 0, NONCE_S_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-            byteBuffer.put(nonceS);
-        }
-    }
-
-    /**
-     * AtNotification represents the AT_NOTIFICATION attribute defined in RFC 4186#10.18 and RFC
-     * 4187#10.19
-     */
-    public static class AtNotification extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = 4;
-        private static final int SUCCESS_MASK = 0x8000;
-        private static final int PRE_SUCCESSFUL_CHALLENGE_MASK = 0x4000;
-
-        // Notification codes defined in RFC 4186 Section 10.18
-        public static final int GENERAL_FAILURE_POST_CHALLENGE = 0;
-        public static final int GENERAL_FAILURE_PRE_CHALLENGE = 16384; // 0x4000
-        public static final int SUCCESS = 32768; // 0x8000
-        public static final int DENIED_ACCESS_POST_CHALLENGE = 1026;
-        public static final int USER_NOT_SUBSCRIBED_POST_CHALLENGE = 1031;
-
-        private static final Map<Integer, String> CODE_DEFS = loadCodeDefs();
-
-        public final boolean isSuccessCode;
-        public final boolean isPreSuccessfulChallenge;
-        public final int notificationCode;
-
-        public AtNotification(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_NOTIFICATION, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            notificationCode = Short.toUnsignedInt(byteBuffer.getShort());
-
-            // If Success bit == 0, failure is implied
-            isSuccessCode = (notificationCode & SUCCESS_MASK) != 0;
-
-            // if Phase bit == 0, notification code can only be used after a successful
-            isPreSuccessfulChallenge = (notificationCode & PRE_SUCCESSFUL_CHALLENGE_MASK) != 0;
-
-            if (isSuccessCode && isPreSuccessfulChallenge) {
-                throw new EapSimAkaInvalidAttributeException("Invalid state specified");
-            }
-        }
-
-        @VisibleForTesting
-        public AtNotification(int notificationCode) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_NOTIFICATION, ATTR_LENGTH);
-            this.notificationCode = notificationCode;
-
-            // If Success bit == 0, failure is implied
-            isSuccessCode = (notificationCode & SUCCESS_MASK) != 0;
-
-            // if Phase bit == 0, notification code can only be used after a successful challenge
-            isPreSuccessfulChallenge = (notificationCode & PRE_SUCCESSFUL_CHALLENGE_MASK) != 0;
-
-            if (isSuccessCode && isPreSuccessfulChallenge) {
-                throw new EapSimAkaInvalidAttributeException("Invalid state specified");
-            }
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.putShort((short) notificationCode);
-        }
-
-        @Override
-        public String toString() {
-            String description = CODE_DEFS.getOrDefault(notificationCode, "Code not recognized");
-            return "{Notification Code=" + notificationCode + ", descr=" + description + "}";
-        }
-
-        private static Map<Integer, String> loadCodeDefs() {
-            Map<Integer, String> defs = new HashMap<>();
-            defs.put(GENERAL_FAILURE_POST_CHALLENGE,
-                    "General failure after authentication. (Implies failure, used after successful"
-                    + " authentication.)");
-            defs.put(GENERAL_FAILURE_PRE_CHALLENGE,
-                    "General failure. (Implies failure, used before authentication.)");
-            defs.put(SUCCESS,
-                    "Success.  User has been successfully authenticated. (Does not imply failure,"
-                    + " used after successful authentication).");
-            defs.put(DENIED_ACCESS_POST_CHALLENGE,
-                    "User has been temporarily denied access to the requested service. (Implies"
-                    + " failure, used after successful authentication.)");
-            defs.put(USER_NOT_SUBSCRIBED_POST_CHALLENGE,
-                    "User has not subscribed to the requested service.  (Implies failure, used"
-                    + " after successful authentication.)");
-            return defs;
-        }
-    }
-
-    /**
-     * AtClientErrorCode represents the AT_CLIENT_ERROR_CODE attribute defined in RFC 4186#10.19 and
-     * RFC 4187#10.20
-     */
-    public static class AtClientErrorCode extends EapSimAkaAttribute {
-        private static final String TAG = AtClientErrorCode.class.getSimpleName();
-        private static final int ATTR_LENGTH = 4;
-
-        // Error codes defined in RFC 4186 Section 10.19
-        public static final AtClientErrorCode UNABLE_TO_PROCESS = getClientErrorCode(0);
-        public static final AtClientErrorCode UNSUPPORTED_VERSION = getClientErrorCode(1);
-        public static final AtClientErrorCode INSUFFICIENT_CHALLENGES = getClientErrorCode(2);
-        public static final AtClientErrorCode STALE_RANDS = getClientErrorCode(3);
-
-        public final int errorCode;
-
-        public AtClientErrorCode(int lengthInBytes, int errorCode)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_CLIENT_ERROR_CODE, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Invalid Length specified");
-            }
-
-            this.errorCode = errorCode;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.putShort((short) errorCode);
-        }
-
-        private static AtClientErrorCode getClientErrorCode(int errorCode) {
-            try {
-                return new AtClientErrorCode(ATTR_LENGTH, errorCode);
-            } catch (EapSimAkaInvalidAttributeException exception) {
-                LOG.wtf(TAG, "Exception thrown while making AtClientErrorCodeConstants");
-                return null;
-            }
-        }
-    }
-
-    /**
-     * AtAutn represents the AT_AUTN attribute defined in RFC 4187#10.7
-     */
-    public static class AtAutn extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = 5 * LENGTH_SCALING;
-        private static final int AUTN_LENGTH = 16;
-        private static final int RESERVED_BYTES = 2;
-
-        public final byte[] autn = new byte[AUTN_LENGTH];
-
-        public AtAutn(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_AUTN, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Length must be 20B");
-            }
-
-            // next two bytes are reserved (RFC 4187#10.7)
-            byteBuffer.get(new byte[RESERVED_BYTES]);
-
-            byteBuffer.get(autn);
-        }
-
-        @VisibleForTesting
-        public AtAutn(byte[] autn) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_AUTN, ATTR_LENGTH);
-
-            if (autn.length != AUTN_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Autn must be 16B");
-            }
-
-            System.arraycopy(autn, 0, this.autn, 0, AUTN_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.put(new byte[RESERVED_BYTES]);
-            byteBuffer.put(autn);
-        }
-    }
-
-    /**
-     * AtRes respresents the AT_RES attribute defined in RFC 4187#10.8
-     */
-    public static class AtRes extends EapSimAkaAttribute {
-        private static final int BITS_PER_BYTE = 8;
-        private static final int MIN_RES_LEN_BYTES = 4;
-        private static final int MAX_RES_LEN_BYTES = 16;
-
-        public final byte[] res;
-
-        public AtRes(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_RES, lengthInBytes);
-
-            // RES length is in bits (RFC 4187#10.8).
-            // RES length should be a multiple of 8 bits (TS 133 105#5.1.7.8)
-            int resLength = Short.toUnsignedInt(byteBuffer.getShort());
-            if (resLength % BITS_PER_BYTE != 0) {
-                throw new EapSimAkaInvalidAttributeException("RES length must be multiple of 8");
-            }
-            int resLengthBytes = resLength / BITS_PER_BYTE;
-            if (resLengthBytes < MIN_RES_LEN_BYTES || resLengthBytes > MAX_RES_LEN_BYTES) {
-                throw new EapSimAkaInvalidAttributeException(
-                        "RES length must be: 4B <= len <= 16B");
-            }
-
-            res = new byte[resLengthBytes];
-            byteBuffer.get(res);
-
-            int bytesUsed = MIN_ATTR_LENGTH + resLengthBytes;
-            consumePadding(bytesUsed, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtRes(int lengthInBytes, byte[] res) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_RES, lengthInBytes);
-
-            if (res.length < MIN_RES_LEN_BYTES || res.length > MAX_RES_LEN_BYTES) {
-                throw new EapSimAkaInvalidAttributeException(
-                        "RES length must be: 4B <= len <= 16B");
-            }
-
-            this.res = res;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-
-            int resLenBits = res.length * BITS_PER_BYTE;
-            byteBuffer.putShort((short) resLenBits);
-            byteBuffer.put(res);
-
-            int bytesUsed = MIN_ATTR_LENGTH + res.length;
-            addPadding(bytesUsed, byteBuffer);
-        }
-
-        /**
-         * Creates and returns an AtRes instance with the given res value.
-         *
-         * @param res byte-array RES value to be used for this
-         * @return AtRes instance for the given RES value
-         * @throws EapSimAkaInvalidAttributeException if the given res value has an invalid length
-         */
-        public static AtRes getAtRes(byte[] res) throws EapSimAkaInvalidAttributeException {
-            // Attributes must be 4B-aligned, so there can be 0 to 3 padding bytes added
-            int resLenBytes = MIN_ATTR_LENGTH + res.length;
-            if (resLenBytes % LENGTH_SCALING != 0) {
-                resLenBytes += LENGTH_SCALING - (resLenBytes % LENGTH_SCALING);
-            }
-
-            return new AtRes(resLenBytes, res);
-        }
-
-        /**
-         * Checks whether the given RES length is valid.
-         *
-         * @param resLenBytes the RES length to be checked
-         * @return true iff the given resLen is valid
-         */
-        public static boolean isValidResLen(int resLenBytes) {
-            return resLenBytes >= MIN_RES_LEN_BYTES && resLenBytes <= MAX_RES_LEN_BYTES;
-        }
-    }
-
-    /**
-     * AtAuts represents the AT_AUTS attribute defined in RFC 4187#10.9
-     */
-    public static class AtAuts extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = 4 * LENGTH_SCALING;
-        public static final int AUTS_LENGTH = 14;
-
-        public final byte[] auts = new byte[AUTS_LENGTH];
-
-        public AtAuts(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_AUTS, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Length must be 16B");
-            }
-
-            byteBuffer.get(auts);
-        }
-
-        public AtAuts(byte[] auts) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_AUTS, ATTR_LENGTH);
-
-            if (auts.length != AUTS_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("Auts must be 14B");
-            }
-
-            System.arraycopy(auts, 0, this.auts, 0, AUTS_LENGTH);
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-
-            byteBuffer.put(auts);
-        }
-    }
-
-    /**
-     * AtKdfInput represents the AT_KDF_INPUT attribute defined in RFC 5448#3.1
-     */
-    public static class AtKdfInput extends EapSimAkaAttribute {
-        public final byte[] networkName;
-
-        public AtKdfInput(int lengthInBytes, ByteBuffer byteBuffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_KDF_INPUT, lengthInBytes);
-
-            int networkNameLength = Short.toUnsignedInt(byteBuffer.getShort());
-            networkName = new byte[networkNameLength];
-            byteBuffer.get(networkName);
-
-            int bytesUsed = MIN_ATTR_LENGTH + networkNameLength;
-            consumePadding(bytesUsed, byteBuffer);
-        }
-
-        @VisibleForTesting
-        public AtKdfInput(int lengthInbytes, byte[] networkName)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_KDF_INPUT, lengthInbytes);
-
-            this.networkName = networkName;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-            byteBuffer.putShort((short) networkName.length);
-            byteBuffer.put(networkName);
-
-            int bytesUsed = MIN_ATTR_LENGTH + networkName.length;
-            addPadding(bytesUsed, byteBuffer);
-        }
-    }
-
-    /**
-     * AdKdf represents the AT_KDF attribute defined in RFC 5448#3.2
-     */
-    public static class AtKdf extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = MIN_ATTR_LENGTH;
-
-        public final int kdf;
-
-        public AtKdf(int lengthInBytes, ByteBuffer buffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_KDF, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("AtKdf length must be 4B");
-            }
-
-            kdf = Short.toUnsignedInt(buffer.getShort());
-        }
-
-        @VisibleForTesting
-        public AtKdf(int kdf) throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_KDF, ATTR_LENGTH);
-
-            this.kdf = kdf;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-
-            byteBuffer.putShort((short) kdf);
-        }
-    }
-
-    /**
-     * AtBidding represents the AT_BIDDING attribute defined in RFC 5448#4
-     */
-    public static class AtBidding extends EapSimAkaAttribute {
-        private static final int ATTR_LENGTH = MIN_ATTR_LENGTH;
-        private static final int SUPPORTS_EAP_AKA_PRIME_MASK = 0x8000;
-
-        public final boolean doesServerSupportEapAkaPrime;
-
-        public AtBidding(int lengthInBytes, ByteBuffer buffer)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_BIDDING, lengthInBytes);
-
-            if (lengthInBytes != ATTR_LENGTH) {
-                throw new EapSimAkaInvalidAttributeException("AtBidding length must be 4B");
-            }
-
-            int serverFlag = Short.toUnsignedInt(buffer.getShort());
-            doesServerSupportEapAkaPrime = (serverFlag & SUPPORTS_EAP_AKA_PRIME_MASK) != 0;
-        }
-
-        @VisibleForTesting
-        public AtBidding(boolean doesServerSupportEapAkaPrime)
-                throws EapSimAkaInvalidAttributeException {
-            super(EAP_AT_BIDDING, ATTR_LENGTH);
-
-            this.doesServerSupportEapAkaPrime = doesServerSupportEapAkaPrime;
-        }
-
-        @Override
-        public void encode(ByteBuffer byteBuffer) {
-            encodeAttributeHeader(byteBuffer);
-
-            int flagToWrite = doesServerSupportEapAkaPrime ? SUPPORTS_EAP_AKA_PRIME_MASK : 0;
-            byteBuffer.putShort((short) flagToWrite);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactory.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactory.java
deleted file mode 100644
index df79a25..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactory.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_CLIENT_ERROR_CODE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_COUNTER;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_COUNTER_TOO_SMALL;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_FULLAUTH_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NONCE_S;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PADDING;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.LENGTH_SCALING;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.SKIPPABLE_ATTRIBUTE_RANGE_START;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtCounter;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtCounterTooSmall;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtFullauthIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceS;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPadding;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EapSimAkaUnsupportedAttribute;
-
-import java.nio.ByteBuffer;
-
-/**
- * EapSimAkaAttributeFactory is used for creating EapSimAkaAttributes according to their type.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186">RFC 4186, Extensible Authentication
- * Protocol for Subscriber Identity Modules (EAP-SIM)</a>
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication
- * Protocol for Authentication and Key Agreement (EAP-AKA)</a>
- * @see <a href="https://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml">EAP SIM/AKA
- * Attributes</a>
- */
-public abstract class EapSimAkaAttributeFactory {
-    /**
-     * Decodes a single EapSimAkaAttribute object from the given ByteBuffer.
-     *
-     * <p>Decoding logic is based on Attribute definitions in RFC 4186#10 and RFC 4187#10.
-     *
-     * @param attributeType the attribute type to be decoded
-     * @param lengthInBytes the length in bytes of the attribute to be decoded
-     * @param byteBuffer The ByteBuffer to parse the current attribute from
-     * @return The current EapSimAkaAttribute to be parsed, or EapSimAkaUnsupportedAttribute if the
-     *     given attributeType is skippable and unsupported
-     * @throws EapSimAkaInvalidAttributeException when a malformatted attribute is attempted to be
-     *     decoded
-     * @throws EapSimAkaUnsupportedAttributeException when an unsupported, unskippable Attribute is
-     *     attempted to be decoded
-     */
-    EapSimAkaAttribute getAttribute(int attributeType, int lengthInBytes, ByteBuffer byteBuffer)
-            throws EapSimAkaInvalidAttributeException, EapSimAkaUnsupportedAttributeException {
-        switch (attributeType) {
-            // TODO(b/139482157): define optional shared attributes
-            case EAP_AT_PERMANENT_ID_REQ:
-                return new AtPermanentIdReq(lengthInBytes, byteBuffer);
-            case EAP_AT_ANY_ID_REQ:
-                return new AtAnyIdReq(lengthInBytes, byteBuffer);
-            case EAP_AT_FULLAUTH_ID_REQ:
-                return new AtFullauthIdReq(lengthInBytes, byteBuffer);
-            case EAP_AT_IDENTITY:
-                return new AtIdentity(lengthInBytes, byteBuffer);
-            case EAP_AT_PADDING:
-                return new AtPadding(lengthInBytes, byteBuffer);
-            case EAP_AT_MAC:
-                return new AtMac(lengthInBytes, byteBuffer);
-            case EAP_AT_COUNTER:
-                return new AtCounter(lengthInBytes, byteBuffer);
-            case EAP_AT_COUNTER_TOO_SMALL:
-                return new AtCounterTooSmall(lengthInBytes, byteBuffer);
-            case EAP_AT_NONCE_S:
-                return new AtNonceS(lengthInBytes, byteBuffer);
-            case EAP_AT_NOTIFICATION:
-                return new AtNotification(lengthInBytes, byteBuffer);
-            case EAP_AT_CLIENT_ERROR_CODE:
-                int errorCode = Short.toUnsignedInt(byteBuffer.getShort());
-                return new AtClientErrorCode(lengthInBytes, errorCode);
-            default:
-                if (attributeType >= SKIPPABLE_ATTRIBUTE_RANGE_START) {
-                    return new EapSimAkaUnsupportedAttribute(
-                            attributeType, lengthInBytes, byteBuffer);
-                }
-
-                throw new EapSimAkaUnsupportedAttributeException(
-                        "Unexpected EAP Attribute=" + attributeType);
-        }
-    }
-
-    /**
-     * This method exists only for testing.
-     *
-     * <p>It follows the attributeFactory.getAttribute(ByteBuffer) pattern used by
-     * EapSimAttributeFactory and EapAkaAttributeFactory.
-     */
-    @VisibleForTesting
-    public EapSimAkaAttribute getAttribute(ByteBuffer byteBuffer)
-            throws EapSimAkaInvalidAttributeException, EapSimAkaUnsupportedAttributeException {
-        int attributeType = Byte.toUnsignedInt(byteBuffer.get());
-
-        // Length is given as a multiple of 4x bytes (RFC 4186 Section 8.1)
-        int lengthInBytes = Byte.toUnsignedInt(byteBuffer.get()) * LENGTH_SCALING;
-        return getAttribute(attributeType, lengthInBytes, byteBuffer);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java
deleted file mode 100644
index c84fdf4..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaTypeData.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_ATTRIBUTE_STRING;
-
-import android.annotation.NonNull;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimInvalidAtRandException;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EapSimAkaUnsupportedAttribute;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * EapSimTypeData represents the Type Data for an {@link EapMessage} during an EAP-SIM session.
- */
-public abstract class EapSimAkaTypeData {
-    private static final int MIN_LEN_BYTES = 3; // subtype (1B) + reserved bytes (2B)
-    private static final int RESERVED_BYTES = 2; // RFC 4186#8.1, RFC 4187#8.1
-
-    public final int eapSubtype;
-
-    // LinkedHashMap used to preserve encoded ordering of attributes. This is necessary for checking
-    // the MAC value for the message
-    public final LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap;
-
-    public EapSimAkaTypeData(
-            int eapSubType,
-            LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-        this.eapSubtype = eapSubType;
-        this.attributeMap = attributeMap;
-    }
-
-    /**
-     * Creates and returns the byte-array encoding of this EapSimTypeData instance.
-     *
-     * @return byte[] representing the byte-encoding of this EapSimTypeData instance.
-     */
-    public byte[] encode() {
-        int lengthInBytes = MIN_LEN_BYTES;
-        for (EapSimAkaAttribute attribute : attributeMap.values()) {
-            lengthInBytes += attribute.lengthInBytes;
-        }
-
-        ByteBuffer output = ByteBuffer.allocate(lengthInBytes);
-        output.put((byte) eapSubtype);
-
-        // two reserved bytes (RFC 4186#8.1, RFC 4187#8.1)
-        output.put(new byte[RESERVED_BYTES]);
-
-        for (EapSimAkaAttribute attribute : attributeMap.values()) {
-            attribute.encode(output);
-        }
-
-        return output.array();
-    }
-
-    /**
-     * Class for decoding EAP-SIM and EAP-AKA type-datas.
-     *
-     * @param <T> The EapSimAkaTypeData type that the EapSimAkaTypeDataDecoder will be decoding
-     */
-    public abstract static class EapSimAkaTypeDataDecoder<T extends EapSimAkaTypeData> {
-        private final String mTAG;
-        private final String mEapMethod;
-        private final Set<Integer> mSupportedSubtypes;
-        private final EapSimAkaAttributeFactory mAttributeFactory;
-        private final Map<Integer, String> mEapSubtypeStrings;
-
-        EapSimAkaTypeDataDecoder(
-                String tag,
-                String eapMethod,
-                Set<Integer> supportedSubtypes,
-                EapSimAkaAttributeFactory eapSimAkaAttributeFactory,
-                Map<Integer, String> eapSubtypeStrings) {
-            this.mTAG = tag;
-            this.mEapMethod = eapMethod;
-            this.mSupportedSubtypes = supportedSubtypes;
-            this.mAttributeFactory = eapSimAkaAttributeFactory;
-            this.mEapSubtypeStrings = eapSubtypeStrings;
-        }
-
-        protected DecodeResult<T> decode(@NonNull byte[] typeData) {
-            if (typeData == null) {
-                LOG.d(mTAG, "Invalid EAP Type-Data");
-                return new DecodeResult<>(AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            ByteBuffer byteBuffer = ByteBuffer.wrap(typeData);
-            try {
-                int eapSubType = Byte.toUnsignedInt(byteBuffer.get());
-                if (!mSupportedSubtypes.contains(eapSubType)) {
-                    LOG.d(mTAG, "Invalid EAP Type-Data");
-                    return new DecodeResult<>(AtClientErrorCode.UNABLE_TO_PROCESS);
-                }
-
-                // next two bytes are reserved (RFC 4186#8.1, RFC 4187#8.1)
-                byteBuffer.get(new byte[RESERVED_BYTES]);
-
-                // read attributes
-                LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap = new LinkedHashMap<>();
-                while (byteBuffer.hasRemaining()) {
-                    EapSimAkaAttribute attribute = mAttributeFactory.getAttribute(byteBuffer);
-
-                    if (attributeMap.containsKey(attribute.attributeType)) {
-                        // Duplicate attributes are not allowed (RFC 4186#6.3.1, RFC 4187#6.3.1)
-                        LOG.e(mTAG, "Duplicate attribute in parsed EAP-Message");
-                        return new DecodeResult<>(AtClientErrorCode.UNABLE_TO_PROCESS);
-                    }
-
-                    if (attribute instanceof EapSimAkaUnsupportedAttribute) {
-                        LOG.d(mTAG, "Unsupported EAP-SIM attribute during decoding: "
-                                + attribute.attributeType);
-                    }
-                    attributeMap.put(attribute.attributeType, attribute);
-                }
-
-                T eapSimAkaTypeData = getInstance(eapSubType, attributeMap);
-
-                logDecodedEapSimTypeData(eapSimAkaTypeData);
-
-                return new DecodeResult<>(eapSimAkaTypeData);
-            } catch (EapSimInvalidAtRandException ex) {
-                LOG.e(mTAG, "Invalid AtRand attribute", ex);
-                return new DecodeResult<>(AtClientErrorCode.INSUFFICIENT_CHALLENGES);
-            } catch (EapSimAkaInvalidAttributeException | BufferUnderflowException ex) {
-                LOG.e(mTAG, "Incorrectly formatted attribute", ex);
-                return new DecodeResult<>(AtClientErrorCode.UNABLE_TO_PROCESS);
-            } catch (EapSimAkaUnsupportedAttributeException ex) {
-                LOG.e(mTAG, "Unrecognized, non-skippable attribute encountered", ex);
-                return new DecodeResult<>(AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-        }
-
-        protected abstract T getInstance(
-                int eapSubType,
-                LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap);
-
-        private void logDecodedEapSimTypeData(EapSimAkaTypeData eapSimAkaTypeData) {
-            StringBuilder msg = new StringBuilder();
-            msg.append("Decoded ");
-            msg.append(mEapMethod);
-            msg.append(" type data: ");
-
-            msg.append(mEapSubtypeStrings.getOrDefault(eapSimAkaTypeData.eapSubtype, "Unknown"));
-            msg.append(" attributes=[ ");
-            for (int attributeType : eapSimAkaTypeData.attributeMap.keySet()) {
-                msg.append(
-                        EAP_ATTRIBUTE_STRING.getOrDefault(attributeType,
-                                "Unknown(" + attributeType + ")"));
-                msg.append(" ");
-            }
-            msg.append("]");
-            LOG.i(mTAG, msg.toString());
-        }
-    }
-
-    /**
-     * DecodeResult represents the result from calling EapSimTypeDataDecoder.decode(). It will
-     * contain either a decoded EapSimTypeData or the relevant AtClientErrorCode.
-     *
-     * @param <T> The EapSimAkaTypeData type that is wrapped in this DecodeResult
-     */
-    public static class DecodeResult<T extends EapSimAkaTypeData> {
-        public final T eapTypeData;
-        public final EapSimAkaAttribute.AtClientErrorCode atClientErrorCode;
-
-        public DecodeResult(T eapTypeData) {
-            this.eapTypeData = eapTypeData;
-            this.atClientErrorCode = null;
-        }
-
-        public DecodeResult(EapSimAkaAttribute.AtClientErrorCode atClientErrorCode) {
-            this.atClientErrorCode = atClientErrorCode;
-            eapTypeData = null;
-        }
-
-        public boolean isSuccessfulDecode() {
-            return eapTypeData != null;
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimAttributeFactory.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimAttributeFactory.java
deleted file mode 100644
index 8be348e..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimAttributeFactory.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NONCE_MT;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_SELECTED_VERSION;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.LENGTH_SCALING;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtSelectedVersion;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-
-import java.nio.ByteBuffer;
-
-/**
- * EapSimAttributeFactory is used for creating EAP-SIM attributes according to their type.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186">RFC 4186, Extensible Authentication
- * Protocol for Subscriber Identity Modules (EAP-SIM)</a>
- * @see <a href="https://www.iana.org/assignments/eap-numbers/eap-numbers.xhtml">EAP SIM/AKA
- * Attributes</a>
- */
-public class EapSimAttributeFactory extends EapSimAkaAttributeFactory {
-    private static EapSimAttributeFactory sInstance = new EapSimAttributeFactory();
-
-    private EapSimAttributeFactory() {
-    }
-
-    public static EapSimAttributeFactory getInstance() {
-        return sInstance;
-    }
-
-    /**
-     * Decodes a single EapSimAkaAttribute object from the given ByteBuffer.
-     *
-     * <p>Decoding logic is based on Attribute definitions in RFC 4186#10.
-     *
-     * @param byteBuffer The ByteBuffer to parse the current attribute from
-     * @return The current EapSimAkaAttribute to be parsed, or EapSimAkaUnsupportedAttribute if the
-     *         given attributeType is skippable and unsupported
-     * @throws EapSimAkaInvalidAttributeException when a malformatted attribute is attempted to be
-     *         decoded
-     * @throws EapSimAkaUnsupportedAttributeException when an unsupported, unskippable Attribute is
-     *         attempted to be decoded
-     */
-    public EapSimAkaAttribute getAttribute(ByteBuffer byteBuffer) throws
-            EapSimAkaInvalidAttributeException, EapSimAkaUnsupportedAttributeException {
-        int attributeType = Byte.toUnsignedInt(byteBuffer.get());
-
-        // Length is given as a multiple of 4x bytes (RFC 4186 Section 8.1)
-        int lengthInBytes = Byte.toUnsignedInt(byteBuffer.get()) * LENGTH_SCALING;
-
-        switch (attributeType) {
-            // TODO(b/134670528): add case statements for all EAP-SIM attributes
-            case EAP_AT_VERSION_LIST:
-                return new AtVersionList(lengthInBytes, byteBuffer);
-            case EAP_AT_SELECTED_VERSION:
-                int selectedVersion = Short.toUnsignedInt(byteBuffer.getShort());
-                return new AtSelectedVersion(lengthInBytes, selectedVersion);
-            case EAP_AT_NONCE_MT:
-                return new AtNonceMt(lengthInBytes, byteBuffer);
-            case EAP_AT_RAND:
-                return new AtRandSim(lengthInBytes, byteBuffer);
-            default:
-                return super.getAttribute(attributeType, lengthInBytes, byteBuffer);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java b/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java
deleted file mode 100644
index ff1be60..0000000
--- a/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeData.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.message.EapMessage;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * EapSimTypeData represents the Type Data for an {@link EapMessage} during an EAP-SIM session.
- */
-public class EapSimTypeData extends EapSimAkaTypeData {
-    private static final String TAG = EapSimTypeData.class.getSimpleName();
-
-    // EAP-SIM Subtype values defined by IANA
-    // https://www.iana.org/assignments/eapsimaka-numbers/eapsimaka-numbers.xhtml
-    public static final int EAP_SIM_START = 10;
-    public static final int EAP_SIM_CHALLENGE = 11;
-    public static final int EAP_SIM_NOTIFICATION = 12;
-    public static final int EAP_SIM_REAUTHENTICATION = 13;
-    public static final int EAP_SIM_CLIENT_ERROR = 14;
-
-    public static final Map<Integer, String> EAP_SIM_SUBTYPE_STRING = new HashMap<>();
-    static {
-        EAP_SIM_SUBTYPE_STRING.put(EAP_SIM_START, "Start");
-        EAP_SIM_SUBTYPE_STRING.put(EAP_SIM_CHALLENGE, "Challenge");
-        EAP_SIM_SUBTYPE_STRING.put(EAP_SIM_NOTIFICATION, "Notification");
-        EAP_SIM_SUBTYPE_STRING.put(EAP_SIM_REAUTHENTICATION, "Re-authentication");
-        EAP_SIM_SUBTYPE_STRING.put(EAP_SIM_CLIENT_ERROR, "Client-Error");
-    }
-
-    private static final Set<Integer> SUPPORTED_SUBTYPES = new HashSet<>();
-    static {
-        SUPPORTED_SUBTYPES.add(EAP_SIM_START);
-        SUPPORTED_SUBTYPES.add(EAP_SIM_CHALLENGE);
-        SUPPORTED_SUBTYPES.add(EAP_SIM_NOTIFICATION);
-        SUPPORTED_SUBTYPES.add(EAP_SIM_REAUTHENTICATION);
-        SUPPORTED_SUBTYPES.add(EAP_SIM_CLIENT_ERROR);
-    }
-
-    private static final EapSimTypeDataDecoder sTypeDataDecoder = new EapSimTypeDataDecoder();
-
-    @VisibleForTesting
-    public EapSimTypeData(int eapSubType, LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-        super(eapSubType, attributeMap);
-    }
-
-    public EapSimTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
-        super(eapSubtype, new LinkedHashMap<>());
-
-        if (!SUPPORTED_SUBTYPES.contains(eapSubtype)) {
-            throw new IllegalArgumentException("Invalid subtype for EAP-SIM: " + eapSubtype);
-        }
-
-        for (EapSimAkaAttribute attribute : attributes) {
-            if (attributeMap.containsKey(attribute.attributeType)) {
-                throw new IllegalArgumentException(
-                        "Duplicate attribute in attributes: " + attribute.attributeType);
-            }
-            attributeMap.put(attribute.attributeType, attribute);
-        }
-    }
-
-    public static EapSimTypeDataDecoder getEapSimTypeDataDecoder() {
-        return sTypeDataDecoder;
-    }
-
-    /**
-     * EapSimTypeDataDecoder will be used for decoding {@link EapSimTypeData} objects.
-     */
-    public static class EapSimTypeDataDecoder extends EapSimAkaTypeDataDecoder<EapSimTypeData> {
-        private static final String TAG = EapSimTypeDataDecoder.class.getSimpleName();
-        private static final String EAP_METHOD = "EAP-SIM";
-
-        protected EapSimTypeDataDecoder() {
-            super(
-                    TAG,
-                    EAP_METHOD,
-                    SUPPORTED_SUBTYPES,
-                    EapSimAttributeFactory.getInstance(),
-                    EAP_SIM_SUBTYPE_STRING);
-        }
-
-        /**
-         * Decodes the given byte-array into a DecodeResult object.
-         *
-         * @param typeData the byte-encoding of the EapSimTypeData to be parsed
-         * @return a DecodeResult object. If the decoding is successful, this will encapsulate an
-         *         EapSimTypeData instance representing the data stored in typeData. Otherwise, it
-         *         will contain the relevant AtClientErrorCode for the decoding error.
-         */
-        public DecodeResult<EapSimTypeData> decode(@NonNull byte[] typeData) {
-            return super.decode(typeData);
-        }
-
-        @Override
-        protected EapSimTypeData getInstance(
-                int eapSubtype,
-                LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap) {
-            return new EapSimTypeData(eapSubtype, attributeMap);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java
deleted file mode 100644
index b26c8e9..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachine.java
+++ /dev/null
@@ -1,612 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_AUTHENTICATION_REJECT;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CLIENT_ERROR;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_SYNCHRONIZATION_FAILURE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_BIDDING;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ENCR_DATA;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_FULLAUTH_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IV;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.crypto.Fips186_2Prf;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.simaka.EapAkaInvalidAuthenticationResponse;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAuts;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * EapAkaMethodStateMachine represents the valid paths possible for the EAP-AKA protocol.
- *
- * <p>EAP-AKA sessions will always follow the path:
- *
- * Created --+--> Identity --+--> Challenge --> Final
- *           |               |
- *           +---------------+
- *
- * Note: If the EAP-Request/AKA-Challenge message contains an AUTN with an invalid sequence number,
- * the peer will indicate a synchronization failure to the server and a new challenge will be
- * attempted.
- *
- * Note: EAP-Request/Notification messages can be received at any point in the above state machine
- * At most one EAP-AKA/Notification message is allowed per EAP-AKA session.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication
- * Protocol for Authentication and Key Agreement (EAP-AKA)</a>
- */
-class EapAkaMethodStateMachine extends EapSimAkaMethodStateMachine {
-    private static final String TAG = EapAkaMethodStateMachine.class.getSimpleName();
-
-    // EAP-AKA identity prefix (RFC 4187#4.1.1.6)
-    private static final String AKA_IDENTITY_PREFIX = "0";
-
-    private final EapAkaTypeDataDecoder mEapAkaTypeDataDecoder;
-    private final boolean mSupportsEapAkaPrime;
-
-    protected EapAkaMethodStateMachine(
-            Context context, byte[] eapIdentity, EapAkaConfig eapAkaConfig) {
-        this(context, eapIdentity, eapAkaConfig, false);
-    }
-
-    EapAkaMethodStateMachine(
-            Context context,
-            byte[] eapIdentity,
-            EapAkaConfig eapAkaConfig,
-            boolean supportsEapAkaPrime) {
-        this(
-                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
-                eapIdentity,
-                eapAkaConfig,
-                EapAkaTypeData.getEapAkaTypeDataDecoder(),
-                supportsEapAkaPrime);
-    }
-
-    @VisibleForTesting
-    protected EapAkaMethodStateMachine(
-            TelephonyManager telephonyManager,
-            byte[] eapIdentity,
-            EapAkaConfig eapAkaConfig,
-            EapAkaTypeDataDecoder eapAkaTypeDataDecoder,
-            boolean supportsEapAkaPrime) {
-        super(
-                telephonyManager.createForSubscriptionId(eapAkaConfig.subId),
-                eapIdentity,
-                eapAkaConfig);
-        mEapAkaTypeDataDecoder = eapAkaTypeDataDecoder;
-        mSupportsEapAkaPrime = supportsEapAkaPrime;
-
-        transitionTo(new CreatedState());
-    }
-
-    @Override
-    @EapMethod
-    int getEapMethod() {
-        return EAP_TYPE_AKA;
-    }
-
-    protected DecodeResult<EapAkaTypeData> decode(byte[] typeData) {
-        return mEapAkaTypeDataDecoder.decode(typeData);
-    }
-
-    /**
-     * This exists so we can override the identity prefix in the EapAkaPrimeMethodStateMachine.
-     *
-     * @return the Identity prefix for this EAP method
-     */
-    protected String getIdentityPrefix() {
-        return AKA_IDENTITY_PREFIX;
-    }
-
-    protected ChallengeState buildChallengeState() {
-        return new ChallengeState();
-    }
-
-    protected ChallengeState buildChallengeState(byte[] identity) {
-        return new ChallengeState(identity);
-    }
-
-    protected class CreatedState extends EapMethodState {
-        private final String mTAG = CreatedState.class.getSimpleName();
-
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            DecodeResult<? extends EapAkaTypeData> decodeResult =
-                    decode(message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier, getEapMethod(), decodeResult.atClientErrorCode);
-            }
-
-            EapAkaTypeData eapAkaTypeData = decodeResult.eapTypeData;
-            switch (eapAkaTypeData.eapSubtype) {
-                case EAP_AKA_IDENTITY:
-                    return transitionAndProcess(new IdentityState(), message);
-                case EAP_AKA_CHALLENGE:
-                    return transitionAndProcess(buildChallengeState(), message);
-                case EAP_AKA_NOTIFICATION:
-                    return handleEapSimAkaNotification(
-                            mTAG,
-                            true, // isPreChallengeState
-                            message.eapIdentifier,
-                            eapAkaTypeData);
-                default:
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            getEapMethod(),
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-        }
-    }
-
-    protected class IdentityState extends EapMethodState {
-        private final String mTAG = IdentityState.class.getSimpleName();
-
-        private byte[] mIdentity;
-
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            DecodeResult<? extends EapAkaTypeData> decodeResult =
-                    decode(message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier, getEapMethod(), decodeResult.atClientErrorCode);
-            }
-
-            EapAkaTypeData eapAkaTypeData = decodeResult.eapTypeData;
-            switch (eapAkaTypeData.eapSubtype) {
-                case EAP_AKA_IDENTITY:
-                    break;
-                case EAP_AKA_CHALLENGE:
-                    return transitionAndProcess(buildChallengeState(mIdentity), message);
-                case EAP_AKA_NOTIFICATION:
-                    return handleEapSimAkaNotification(
-                            mTAG,
-                            true, // isPreChallengeState
-                            message.eapIdentifier,
-                            eapAkaTypeData);
-                default:
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            getEapMethod(),
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            if (!isValidIdentityAttributes(eapAkaTypeData)) {
-                LOG.e(mTAG, "Invalid attributes: " + eapAkaTypeData.attributeMap.keySet());
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_AKA,
-                        AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            String imsi = mTelephonyManager.getSubscriberId();
-            if (imsi == null) {
-                LOG.e(mTAG, "Unable to get IMSI for subId=" + mEapUiccConfig.subId);
-                return new EapError(
-                        new EapSimAkaIdentityUnavailableException(
-                                "IMSI for subId (" + mEapUiccConfig.subId + ") not available"));
-            }
-            String identityString = getIdentityPrefix() + imsi;
-            mIdentity = identityString.getBytes(StandardCharsets.US_ASCII);
-            LOG.d(mTAG, "EAP-AKA/Identity=" + LOG.pii(identityString));
-
-            AtIdentity atIdentity;
-            try {
-                atIdentity = AtIdentity.getAtIdentity(mIdentity);
-            } catch (EapSimAkaInvalidAttributeException ex) {
-                LOG.wtf(mTAG, "Exception thrown while making AtIdentity attribute", ex);
-                return new EapError(ex);
-            }
-
-            return buildResponseMessage(
-                    getEapMethod(),
-                    EAP_AKA_IDENTITY,
-                    message.eapIdentifier,
-                    Arrays.asList(atIdentity));
-        }
-
-        private boolean isValidIdentityAttributes(EapAkaTypeData eapAkaTypeData) {
-            Set<Integer> attrs = eapAkaTypeData.attributeMap.keySet();
-
-            // exactly one ID request type required
-            int idRequests = 0;
-            idRequests += attrs.contains(EAP_AT_PERMANENT_ID_REQ) ? 1 : 0;
-            idRequests += attrs.contains(EAP_AT_ANY_ID_REQ) ? 1 : 0;
-            idRequests += attrs.contains(EAP_AT_FULLAUTH_ID_REQ) ? 1 : 0;
-
-            if (idRequests != 1) {
-                return false;
-            }
-
-            // can't contain mac, iv, encr data
-            if (attrs.contains(EAP_AT_MAC)
-                    || attrs.contains(EAP_AT_IV)
-                    || attrs.contains(EAP_AT_ENCR_DATA)) {
-                return false;
-            }
-            return true;
-        }
-    }
-
-    protected class ChallengeState extends EapMethodState {
-        private final String mTAG = ChallengeState.class.getSimpleName();
-
-        @VisibleForTesting boolean mHadSuccessfulChallenge = false;
-        @VisibleForTesting protected final byte[] mIdentity;
-
-        // IK and CK lengths defined as 16B (RFC 4187#1)
-        private final int mIkLenBytes = 16;
-        private final int mCkLenBytes = 16;
-
-        // Tags for Successful and Synchronization responses
-        private final byte mSuccess = (byte) 0xDB;
-        private final byte mSynchronization = (byte) 0xDC;
-
-        ChallengeState() {
-            // use the EAP-Identity for the default value (RFC 4187#7)
-            this(mEapIdentity);
-        }
-
-        ChallengeState(byte[] identity) {
-            this.mIdentity = identity;
-        }
-
-        public EapResult process(EapMessage message) {
-            if (message.eapCode == EAP_CODE_SUCCESS) {
-                if (!mHadSuccessfulChallenge) {
-                    LOG.e(mTAG, "Received unexpected EAP-Success");
-                    return new EapError(
-                            new EapInvalidRequestException(
-                                    "Received an EAP-Success in the ChallengeState"));
-                }
-                transitionTo(new FinalState());
-                return new EapSuccess(mMsk, mEmsk);
-            } else if (message.eapCode == EAP_CODE_FAILURE) {
-                transitionTo(new FinalState());
-                return new EapFailure();
-            } else if (message.eapData.eapType == EAP_NOTIFICATION) {
-                return handleEapNotification(mTAG, message);
-            }
-
-            if (message.eapData.eapType != getEapMethod()) {
-                return new EapError(new EapInvalidRequestException(
-                        "Expected EAP Type " + getEapMethod()
-                                + ", received " + message.eapData.eapType));
-            }
-
-            DecodeResult<? extends EapAkaTypeData> decodeResult =
-                    decode(message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier, getEapMethod(), decodeResult.atClientErrorCode);
-            }
-
-            EapAkaTypeData eapAkaTypeData = decodeResult.eapTypeData;
-            switch (eapAkaTypeData.eapSubtype) {
-                case EAP_AKA_CHALLENGE:
-                    break;
-                case EAP_AKA_NOTIFICATION:
-                    return handleEapSimAkaNotification(
-                            mTAG,
-                            false, // isPreChallengeState
-                            message.eapIdentifier,
-                            eapAkaTypeData);
-                default:
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            getEapMethod(),
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            if (!isValidChallengeAttributes(eapAkaTypeData)) {
-                LOG.e(mTAG, "Invalid attributes: " + eapAkaTypeData.attributeMap.keySet());
-                return buildClientErrorResponse(
-                        message.eapIdentifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            return handleChallengeAuthentication(message, eapAkaTypeData);
-        }
-
-        protected EapResult handleChallengeAuthentication(
-                EapMessage message, EapAkaTypeData eapAkaTypeData) {
-            RandChallengeResult result;
-            try {
-                result = getRandChallengeResult(eapAkaTypeData);
-            } catch (EapAkaInvalidAuthenticationResponse ex) {
-                return new EapError(ex);
-            } catch (EapSimAkaInvalidLengthException | BufferUnderflowException ex) {
-                LOG.e(mTAG, "Invalid response returned from SIM", ex);
-                return buildClientErrorResponse(
-                        message.eapIdentifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-            } catch (EapSimAkaAuthenticationFailureException ex) {
-                // Return EAP-Response/AKA-Authentication-Reject when the AUTN is rejected
-                // (RFC 4187#6.3.1)
-                return buildAuthenticationRejectMessage(message.eapIdentifier);
-            }
-
-            if (!result.isSuccessfulResult()) {
-                try {
-                    return buildResponseMessage(
-                            getEapMethod(),
-                            EAP_AKA_SYNCHRONIZATION_FAILURE,
-                            message.eapIdentifier,
-                            Arrays.asList(new AtAuts(result.auts)));
-                } catch (EapSimAkaInvalidAttributeException ex) {
-                    LOG.wtf(mTAG, "Error creating an AtAuts attr", ex);
-                    return new EapError(ex);
-                }
-            }
-
-            EapResult eapResult =
-                    generateAndPersistEapAkaKeys(result, message.eapIdentifier, eapAkaTypeData);
-            if (eapResult != null) {
-                return eapResult;
-            }
-
-            try {
-                if (!isValidMac(mTAG, message, eapAkaTypeData, new byte[0])) {
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            getEapMethod(),
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-                }
-            } catch (GeneralSecurityException
-                    | EapSilentException
-                    | EapSimAkaInvalidAttributeException ex) {
-                // if the MAC can't be generated, we can't continue
-                LOG.e(mTAG, "Error computing MAC for EapMessage", ex);
-                return new EapError(ex);
-            }
-
-            // before sending a response, check for bidding-down attacks (RFC 5448#4)
-            if (mSupportsEapAkaPrime) {
-                AtBidding atBidding = (AtBidding) eapAkaTypeData.attributeMap.get(EAP_AT_BIDDING);
-                if (atBidding != null && atBidding.doesServerSupportEapAkaPrime) {
-                    LOG.w(
-                            mTAG,
-                            "Potential bidding down attack. AT_BIDDING attr included and EAP-AKA'"
-                                + " is supported");
-                    return buildAuthenticationRejectMessage(message.eapIdentifier);
-                }
-            }
-
-            // server has been authenticated, so we can send a response
-            try {
-                mHadSuccessfulChallenge = true;
-                return buildResponseMessageWithMac(
-                        message.eapIdentifier,
-                        EAP_AKA_CHALLENGE,
-                        new byte[0],
-                        Arrays.asList(AtRes.getAtRes(result.res)));
-            } catch (EapSimAkaInvalidAttributeException ex) {
-                LOG.wtf(mTAG, "Error creating AtRes value", ex);
-                return new EapError(ex);
-            }
-        }
-
-        @VisibleForTesting
-        class RandChallengeResult {
-            public final byte[] res;
-            public final byte[] ik;
-            public final byte[] ck;
-            public final byte[] auts;
-
-            RandChallengeResult(byte[] res, byte[] ik, byte[] ck)
-                    throws EapSimAkaInvalidLengthException {
-                if (!AtRes.isValidResLen(res.length)) {
-                    throw new EapSimAkaInvalidLengthException("Invalid RES length");
-                } else if (ik.length != mIkLenBytes) {
-                    throw new EapSimAkaInvalidLengthException("Invalid IK length");
-                } else if (ck.length != mCkLenBytes) {
-                    throw new EapSimAkaInvalidLengthException("Invalid CK length");
-                }
-
-                this.res = res;
-                this.ik = ik;
-                this.ck = ck;
-                this.auts = null;
-            }
-
-            RandChallengeResult(byte[] auts) throws EapSimAkaInvalidLengthException {
-                if (auts.length != AtAuts.AUTS_LENGTH) {
-                    throw new EapSimAkaInvalidLengthException("Invalid AUTS length");
-                }
-
-                this.res = null;
-                this.ik = null;
-                this.ck = null;
-                this.auts = auts;
-            }
-
-            private boolean isSuccessfulResult() {
-                return res != null && ik != null && ck != null;
-            }
-        }
-
-        private boolean isValidChallengeAttributes(EapAkaTypeData eapAkaTypeData) {
-            Set<Integer> attrs = eapAkaTypeData.attributeMap.keySet();
-
-            // must contain: AT_RAND, AT_AUTN, AT_MAC
-            return attrs.contains(EAP_AT_RAND)
-                    && attrs.contains(EAP_AT_AUTN)
-                    && attrs.contains(EAP_AT_MAC);
-        }
-
-        private RandChallengeResult getRandChallengeResult(EapAkaTypeData eapAkaTypeData)
-                throws EapSimAkaAuthenticationFailureException, EapSimAkaInvalidLengthException {
-            AtRandAka atRandAka = (AtRandAka) eapAkaTypeData.attributeMap.get(EAP_AT_RAND);
-            AtAutn atAutn = (AtAutn) eapAkaTypeData.attributeMap.get(EAP_AT_AUTN);
-
-            // pre-Base64 formatting needs to be: [Length][RAND][Length][AUTN]
-            int randLen = atRandAka.rand.length;
-            int autnLen = atAutn.autn.length;
-            ByteBuffer formattedChallenge = ByteBuffer.allocate(1 + randLen + 1 + autnLen);
-            formattedChallenge.put((byte) randLen);
-            formattedChallenge.put(atRandAka.rand);
-            formattedChallenge.put((byte) autnLen);
-            formattedChallenge.put(atAutn.autn);
-
-            byte[] challengeResponse =
-                    processUiccAuthentication(
-                            mTAG,
-                            TelephonyManager.AUTHTYPE_EAP_AKA,
-                            formattedChallenge.array());
-            ByteBuffer buffer = ByteBuffer.wrap(challengeResponse);
-            byte tag = buffer.get();
-
-            switch (tag) {
-                case mSuccess:
-                    // response format: [tag][RES length][RES][IK length][IK][CK length][CK]
-                    break;
-                case mSynchronization:
-                    // response format: [tag][AUTS length][AUTS]
-                    byte[] auts = new byte[Byte.toUnsignedInt(buffer.get())];
-                    buffer.get(auts);
-
-                    LOG.i(mTAG, "Synchronization Failure");
-                    LOG.d(
-                            mTAG,
-                            "RAND=" + LOG.pii(atRandAka.rand)
-                                    + " AUTN=" + LOG.pii(atAutn.autn)
-                                    + " AUTS=" + LOG.pii(auts));
-
-                    return new RandChallengeResult(auts);
-                default:
-                    throw new EapAkaInvalidAuthenticationResponse(
-                            "Invalid tag for UICC response: " + String.format("%02X", tag));
-            }
-
-            byte[] res = new byte[Byte.toUnsignedInt(buffer.get())];
-            buffer.get(res);
-
-            byte[] ik = new byte[Byte.toUnsignedInt(buffer.get())];
-            buffer.get(ik);
-
-            byte[] ck = new byte[Byte.toUnsignedInt(buffer.get())];
-            buffer.get(ck);
-
-            LOG.d(
-                    mTAG,
-                    "RAND=" + LOG.pii(atRandAka.rand)
-                            + " AUTN=" + LOG.pii(atAutn.autn)
-                            + " RES=" + LOG.pii(res)
-                            + " IK=" + LOG.pii(ik)
-                            + " CK=" + LOG.pii(ck));
-
-            return new RandChallengeResult(res, ik, ck);
-        }
-
-        protected EapResult buildAuthenticationRejectMessage(int eapIdentifier) {
-            return buildResponseMessage(
-                    getEapMethod(),
-                    EAP_AKA_AUTHENTICATION_REJECT,
-                    eapIdentifier,
-                    new ArrayList<>());
-        }
-
-        @Nullable
-        protected EapResult generateAndPersistEapAkaKeys(
-                RandChallengeResult result, int eapIdentifier, EapAkaTypeData eapAkaTypeData) {
-            try {
-                MessageDigest sha1 = MessageDigest.getInstance(MASTER_KEY_GENERATION_ALG);
-                byte[] mkInputData = getMkInputData(result);
-                generateAndPersistKeys(mTAG, sha1, new Fips186_2Prf(), mkInputData);
-                return null;
-            } catch (NoSuchAlgorithmException | BufferUnderflowException ex) {
-                LOG.e(mTAG, "Error while creating keys", ex);
-                return buildClientErrorResponse(
-                        eapIdentifier, EAP_TYPE_AKA, AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-        }
-
-        private byte[] getMkInputData(RandChallengeResult result) {
-            int numInputBytes = mIdentity.length + result.ik.length + result.ck.length;
-            ByteBuffer buffer = ByteBuffer.allocate(numInputBytes);
-            buffer.put(mIdentity);
-            buffer.put(result.ik);
-            buffer.put(result.ck);
-            return buffer.array();
-        }
-    }
-
-    EapAkaTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) {
-        return new EapAkaTypeData(EAP_AKA_CLIENT_ERROR, Arrays.asList(clientErrorCode));
-    }
-
-    EapAkaTypeData getEapSimAkaTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
-        return new EapAkaTypeData(eapSubtype, attributes);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachine.java
deleted file mode 100644
index d2e8ba2..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachine.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CLIENT_ERROR;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF_INPUT;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.eap.EapSessionConfig.EapAkaPrimeConfig;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.crypto.KeyGenerationUtils;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.crypto.HmacSha256ByteSigner;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-
-import java.nio.BufferOverflowException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * EapAkaPrimeMethodStateMachine represents the valid paths possible for the EAP-AKA' protocol.
- *
- * <p>EAP-AKA' sessions will always follow the path:
- *
- * Created --+--> Identity --+--> Challenge  --> Final
- *           |               |
- *           +---------------+
- *
- * <p>Note: If the EAP-Request/AKA'-Challenge message contains an AUTN with an invalid sequence
- * number, the peer will indicate a synchronization failure to the server and a new challenge will
- * be attempted.
- *
- * <p>Note: EAP-Request/Notification messages can be received at any point in the above state
- * machine At most one EAP-AKA'/Notification message is allowed per EAP-AKA' session.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication Protocol
- *     for Authentication and Key Agreement (EAP-AKA)</a>
- * @see <a href="https://tools.ietf.org/html/rfc5448">RFC 5448, Improved Extensible Authentication
- *     Protocol Method for 3rd Generation Authentication and Key Agreement (EAP-AKA')</a>
- */
-public class EapAkaPrimeMethodStateMachine extends EapAkaMethodStateMachine {
-    public static final int K_AUT_LEN = 32;
-    public static final int K_RE_LEN = 32;
-
-    // EAP-AKA' identity prefix (RFC 5448#3)
-    private static final String AKA_PRIME_IDENTITY_PREFIX = "6";
-    private static final int SUPPORTED_KDF = 1;
-    private static final int FC = 0x20; // Required by TS 133 402 Annex A.2
-    private static final int SQN_XOR_AK_LEN = 6;
-    private static final String MAC_ALGORITHM_STRING = "HmacSHA256";
-    private static final String MK_DATA_PREFIX = "EAP-AKA'";
-
-    // MK_LEN_BYTES = len(K_encr | K_aut | K_re | MSK | EMSK)
-    private static final int MK_LEN_BYTES =
-            KEY_LEN + K_AUT_LEN + K_RE_LEN + (2 * SESSION_KEY_LENGTH);
-
-    public final byte[] mKRe = new byte[getKReLen()];
-
-    private final EapAkaPrimeConfig mEapAkaPrimeConfig;
-    private final EapAkaPrimeTypeDataDecoder mEapAkaPrimeTypeDataDecoder;
-
-    EapAkaPrimeMethodStateMachine(
-            Context context, byte[] eapIdentity, EapAkaPrimeConfig eapAkaPrimeConfig) {
-        this(
-                context,
-                eapIdentity,
-                eapAkaPrimeConfig,
-                EapAkaPrimeTypeData.getEapAkaPrimeTypeDataDecoder());
-    }
-
-    @VisibleForTesting
-    protected EapAkaPrimeMethodStateMachine(
-            Context context,
-            byte[] eapIdentity,
-            EapAkaPrimeConfig eapAkaPrimeConfig,
-            EapAkaPrimeTypeDataDecoder eapAkaPrimeTypeDataDecoder) {
-        super(context, eapIdentity, eapAkaPrimeConfig);
-        mEapAkaPrimeConfig = eapAkaPrimeConfig;
-        mEapAkaPrimeTypeDataDecoder = eapAkaPrimeTypeDataDecoder;
-
-        transitionTo(new CreatedState());
-    }
-
-    @Override
-    @EapMethod
-    int getEapMethod() {
-        return EAP_TYPE_AKA_PRIME;
-    }
-
-    @Override
-    protected int getKAutLength() {
-        return K_AUT_LEN;
-    }
-
-    protected int getKReLen() {
-        return K_RE_LEN;
-    }
-
-    @Override
-    protected DecodeResult<EapAkaTypeData> decode(byte[] typeData) {
-        return mEapAkaPrimeTypeDataDecoder.decode(typeData);
-    }
-
-    @Override
-    protected String getIdentityPrefix() {
-        return AKA_PRIME_IDENTITY_PREFIX;
-    }
-
-    @Override
-    protected ChallengeState buildChallengeState() {
-        return new ChallengeState();
-    }
-
-    @Override
-    protected ChallengeState buildChallengeState(byte[] identity) {
-        return new ChallengeState(identity);
-    }
-
-    @Override
-    protected String getMacAlgorithm() {
-        return MAC_ALGORITHM_STRING;
-    }
-
-    protected class ChallengeState extends EapAkaMethodStateMachine.ChallengeState {
-        private final String mTAG = ChallengeState.class.getSimpleName();
-
-        ChallengeState() {
-            super();
-        }
-
-        ChallengeState(byte[] identity) {
-            super(identity);
-        }
-
-        @Override
-        protected EapResult handleChallengeAuthentication(
-                EapMessage message, EapAkaTypeData eapAkaTypeData) {
-            EapAkaPrimeTypeData eapAkaPrimeTypeData = (EapAkaPrimeTypeData) eapAkaTypeData;
-
-            if (!isValidChallengeAttributes(eapAkaPrimeTypeData)) {
-                return buildAuthenticationRejectMessage(message.eapIdentifier);
-            }
-            return super.handleChallengeAuthentication(message, eapAkaPrimeTypeData);
-        }
-
-        @VisibleForTesting
-        boolean isValidChallengeAttributes(EapAkaPrimeTypeData eapAkaPrimeTypeData) {
-            Map<Integer, EapSimAkaAttribute> attrs = eapAkaPrimeTypeData.attributeMap;
-
-            if (!attrs.containsKey(EAP_AT_KDF) || !attrs.containsKey(EAP_AT_KDF_INPUT)) {
-                return false;
-            }
-
-            // TODO(b/143073851): implement KDF resolution specified in RFC 5448#3.2
-            // This is safe, as there only exists one defined KDF.
-            AtKdf atKdf = (AtKdf) attrs.get(EAP_AT_KDF);
-            if (atKdf.kdf != SUPPORTED_KDF) {
-                return false;
-            }
-
-            AtKdfInput atKdfInput = (AtKdfInput) attrs.get(EAP_AT_KDF_INPUT);
-            if (atKdfInput.networkName.length == 0) {
-                return false;
-            }
-
-            boolean hasMatchingNetworkNames =
-                    hasMatchingNetworkNames(
-                            mEapAkaPrimeConfig.networkName,
-                            new String(atKdfInput.networkName, StandardCharsets.UTF_8));
-            return mEapAkaPrimeConfig.allowMismatchedNetworkNames || hasMatchingNetworkNames;
-        }
-
-        /**
-         * Compares the peer's network name against the server's network name.
-         *
-         * <p>RFC 5448#3.1 describes how the network names are to be compared: "each name is broken
-         * down to the fields separated by colons. If one of the names has more colons and fields
-         * than the other one, the additional fields are ignored. The remaining sequences of fields
-         * are compared. This algorithm allows a prefix match".
-         *
-         * @return true iff one network name matches the other, as defined by RC 5448#3.1
-         */
-        @VisibleForTesting
-        boolean hasMatchingNetworkNames(String peerNetworkName, String serverNetworkName) {
-            // compare network names according to RFC 5448#3.1
-            if (peerNetworkName.isEmpty() || serverNetworkName.isEmpty()) {
-                return true;
-            }
-
-            String[] peerNetworkNameFields = peerNetworkName.split(":");
-            String[] serverNetworkNameFields = serverNetworkName.split(":");
-            int numFieldsToCompare =
-                    Math.min(peerNetworkNameFields.length, serverNetworkNameFields.length);
-            for (int i = 0; i < numFieldsToCompare; i++) {
-                if (!peerNetworkNameFields[i].equals(serverNetworkNameFields[i])) {
-                    LOG.i(
-                            mTAG,
-                            "EAP-AKA' network names don't match."
-                                    + " Peer: " + LOG.pii(peerNetworkName)
-                                    + ", Server: " + LOG.pii(serverNetworkName));
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        @Nullable
-        @Override
-        protected EapResult generateAndPersistEapAkaKeys(
-                RandChallengeResult result, int eapIdentifier, EapAkaTypeData eapAkaTypeData) {
-            try {
-                AtKdfInput atKdfInput =
-                        (AtKdfInput) eapAkaTypeData.attributeMap.get(EAP_AT_KDF_INPUT);
-                AtAutn atAutn = (AtAutn) eapAkaTypeData.attributeMap.get(EAP_AT_AUTN);
-                byte[] ckIkPrime = deriveCkIkPrime(result, atKdfInput, atAutn);
-
-                int dataToSignLen = MK_DATA_PREFIX.length() + mIdentity.length;
-                ByteBuffer dataToSign = ByteBuffer.allocate(dataToSignLen);
-                dataToSign.put(MK_DATA_PREFIX.getBytes(StandardCharsets.US_ASCII));
-                dataToSign.put(mIdentity);
-
-                ByteBuffer mk =
-                        ByteBuffer.wrap(
-                                KeyGenerationUtils.prfPlus(
-                                        HmacSha256ByteSigner.getInstance(),
-                                        ckIkPrime,
-                                        dataToSign.array(),
-                                        MK_LEN_BYTES));
-
-                mk.get(mKEncr);
-                mk.get(mKAut);
-                mk.get(mKRe);
-                mk.get(mMsk);
-                mk.get(mEmsk);
-
-                // Log as hash unless PII debug mode enabled
-                LOG.d(mTAG, "K_encr=" + LOG.pii(mKEncr));
-                LOG.d(mTAG, "K_aut=" + LOG.pii(mKAut));
-                LOG.d(mTAG, "K_re=" + LOG.pii(mKRe));
-                LOG.d(mTAG, "MSK=" + LOG.pii(mMsk));
-                LOG.d(mTAG, "EMSK=" + LOG.pii(mEmsk));
-                return null;
-            } catch (GeneralSecurityException
-                    | BufferOverflowException
-                    | BufferUnderflowException ex) {
-                LOG.e(mTAG, "Error while generating keys", ex);
-                return buildClientErrorResponse(
-                        eapIdentifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-        }
-
-        /**
-         * Derives CK' and IK' values from CK and IK
-         *
-         * <p>CK' and IK' generation is specified in TS 133 402 Annex A.2, which relies on the key
-         * derivation function KDF specified in TS 133 220 Annex B.2.
-         */
-        @VisibleForTesting
-        byte[] deriveCkIkPrime(
-                RandChallengeResult randChallengeResult, AtKdfInput atKdfInput, AtAutn atAutn)
-                throws GeneralSecurityException {
-            final int fcLen = 1;
-            int lengthFieldLen = 2;
-
-            // SQN ^ AK is the first 6B of the AUTN value
-            byte[] sqnXorAk = Arrays.copyOf(atAutn.autn, SQN_XOR_AK_LEN);
-            int sLength =
-                    fcLen
-                            + atKdfInput.networkName.length + lengthFieldLen
-                            + SQN_XOR_AK_LEN + lengthFieldLen;
-
-            ByteBuffer dataToSign = ByteBuffer.allocate(sLength);
-            dataToSign.put((byte) FC);
-            dataToSign.put(atKdfInput.networkName);
-            dataToSign.putShort((short) atKdfInput.networkName.length);
-            dataToSign.put(sqnXorAk);
-            dataToSign.putShort((short) SQN_XOR_AK_LEN);
-
-            int keyLen = randChallengeResult.ck.length + randChallengeResult.ik.length;
-            ByteBuffer key = ByteBuffer.allocate(keyLen);
-            key.put(randChallengeResult.ck);
-            key.put(randChallengeResult.ik);
-
-            Mac mac = Mac.getInstance(MAC_ALGORITHM_STRING);
-            mac.init(new SecretKeySpec(key.array(), MAC_ALGORITHM_STRING));
-            return mac.doFinal(dataToSign.array());
-        }
-    }
-
-    EapAkaPrimeTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) {
-        return new EapAkaPrimeTypeData(EAP_AKA_CLIENT_ERROR, Arrays.asList(clientErrorCode));
-    }
-
-    EapAkaPrimeTypeData getEapSimAkaTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
-        return new EapAkaPrimeTypeData(eapSubtype, attributes);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapMethodStateMachine.java
deleted file mode 100644
index bab182b..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapMethodStateMachine.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-
-import android.annotation.Nullable;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.utils.SimpleStateMachine;
-
-/**
- * EapMethodStateMachine is an abstract class representing a state machine for EAP Method
- * implementations.
- */
-public abstract class EapMethodStateMachine extends SimpleStateMachine<EapMessage, EapResult> {
-    /**
-     * Returns the EAP Method type for this EapMethodStateMachine implementation.
-     *
-     * @return the IANA value for the EAP Method represented by this EapMethodStateMachine
-     */
-    @EapMethod
-    abstract int getEapMethod();
-
-    @VisibleForTesting
-    protected SimpleState getState() {
-        return mState;
-    }
-
-    @VisibleForTesting
-    protected void transitionTo(EapMethodState newState) {
-        LOG.d(
-                this.getClass().getSimpleName(),
-                "Transitioning from " + mState.getClass().getSimpleName()
-                        + " to " + newState.getClass().getSimpleName());
-        super.transitionTo(newState);
-    }
-
-    abstract EapResult handleEapNotification(String tag, EapMessage message);
-
-    protected abstract class EapMethodState extends SimpleState {
-        /**
-         * Handles premature EAP-Success and EAP-Failure messages, as well as EAP-Notification
-         * messages.
-         *
-         * @param tag the String logging tag to be used while handing message
-         * @param message the EapMessage to be checked for early Success/Failure/Notification
-         *                messages
-         * @return the EapResult generated from handling the give EapMessage, or null if the message
-         * Type matches that of the current EAP method
-         */
-        @Nullable
-        EapResult handleEapSuccessFailureNotification(String tag, EapMessage message) {
-            if (message.eapCode == EAP_CODE_SUCCESS) {
-                // EAP-SUCCESS is required to be the last EAP message sent during the EAP protocol,
-                // so receiving a premature SUCCESS message is an unrecoverable error.
-                return new EapError(
-                        new EapInvalidRequestException(
-                                "Received an EAP-Success in the " + tag));
-            } else if (message.eapCode == EAP_CODE_FAILURE) {
-                transitionTo(new EapAkaMethodStateMachine.FinalState());
-                return new EapFailure();
-            } else if (message.eapData.eapType == EAP_NOTIFICATION) {
-                return handleEapNotification(tag, message);
-            } else if (message.eapData.eapType != getEapMethod()) {
-                return new EapError(new EapInvalidRequestException(
-                        "Expected EAP Type " + getEapMethod()
-                                + ", received " + message.eapData.eapType));
-            }
-
-            return null;
-        }
-    }
-
-    protected class FinalState extends EapMethodState {
-        @Override
-        public EapResult process(EapMessage msg) {
-            return new EapError(
-                    new IllegalStateException("Attempting to process from a FinalState"));
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachine.java
deleted file mode 100644
index 490b8ba..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachine.java
+++ /dev/null
@@ -1,673 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_STRING;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_RESPONSE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_OP_CODE_STRING;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureRequest.EAP_ERROR_CODE_STRING;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureResponse.getEapMsChapV2FailureResponse;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessResponse.getEapMsChapV2SuccessResponse;
-
-import android.net.eap.EapSessionConfig.EapMsChapV2Config;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.crypto.ParityBitUtil;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeResponse;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-import com.android.internal.net.utils.Log;
-import com.android.org.bouncycastle.crypto.digests.MD4Digest;
-
-import java.io.UnsupportedEncodingException;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.SecretKeyFactory;
-import javax.crypto.spec.DESKeySpec;
-
-/**
- * EapMsChapV2MethodStateMachine represents the valid paths possible for the EAP MSCHAPv2 protocol.
- *
- * <p>EAP MSCHAPv2 sessions will always follow the path:
- *
- * <p>CreatedState
- *      |
- *      +--> ChallengeState
- *             |
- *             +--> ValidateAuthenticatorState --+--> AwaitingEapSuccessState --> FinalState
- *                                               |
- *                                               +--> AwaitingEapFailureState --> FinalState
- *
- * <p>Note: All Failure-Request messages received in the PostChallenge state will be responded to
- * with Failure-Response messages. That is, retryable failures <i>will not</i> be retried.
- *
- * <p>Note: The EAP standard states that EAP methods may disallow EAP Notification messages for the
- * duration of the method (RFC 3748#5.2). EAP MSCHAPv2 does not explicitly ban these packets, so
- * they are allowed at any time (except once a terminal state is reached).
- *
- * @see <a href="https://tools.ietf.org/html/draft-kamath-pppext-eap-mschapv2-02">Microsoft EAP CHAP
- *     Extensions Draft (EAP MSCHAPv2)</a>
- * @see <a href="https://tools.ietf.org/html/rfc2759">RFC 2759, Microsoft PPP CHAP Extensions,
- *     Version 2 (MSCHAPv2)</a>
- * @see <a href="https://tools.ietf.org/html/rfc3079">RFC 3079, Deriving Keys for use with Microsoft
- *     Point-to-Point Encryption (MPPE)</a>
- */
-public class EapMsChapV2MethodStateMachine extends EapMethodStateMachine {
-    private static final String SHA_ALG = "SHA-1";
-    private static final String DES_ALG = "DES/ECB/NoPadding";
-    private static final String DES_KEY_FACTORY = "DES";
-    private static final int PEER_CHALLENGE_SIZE = 16;
-    private static final int CHALLENGE_HASH_LEN = 8;
-    private static final int PASSWORD_HASH_LEN = 16;
-    private static final int PASSWORD_HASH_HASH_LEN = 16;
-    private static final int RESPONSE_LEN = 24;
-    private static final int Z_PASSWORD_HASH_LEN = 21;
-    private static final int Z_PASSWORD_SECTION_LEN = 7;
-    private static final int RESPONSE_SECTION_LEN = 8;
-    private static final int SHS_PAD_LEN = 40;
-    private static final int MASTER_KEY_LEN = 16;
-    private static final int SESSION_KEY_LEN = 16;
-    private static final int MASTER_SESSION_KEY_LEN = 2 * SESSION_KEY_LEN;
-
-    // Reserved for future use and must be 0 (EAP MSCHAPv2#2.2)
-    private static final int FLAGS = 0;
-
-    // we all need a little magic in our lives
-    // Defined in RFC 2759#8.7. Constants used for Success response generation.
-    private static final byte[] CHALLENGE_MAGIC_1 = {
-        (byte) 0x4D, (byte) 0x61, (byte) 0x67, (byte) 0x69, (byte) 0x63, (byte) 0x20, (byte) 0x73,
-        (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65, (byte) 0x72, (byte) 0x20, (byte) 0x74,
-        (byte) 0x6F, (byte) 0x20, (byte) 0x63, (byte) 0x6C, (byte) 0x69, (byte) 0x65, (byte) 0x6E,
-        (byte) 0x74, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x67, (byte) 0x6E, (byte) 0x69,
-        (byte) 0x6E, (byte) 0x67, (byte) 0x20, (byte) 0x63, (byte) 0x6F, (byte) 0x6E, (byte) 0x73,
-        (byte) 0x74, (byte) 0x61, (byte) 0x6E, (byte) 0x74
-    };
-    private static final byte[] CHALLENGE_MAGIC_2 = {
-        (byte) 0x50, (byte) 0x61, (byte) 0x64, (byte) 0x20, (byte) 0x74, (byte) 0x6F, (byte) 0x20,
-        (byte) 0x6D, (byte) 0x61, (byte) 0x6B, (byte) 0x65, (byte) 0x20, (byte) 0x69, (byte) 0x74,
-        (byte) 0x20, (byte) 0x64, (byte) 0x6F, (byte) 0x20, (byte) 0x6D, (byte) 0x6F, (byte) 0x72,
-        (byte) 0x65, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x61, (byte) 0x6E, (byte) 0x20,
-        (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x20, (byte) 0x69, (byte) 0x74, (byte) 0x65,
-        (byte) 0x72, (byte) 0x61, (byte) 0x74, (byte) 0x69, (byte) 0x6F, (byte) 0x6E
-    };
-
-    // Defined in RFC 3079#3.4. Constants used for Master Session Key (MSK) generation
-    private static final byte[] SHS_PAD_1 = new byte[SHS_PAD_LEN];
-    private static final byte[] SHS_PAD_2 = new byte[SHS_PAD_LEN];
-
-    static {
-        Arrays.fill(SHS_PAD_2, (byte) 0xF2);
-    }
-
-    private static final byte[] MSK_MAGIC_1 = {
-        (byte) 0x54, (byte) 0x68, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x69,
-        (byte) 0x73, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x20,
-        (byte) 0x4D, (byte) 0x50, (byte) 0x50, (byte) 0x45, (byte) 0x20, (byte) 0x4D,
-        (byte) 0x61, (byte) 0x73, (byte) 0x74, (byte) 0x65, (byte) 0x72, (byte) 0x20,
-        (byte) 0x4B, (byte) 0x65, (byte) 0x79
-    };
-    private static final byte[] MSK_MAGIC_2 = {
-        (byte) 0x4F, (byte) 0x6E, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x65,
-        (byte) 0x20, (byte) 0x63, (byte) 0x6C, (byte) 0x69, (byte) 0x65, (byte) 0x6E,
-        (byte) 0x74, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x64, (byte) 0x65,
-        (byte) 0x2C, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x69, (byte) 0x73,
-        (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x74, (byte) 0x68,
-        (byte) 0x65, (byte) 0x20, (byte) 0x73, (byte) 0x65, (byte) 0x6E, (byte) 0x64,
-        (byte) 0x20, (byte) 0x6B, (byte) 0x65, (byte) 0x79, (byte) 0x3B, (byte) 0x20,
-        (byte) 0x6F, (byte) 0x6E, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x65,
-        (byte) 0x20, (byte) 0x73, (byte) 0x65, (byte) 0x72, (byte) 0x76, (byte) 0x65,
-        (byte) 0x72, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x64, (byte) 0x65,
-        (byte) 0x2C, (byte) 0x20, (byte) 0x69, (byte) 0x74, (byte) 0x20, (byte) 0x69,
-        (byte) 0x73, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x20,
-        (byte) 0x72, (byte) 0x65, (byte) 0x63, (byte) 0x65, (byte) 0x69, (byte) 0x76,
-        (byte) 0x65, (byte) 0x20, (byte) 0x6B, (byte) 0x65, (byte) 0x79, (byte) 0x2E
-    };
-    private static final byte[] MSK_MAGIC_3 = {
-        (byte) 0x4F, (byte) 0x6E, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x65,
-        (byte) 0x20, (byte) 0x63, (byte) 0x6C, (byte) 0x69, (byte) 0x65, (byte) 0x6E,
-        (byte) 0x74, (byte) 0x20, (byte) 0x73, (byte) 0x69, (byte) 0x64, (byte) 0x65,
-        (byte) 0x2C, (byte) 0x20, (byte) 0x74, (byte) 0x68, (byte) 0x69, (byte) 0x73,
-        (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x74, (byte) 0x68,
-        (byte) 0x65, (byte) 0x20, (byte) 0x72, (byte) 0x65, (byte) 0x63, (byte) 0x65,
-        (byte) 0x69, (byte) 0x76, (byte) 0x65, (byte) 0x20, (byte) 0x6B, (byte) 0x65,
-        (byte) 0x79, (byte) 0x3B, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x20,
-        (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x20, (byte) 0x73, (byte) 0x65,
-        (byte) 0x72, (byte) 0x76, (byte) 0x65, (byte) 0x72, (byte) 0x20, (byte) 0x73,
-        (byte) 0x69, (byte) 0x64, (byte) 0x65, (byte) 0x2C, (byte) 0x20, (byte) 0x69,
-        (byte) 0x74, (byte) 0x20, (byte) 0x69, (byte) 0x73, (byte) 0x20, (byte) 0x74,
-        (byte) 0x68, (byte) 0x65, (byte) 0x20, (byte) 0x73, (byte) 0x65, (byte) 0x6E,
-        (byte) 0x64, (byte) 0x20, (byte) 0x6B, (byte) 0x65, (byte) 0x79, (byte) 0x2E
-    };
-
-    private final EapMsChapV2Config mEapMsChapV2Config;
-    private final SecureRandom mSecureRandom;
-    private final EapMsChapV2TypeDataDecoder mTypeDataDecoder;
-
-    public EapMsChapV2MethodStateMachine(
-            EapMsChapV2Config eapMsChapV2Config, SecureRandom secureRandom) {
-        this(eapMsChapV2Config, secureRandom, new EapMsChapV2TypeDataDecoder());
-    }
-
-    @VisibleForTesting
-    EapMsChapV2MethodStateMachine(
-            EapMsChapV2Config eapMsChapV2Config,
-            SecureRandom secureRandom,
-            EapMsChapV2TypeDataDecoder eapMsChapV2TypeDataDecoder) {
-        this.mEapMsChapV2Config = eapMsChapV2Config;
-        this.mSecureRandom = secureRandom;
-        this.mTypeDataDecoder = eapMsChapV2TypeDataDecoder;
-
-        transitionTo(new CreatedState());
-    }
-
-    @Override
-    @EapMethod
-    int getEapMethod() {
-        return EAP_TYPE_MSCHAP_V2;
-    }
-
-    @Override
-    EapResult handleEapNotification(String tag, EapMessage message) {
-        return EapStateMachine.handleNotification(tag, message);
-    }
-
-    protected class CreatedState extends EapMethodState {
-        private final String mTAG = this.getClass().getSimpleName();
-
-        @Override
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            DecodeResult<EapMsChapV2ChallengeRequest> decodeResult =
-                    mTypeDataDecoder.decodeChallengeRequest(mTAG, message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return decodeResult.eapError;
-            }
-
-            return transitionAndProcess(new ChallengeState(), message);
-        }
-    }
-
-    protected class ChallengeState extends EapMethodState {
-        private final String mTAG = this.getClass().getSimpleName();
-
-        @Override
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            DecodeResult<EapMsChapV2ChallengeRequest> decodeResult =
-                    mTypeDataDecoder.decodeChallengeRequest(mTAG, message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return decodeResult.eapError;
-            }
-
-            EapMsChapV2ChallengeRequest challengeRequest = decodeResult.eapTypeData;
-            LOG.d(
-                    mTAG,
-                    "Received Challenge Request:"
-                            + " Challenge=" + LOG.pii(challengeRequest.challenge)
-                            + " Server-Name=" + Log.byteArrayToHexString(challengeRequest.name));
-
-            byte[] peerChallenge = new byte[PEER_CHALLENGE_SIZE];
-            mSecureRandom.nextBytes(peerChallenge);
-
-            byte[] ntResponse;
-            try {
-                ntResponse =
-                        generateNtResponse(
-                                challengeRequest.challenge,
-                                peerChallenge,
-                                mEapMsChapV2Config.username,
-                                mEapMsChapV2Config.password);
-            } catch (GeneralSecurityException ex) {
-                LOG.e(mTAG, "Error generating EAP MSCHAPv2 Challenge response", ex);
-                return new EapError(ex);
-            }
-
-            LOG.d(
-                    mTAG,
-                    "Generating Challenge Response:"
-                            + " Username=" + LOG.pii(mEapMsChapV2Config.username)
-                            + " Peer-Challenge=" + LOG.pii(peerChallenge)
-                            + " NT-Response=" + LOG.pii(ntResponse));
-
-            try {
-                EapMsChapV2ChallengeResponse challengeResponse =
-                        new EapMsChapV2ChallengeResponse(
-                                challengeRequest.msChapV2Id,
-                                peerChallenge,
-                                ntResponse,
-                                FLAGS,
-                                usernameToBytes(mEapMsChapV2Config.username));
-                transitionTo(
-                        new ValidateAuthenticatorState(
-                                challengeRequest.challenge, peerChallenge, ntResponse));
-
-                return buildEapMessageResponse(mTAG, message.eapIdentifier, challengeResponse);
-            } catch (EapMsChapV2ParsingException ex) {
-                LOG.e(mTAG, "Error building response type data", ex);
-                return new EapError(ex);
-            }
-        }
-    }
-
-    protected class ValidateAuthenticatorState extends EapMethodState {
-        private final String mTAG = this.getClass().getSimpleName();
-
-        private final byte[] mAuthenticatorChallenge;
-        private final byte[] mPeerChallenge;
-        private final byte[] mNtResponse;
-
-        @VisibleForTesting
-        ValidateAuthenticatorState(
-                byte[] authenticatorChallenge, byte[] peerChallenge, byte[] ntResponse) {
-            this.mAuthenticatorChallenge = authenticatorChallenge;
-            this.mPeerChallenge = peerChallenge;
-            this.mNtResponse = ntResponse;
-        }
-
-        @Override
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            int opCode;
-            try {
-                opCode = mTypeDataDecoder.getOpCode(message.eapData.eapTypeData);
-            } catch (BufferUnderflowException ex) {
-                LOG.e(mTAG, "Empty type data received in ValidateAuthenticatorState", ex);
-                return new EapError(ex);
-            }
-
-            LOG.d(
-                    mTAG,
-                    "Received Op Code: "
-                            + EAP_OP_CODE_STRING.getOrDefault(opCode, "Unknown")
-                            + " (" + opCode + ")");
-
-            switch (opCode) {
-                case EAP_MSCHAP_V2_SUCCESS:
-                    DecodeResult<EapMsChapV2SuccessRequest> successDecodeResult =
-                            mTypeDataDecoder.decodeSuccessRequest(
-                                    mTAG, message.eapData.eapTypeData);
-                    if (!successDecodeResult.isSuccessfulDecode()) {
-                        return successDecodeResult.eapError;
-                    }
-
-                    EapMsChapV2SuccessRequest successRequest = successDecodeResult.eapTypeData;
-                    LOG.d(
-                            mTAG,
-                            "Received SuccessRequest:"
-                                    + " Auth-String=" + LOG.pii(successRequest.authBytes)
-                                    + " Message=" + successRequest.message);
-
-                    boolean isSuccessfulAuth;
-                    try {
-                        isSuccessfulAuth =
-                                checkAuthenticatorResponse(
-                                        mEapMsChapV2Config.password,
-                                        mNtResponse,
-                                        mPeerChallenge,
-                                        mAuthenticatorChallenge,
-                                        mEapMsChapV2Config.username,
-                                        successRequest.authBytes);
-                    } catch (GeneralSecurityException | UnsupportedEncodingException ex) {
-                        LOG.e(mTAG, "Error validating MSCHAPv2 Authenticator Response", ex);
-                        return new EapError(ex);
-                    }
-
-                    if (!isSuccessfulAuth) {
-                        LOG.e(
-                                mTAG,
-                                "Authenticator Response does not match expected response value");
-                        transitionTo(new FinalState());
-                        return new EapFailure();
-                    }
-
-                    transitionTo(new AwaitingEapSuccessState(mNtResponse));
-                    return buildEapMessageResponse(
-                            mTAG, message.eapIdentifier, getEapMsChapV2SuccessResponse());
-
-                case EAP_MSCHAP_V2_FAILURE:
-                    DecodeResult<EapMsChapV2FailureRequest> failureDecodeResult =
-                            mTypeDataDecoder.decodeFailureRequest(
-                                    mTAG, message.eapData.eapTypeData);
-                    if (!failureDecodeResult.isSuccessfulDecode()) {
-                        return failureDecodeResult.eapError;
-                    }
-
-                    EapMsChapV2FailureRequest failureRequest = failureDecodeResult.eapTypeData;
-                    int errorCode = failureRequest.errorCode;
-                    LOG.e(
-                            mTAG,
-                            String.format(
-                                    "Received MSCHAPv2 Failure-Request: E=%s (%d) R=%b V=%d M=%s",
-                                    EAP_ERROR_CODE_STRING.getOrDefault(errorCode, "UNKNOWN"),
-                                    errorCode,
-                                    failureRequest.isRetryable,
-                                    failureRequest.passwordChangeProtocol,
-                                    failureRequest.message));
-                    transitionTo(new AwaitingEapFailureState());
-                    return buildEapMessageResponse(
-                            mTAG, message.eapIdentifier, getEapMsChapV2FailureResponse());
-
-                default:
-                    LOG.e(mTAG, "Invalid OpCode: " + opCode);
-                    return new EapError(
-                            new EapInvalidRequestException(
-                                    "Unexpected request received in EAP MSCHAPv2"));
-            }
-        }
-    }
-
-    protected class AwaitingEapSuccessState extends EapMethodState {
-        private final String mTAG = this.getClass().getSimpleName();
-
-        private final byte[] mNtResponse;
-
-        AwaitingEapSuccessState(byte[] ntResponse) {
-            this.mNtResponse = ntResponse;
-        }
-
-        @Override
-        public EapResult process(EapMessage message) {
-            if (message.eapCode == EAP_CODE_FAILURE) {
-                LOG.e(mTAG, "Received EAP-Failure in PreSuccessState");
-                transitionTo(new FinalState());
-                return new EapFailure();
-            } else if (message.eapCode != EAP_CODE_SUCCESS) {
-                int eapType = message.eapData.eapType;
-                if (eapType == EAP_NOTIFICATION) {
-                    return handleEapNotification(mTAG, message);
-                } else {
-                    LOG.e(
-                            mTAG,
-                            "Received unexpected EAP message. Type="
-                                    + EAP_TYPE_STRING.getOrDefault(
-                                            eapType, "UNKNOWN (" + eapType + ")"));
-                    return new EapError(
-                            new EapInvalidRequestException(
-                                    "Expected EAP Type "
-                                            + getEapMethod()
-                                            + ", received "
-                                            + eapType));
-                }
-            }
-
-            try {
-                byte[] msk = generateMsk(mEapMsChapV2Config.password, mNtResponse);
-                transitionTo(new FinalState());
-                return new EapSuccess(msk, new byte[0]);
-            } catch (GeneralSecurityException | UnsupportedEncodingException ex) {
-                LOG.e(mTAG, "Error generating MSK for EAP MSCHAPv2", ex);
-                return new EapError(ex);
-            }
-        }
-    }
-
-    protected class AwaitingEapFailureState extends EapMethodState {
-        private final String mTAG = this.getClass().getSimpleName();
-
-        @Override
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-            int eapType = message.eapData.eapType;
-            LOG.e(
-                    mTAG,
-                    "Received unexpected EAP message. Type="
-                            + EAP_TYPE_STRING.getOrDefault(eapType, "UNKNOWN (" + eapType + ")"));
-            return new EapError(
-                    new EapInvalidRequestException(
-                            "Expected EAP Type " + getEapMethod() + ", received " + eapType));
-        }
-    }
-
-    private EapResult buildEapMessageResponse(
-            String tag, int eapIdentifier, EapMsChapV2TypeData typeData) {
-        try {
-            EapData eapData = new EapData(getEapMethod(), typeData.encode());
-            EapMessage eapMessage = new EapMessage(EAP_CODE_RESPONSE, eapIdentifier, eapData);
-            return EapResponse.getEapResponse(eapMessage);
-        } catch (EapSilentException ex) {
-            LOG.e(tag, "Error building response EapMessage", ex);
-            return new EapError(ex);
-        }
-    }
-
-    /** Util for converting String username to "0-to-256 char username", as used in RFC 2759#8. */
-    @VisibleForTesting
-    static byte[] usernameToBytes(String username) {
-        return username.getBytes(StandardCharsets.US_ASCII);
-    }
-
-    /**
-     * Util for converting String password to "0-to-256-unicode-char password", as used in
-     * RFC 2759#8.
-     */
-    @VisibleForTesting
-    static byte[] passwordToBytes(String password) {
-        return password.getBytes(StandardCharsets.UTF_16LE);
-    }
-
-    /* Implementation of RFC 2759#8.1: GenerateNTResponse() */
-    @VisibleForTesting
-    static byte[] generateNtResponse(
-            byte[] authenticatorChallenge, byte[] peerChallenge, String username, String password)
-            throws GeneralSecurityException {
-        byte[] challenge = challengeHash(peerChallenge, authenticatorChallenge, username);
-        byte[] passwordHash = ntPasswordHash(password);
-        return challengeResponse(challenge, passwordHash);
-    }
-
-    /* Implementation of RFC 2759#8.2: ChallengeHash() */
-    @VisibleForTesting
-    static byte[] challengeHash(
-            byte[] peerChallenge, byte[] authenticatorChallenge, String username)
-            throws GeneralSecurityException {
-        MessageDigest sha1 = MessageDigest.getInstance(SHA_ALG);
-        sha1.update(peerChallenge);
-        sha1.update(authenticatorChallenge);
-        sha1.update(usernameToBytes(username));
-        return Arrays.copyOf(sha1.digest(), CHALLENGE_HASH_LEN);
-    }
-
-    /* Implementation of RFC 2759#8.3: NtPasswordHash() */
-    @VisibleForTesting
-    static byte[] ntPasswordHash(String password) {
-        MD4Digest md4 = new MD4Digest();
-        byte[] passwordBytes = passwordToBytes(password);
-        md4.update(passwordBytes, 0, passwordBytes.length);
-
-        byte[] passwordHash = new byte[PASSWORD_HASH_LEN];
-        md4.doFinal(passwordHash, 0);
-        return passwordHash;
-    }
-
-    /* Implementation of RFC 2759#8.4: HashNtPasswordHash() */
-    @VisibleForTesting
-    static byte[] hashNtPasswordHash(byte[] passwordHash) {
-        MD4Digest md4 = new MD4Digest();
-        md4.update(passwordHash, 0, passwordHash.length);
-
-        byte[] passwordHashHash = new byte[PASSWORD_HASH_HASH_LEN];
-        md4.doFinal(passwordHashHash, 0);
-        return passwordHashHash;
-    }
-
-    /* Implementation of RFC 2759#8.5: ChallengeResponse() */
-    @VisibleForTesting
-    static byte[] challengeResponse(byte[] challenge, byte[] passwordHash)
-            throws GeneralSecurityException {
-        byte[] zPasswordHash = Arrays.copyOf(passwordHash, Z_PASSWORD_HASH_LEN);
-
-        ByteBuffer response = ByteBuffer.allocate(RESPONSE_LEN);
-        for (int i = 0; i < 3; i++) {
-            int from = i * Z_PASSWORD_SECTION_LEN;
-            int to = from + Z_PASSWORD_SECTION_LEN;
-            byte[] zPasswordSection = Arrays.copyOfRange(zPasswordHash, from, to);
-            response.put(desEncrypt(challenge, zPasswordSection));
-        }
-        return response.array();
-    }
-
-    /* Implementation of RFC 2759#8.6: DesEncrypt() */
-    @VisibleForTesting
-    static byte[] desEncrypt(byte[] clear, byte[] key) throws GeneralSecurityException {
-        if (key.length != Z_PASSWORD_SECTION_LEN) {
-            throw new IllegalArgumentException("DES Key must be 7B before parity-bits are added");
-        }
-
-        key = ParityBitUtil.addParityBits(key);
-        SecretKey secretKey =
-                SecretKeyFactory.getInstance(DES_KEY_FACTORY).generateSecret(new DESKeySpec(key));
-
-        Cipher des = Cipher.getInstance(DES_ALG);
-        des.init(Cipher.ENCRYPT_MODE, secretKey);
-        byte[] output = des.doFinal(clear);
-
-        // RFC 2759#8.6 specifies 8B outputs for DesEncrypt()
-        return Arrays.copyOf(output, RESPONSE_SECTION_LEN);
-    }
-
-    /**
-     * Implementation of RFC 2759#8.7: GenerateAuthenticatorResponse()
-     *
-     * <p>Keep response as byte[] so checkAuthenticatorResponse() can easily compare byte[]'s
-     */
-    @VisibleForTesting
-    static byte[] generateAuthenticatorResponse(
-            String password,
-            byte[] ntResponse,
-            byte[] peerChallenge,
-            byte[] authenticatorChallenge,
-            String username)
-            throws GeneralSecurityException, UnsupportedEncodingException {
-        byte[] passwordHash = ntPasswordHash(password);
-        byte[] passwordHashHash = hashNtPasswordHash(passwordHash);
-
-        MessageDigest sha1 = MessageDigest.getInstance(SHA_ALG);
-        sha1.update(passwordHashHash);
-        sha1.update(ntResponse);
-        sha1.update(CHALLENGE_MAGIC_1); // add just a dash of magic
-        byte[] digest = sha1.digest();
-
-        byte[] challenge = challengeHash(peerChallenge, authenticatorChallenge, username);
-
-        sha1.update(digest);
-        sha1.update(challenge);
-        sha1.update(CHALLENGE_MAGIC_2);
-
-        return sha1.digest();
-    }
-
-    /* Implementation of RFC 2759#8.8: CheckAuthenticatorResponse() */
-    @VisibleForTesting
-    static boolean checkAuthenticatorResponse(
-            String password,
-            byte[] ntResponse,
-            byte[] peerChallenge,
-            byte[] authenticatorChallenge,
-            String userName,
-            byte[] receivedResponse)
-            throws GeneralSecurityException, UnsupportedEncodingException {
-        byte[] myResponse =
-                generateAuthenticatorResponse(
-                        password, ntResponse, peerChallenge, authenticatorChallenge, userName);
-        return Arrays.equals(myResponse, receivedResponse);
-    }
-
-    /* Implementation of RFC 3079#3.4: GetMasterKey() */
-    @VisibleForTesting
-    static byte[] getMasterKey(byte[] passwordHashHash, byte[] ntResponse)
-            throws GeneralSecurityException {
-        MessageDigest sha1 = MessageDigest.getInstance(SHA_ALG);
-        sha1.update(passwordHashHash);
-        sha1.update(ntResponse);
-        sha1.update(MSK_MAGIC_1);
-        return Arrays.copyOf(sha1.digest(), MASTER_KEY_LEN);
-    }
-
-    /* Implementation of RFC 3079#3.4: GetAsymmetricStartKey() */
-    @VisibleForTesting
-    static byte[] getAsymmetricStartKey(byte[] masterKey, boolean isSend)
-            throws GeneralSecurityException {
-        // salt: referred to as 's' in RFC 3079#3.4 GetAsymmetricStartKey()
-        byte[] salt = isSend ? MSK_MAGIC_2 : MSK_MAGIC_3;
-        MessageDigest sha1 = MessageDigest.getInstance(SHA_ALG);
-        sha1.update(masterKey);
-        sha1.update(SHS_PAD_1);
-        sha1.update(salt);
-        sha1.update(SHS_PAD_2);
-        return Arrays.copyOf(sha1.digest(), SESSION_KEY_LEN);
-    }
-
-    @VisibleForTesting
-    static byte[] generateMsk(String password, byte[] ntResponse)
-            throws GeneralSecurityException, UnsupportedEncodingException {
-        byte[] passwordHash = ntPasswordHash(password);
-        byte[] passwordHashHash = hashNtPasswordHash(passwordHash);
-        byte[] masterKey = getMasterKey(passwordHashHash, ntResponse);
-
-        // MSK: SendKey + ReceiveKey
-        ByteBuffer msk = ByteBuffer.allocate(MASTER_SESSION_KEY_LEN);
-        msk.put(getAsymmetricStartKey(masterKey, true /* isSend */));
-        msk.put(getAsymmetricStartKey(masterKey, false /* isSend */));
-
-        return msk.array();
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java
deleted file mode 100644
index dfd1627..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachine.java
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_RESPONSE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NOTIFICATION;
-
-import android.net.eap.EapSessionConfig.EapUiccConfig;
-import android.telephony.TelephonyManager;
-import android.util.Base64;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.crypto.Fips186_2Prf;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData;
-import com.android.internal.net.utils.Log;
-
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * EapSimAkaMethodStateMachine represents an abstract state machine for managing EAP-SIM and EAP-AKA
- * sessions.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186">RFC 4186, Extensible Authentication
- * Protocol for Subscriber Identity Modules (EAP-SIM)</a>
- * @see <a href="https://tools.ietf.org/html/rfc4187">RFC 4187, Extensible Authentication
- * Protocol for Authentication and Key Agreement (EAP-AKA)</a>
- */
-public abstract class EapSimAkaMethodStateMachine extends EapMethodStateMachine {
-    public static final String MASTER_KEY_GENERATION_ALG = "SHA-1";
-    public static final String MAC_ALGORITHM_STRING = "HmacSHA1";
-
-    // K_encr and K_aut lengths are 16 bytes (RFC 4186#7, RFC 4187#7)
-    public static final int KEY_LEN = 16;
-
-    // Session Key lengths are 64 bytes (RFC 4186#7, RFC 4187#7)
-    public static final int SESSION_KEY_LENGTH = 64;
-
-    public final byte[] mKEncr = new byte[getKEncrLength()];
-    public final byte[] mKAut = new byte[getKAutLength()];
-    public final byte[] mMsk = new byte[getMskLength()];
-    public final byte[] mEmsk = new byte[getEmskLength()];
-
-    @VisibleForTesting boolean mHasReceivedSimAkaNotification = false;
-
-    final TelephonyManager mTelephonyManager;
-    final byte[] mEapIdentity;
-    final EapUiccConfig mEapUiccConfig;
-
-    @VisibleForTesting Mac mMacAlgorithm;
-
-    EapSimAkaMethodStateMachine(
-            TelephonyManager telephonyManager, byte[] eapIdentity, EapUiccConfig eapUiccConfig) {
-        if (telephonyManager == null) {
-            throw new IllegalArgumentException("TelephonyManager must be non-null");
-        } else if (eapIdentity == null) {
-            throw new IllegalArgumentException("EapIdentity must be non-null");
-        } else if (eapUiccConfig == null) {
-            throw new IllegalArgumentException("EapUiccConfig must be non-null");
-        }
-        this.mTelephonyManager = telephonyManager;
-        this.mEapIdentity = eapIdentity;
-        this.mEapUiccConfig = eapUiccConfig;
-
-        LOG.d(
-                this.getClass().getSimpleName(),
-                mEapUiccConfig.getClass().getSimpleName() + ":"
-                        + " subId=" + mEapUiccConfig.subId
-                        + " apptype=" + mEapUiccConfig.apptype);
-    }
-
-    protected int getKEncrLength() {
-        return KEY_LEN;
-    }
-
-    protected int getKAutLength() {
-        return KEY_LEN;
-    }
-
-    protected int getMskLength() {
-        return SESSION_KEY_LENGTH;
-    }
-
-    protected int getEmskLength() {
-        return SESSION_KEY_LENGTH;
-    }
-
-    @Override
-    EapResult handleEapNotification(String tag, EapMessage message) {
-        return EapStateMachine.handleNotification(tag, message);
-    }
-
-    protected String getMacAlgorithm() {
-        return MAC_ALGORITHM_STRING;
-    }
-
-    @VisibleForTesting
-    EapResult buildClientErrorResponse(
-            int eapIdentifier,
-            int eapMethodType,
-            AtClientErrorCode clientErrorCode) {
-        EapSimAkaTypeData eapSimAkaTypeData = getEapSimAkaTypeData(clientErrorCode);
-        byte[] encodedTypeData = eapSimAkaTypeData.encode();
-
-        EapData eapData = new EapData(eapMethodType, encodedTypeData);
-        try {
-            EapMessage response = new EapMessage(EAP_CODE_RESPONSE, eapIdentifier, eapData);
-            return EapResult.EapResponse.getEapResponse(response);
-        } catch (EapSilentException ex) {
-            return new EapResult.EapError(ex);
-        }
-    }
-
-    @VisibleForTesting
-    EapResult buildResponseMessage(
-            int eapType,
-            int eapSubtype,
-            int identifier,
-            List<EapSimAkaAttribute> attributes) {
-        EapSimAkaTypeData eapSimTypeData = getEapSimAkaTypeData(eapSubtype, attributes);
-        EapData eapData = new EapData(eapType, eapSimTypeData.encode());
-
-        try {
-            EapMessage eapMessage = new EapMessage(EAP_CODE_RESPONSE, identifier, eapData);
-            return EapResult.EapResponse.getEapResponse(eapMessage);
-        } catch (EapSilentException ex) {
-            return new EapResult.EapError(ex);
-        }
-    }
-
-    @VisibleForTesting
-    protected void generateAndPersistKeys(
-            String tag, MessageDigest sha1, Fips186_2Prf prf, byte[] mkInput) {
-        byte[] mk = sha1.digest(mkInput);
-
-        // run mk through FIPS 186-2
-        int outputBytes = mKEncr.length + mKAut.length + mMsk.length + mEmsk.length;
-        byte[] prfResult = prf.getRandom(mk, outputBytes);
-
-        ByteBuffer prfResultBuffer = ByteBuffer.wrap(prfResult);
-        prfResultBuffer.get(mKEncr);
-        prfResultBuffer.get(mKAut);
-        prfResultBuffer.get(mMsk);
-        prfResultBuffer.get(mEmsk);
-
-        // Log as hash unless PII debug mode enabled
-        LOG.d(tag, "K_encr=" + LOG.pii(mKEncr));
-        LOG.d(tag, "K_aut=" + LOG.pii(mKAut));
-        LOG.d(tag, "MSK=" + LOG.pii(mMsk));
-        LOG.d(tag, "EMSK=" + LOG.pii(mEmsk));
-    }
-
-    @VisibleForTesting
-    byte[] processUiccAuthentication(String tag, int authType, byte[] formattedChallenge) throws
-            EapSimAkaAuthenticationFailureException {
-        String base64Challenge = Base64.encodeToString(formattedChallenge, Base64.NO_WRAP);
-        String base64Response =
-                mTelephonyManager.getIccAuthentication(
-                        mEapUiccConfig.apptype,
-                        authType,
-                        base64Challenge);
-
-        if (base64Response == null) {
-            String msg = "UICC authentication failed. Input: " + LOG.pii(formattedChallenge);
-            LOG.e(tag, msg);
-            throw new EapSimAkaAuthenticationFailureException(msg);
-        }
-
-        return Base64.decode(base64Response, Base64.DEFAULT);
-    }
-
-    @VisibleForTesting
-    boolean isValidMac(String tag, EapMessage message, EapSimAkaTypeData typeData, byte[] extraData)
-            throws GeneralSecurityException, EapSimAkaInvalidAttributeException,
-                    EapSilentException {
-        mMacAlgorithm = Mac.getInstance(getMacAlgorithm());
-        mMacAlgorithm.init(new SecretKeySpec(mKAut, getMacAlgorithm()));
-
-        byte[] mac = getMac(message.eapCode, message.eapIdentifier, typeData, extraData);
-        // attributes are 'valid', so must have AtMac
-        AtMac atMac = (AtMac) typeData.attributeMap.get(EAP_AT_MAC);
-
-        boolean isValidMac = Arrays.equals(mac, atMac.mac);
-        if (!isValidMac) {
-            // MAC in message != calculated mac
-            LOG.e(
-                    tag,
-                    "Received message with invalid Mac."
-                            + " received=" + Log.byteArrayToHexString(atMac.mac)
-                            + ", computed=" + Log.byteArrayToHexString(mac));
-        }
-
-        return isValidMac;
-    }
-
-    @VisibleForTesting
-    byte[] getMac(int eapCode, int eapIdentifier, EapSimAkaTypeData typeData, byte[] extraData)
-            throws EapSimAkaInvalidAttributeException, EapSilentException {
-        if (mMacAlgorithm == null) {
-            throw new IllegalStateException(
-                    "Can't calculate MAC before mMacAlgorithm is set in ChallengeState");
-        }
-
-        // cache original Mac so it can be restored after calculating the Mac
-        AtMac originalMac = (AtMac) typeData.attributeMap.get(EAP_AT_MAC);
-        typeData.attributeMap.put(EAP_AT_MAC, new AtMac());
-
-        byte[] typeDataWithEmptyMac = typeData.encode();
-        EapData eapData = new EapData(getEapMethod(), typeDataWithEmptyMac);
-        EapMessage messageForMac = new EapMessage(eapCode, eapIdentifier, eapData);
-
-        ByteBuffer buffer = ByteBuffer.allocate(messageForMac.eapLength + extraData.length);
-        buffer.put(messageForMac.encode());
-        buffer.put(extraData);
-        byte[] mac = mMacAlgorithm.doFinal(buffer.array());
-
-        typeData.attributeMap.put(EAP_AT_MAC, originalMac);
-
-        // need HMAC-SHA1-128 - first 16 bytes of SHA1 (RFC 4186#10.14, RFC 4187#10.15)
-        return Arrays.copyOfRange(mac, 0, AtMac.MAC_LENGTH);
-    }
-
-    @VisibleForTesting
-    EapResult buildResponseMessageWithMac(int identifier, int eapSubtype, byte[] extraData) {
-        // capacity of 1 for AtMac to be added
-        return buildResponseMessageWithMac(identifier, eapSubtype, extraData, new ArrayList<>(1));
-    }
-
-    @VisibleForTesting
-    EapResult buildResponseMessageWithMac(
-            int identifier, int eapSubtype, byte[] extraData, List<EapSimAkaAttribute> attributes) {
-        try {
-            attributes = new ArrayList<>(attributes);
-            attributes.add(new AtMac());
-            EapSimAkaTypeData eapSimAkaTypeData = getEapSimAkaTypeData(eapSubtype, attributes);
-
-            byte[] mac = getMac(EAP_CODE_RESPONSE, identifier, eapSimAkaTypeData, extraData);
-
-            eapSimAkaTypeData.attributeMap.put(EAP_AT_MAC, new AtMac(mac));
-            EapData eapData = new EapData(getEapMethod(), eapSimAkaTypeData.encode());
-            EapMessage eapMessage = new EapMessage(EAP_CODE_RESPONSE, identifier, eapData);
-            return EapResponse.getEapResponse(eapMessage);
-        } catch (EapSimAkaInvalidAttributeException | EapSilentException ex) {
-            // this should never happen
-            return new EapError(ex);
-        }
-    }
-
-    @VisibleForTesting
-    EapResult handleEapSimAkaNotification(
-            String tag,
-            boolean isPreChallengeState,
-            int identifier,
-            EapSimAkaTypeData eapSimAkaTypeData) {
-        // EAP-SIM exchanges must not include more than one EAP-SIM notification round
-        // (RFC 4186#6.1, RFC 4187#6.1)
-        if (mHasReceivedSimAkaNotification) {
-            return new EapError(
-                    new EapInvalidRequestException("Received multiple EAP-SIM notifications"));
-        }
-
-        mHasReceivedSimAkaNotification = true;
-        AtNotification atNotification =
-                (AtNotification) eapSimAkaTypeData.attributeMap.get(EAP_AT_NOTIFICATION);
-
-        LOG.d(
-                tag,
-                "Received AtNotification:"
-                        + " S=" + (atNotification.isSuccessCode ? "1" : "0")
-                        + " P=" + (atNotification.isPreSuccessfulChallenge ? "1" : "0")
-                        + " Code=" + atNotification.notificationCode);
-
-        // P bit of notification code is only allowed after a successful challenge round. This is
-        // only possible in the ChallengeState (RFC 4186#6.1, RFC 4187#6.1)
-        if (isPreChallengeState && !atNotification.isPreSuccessfulChallenge) {
-            return buildClientErrorResponse(
-                    identifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-        }
-
-        if (atNotification.isPreSuccessfulChallenge) {
-            // AT_MAC attribute must not be included when the P bit is set (RFC 4186#9.8,
-            // RFC 4187#9.10)
-            if (eapSimAkaTypeData.attributeMap.containsKey(EAP_AT_MAC)) {
-                return buildClientErrorResponse(
-                        identifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            return buildResponseMessage(
-                    getEapMethod(), eapSimAkaTypeData.eapSubtype, identifier, Arrays.asList());
-        } else if (!eapSimAkaTypeData.attributeMap.containsKey(EAP_AT_MAC)) {
-            // MAC must be included for messages with their P bit not set (RFC 4186#9.8,
-            // RFC 4187#9.10)
-            return buildClientErrorResponse(
-                    identifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-        }
-
-        try {
-            byte[] mac = getMac(EAP_CODE_REQUEST, identifier, eapSimAkaTypeData, new byte[0]);
-
-            AtMac atMac = (AtMac) eapSimAkaTypeData.attributeMap.get(EAP_AT_MAC);
-            if (!Arrays.equals(mac, atMac.mac)) {
-                // MAC in message != calculated mac
-                return buildClientErrorResponse(
-                        identifier, getEapMethod(), AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-        } catch (EapSilentException | EapSimAkaInvalidAttributeException ex) {
-            // We can't continue if the MAC can't be generated
-            return new EapError(ex);
-        }
-
-        // server has been authenticated, so we can send a response
-        return buildResponseMessageWithMac(identifier, eapSimAkaTypeData.eapSubtype, new byte[0]);
-    }
-
-    abstract EapSimAkaTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode);
-    abstract EapSimAkaTypeData getEapSimAkaTypeData(
-            int eapSubtype, List<EapSimAkaAttribute> attributes);
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachine.java
deleted file mode 100644
index 005cfb9..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachine.java
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ENCR_DATA;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_FULLAUTH_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IV;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CLIENT_ERROR;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.eap.EapSessionConfig.EapSimConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.crypto.Fips186_2Prf;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtSelectedVersion;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.SecureRandom;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-/**
- * EapSimMethodStateMachine represents the valid paths possible for the EAP-SIM protocol.
- *
- * <p>EAP-SIM procedures will always follow the path:
- *
- * Created ---> Start --+--> Challenge --+--> null
- *                      |                |
- *                      +-->  failed  >--+
- *
- * Note that EAP-SIM/Notification messages can be received at any point in the above state machine.
- * At most one EAP-SIM/Notification message is allowed per EAP-SIM session.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4186">RFC 4186, Extensible Authentication Protocol
- * Method for Subscriber Identity Modules (EAP-SIM)</a>
- */
-class EapSimMethodStateMachine extends EapSimAkaMethodStateMachine {
-    private final SecureRandom mSecureRandom;
-    private final EapSimTypeDataDecoder mEapSimTypeDataDecoder;
-
-    EapSimMethodStateMachine(
-            Context context,
-            byte[] eapIdentity,
-            EapSimConfig eapSimConfig,
-            SecureRandom secureRandom) {
-        this(
-                (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE),
-                eapIdentity,
-                eapSimConfig,
-                secureRandom,
-                EapSimTypeData.getEapSimTypeDataDecoder());
-    }
-
-    @VisibleForTesting
-    EapSimMethodStateMachine(
-            TelephonyManager telephonyManager,
-            byte[] eapIdentity,
-            EapSimConfig eapSimConfig,
-            SecureRandom secureRandom,
-            EapSimTypeDataDecoder eapSimTypeDataDecoder) {
-        super(
-                telephonyManager.createForSubscriptionId(eapSimConfig.subId),
-                eapIdentity,
-                eapSimConfig);
-
-        if (eapSimTypeDataDecoder == null) {
-            throw new IllegalArgumentException("EapSimTypeDataDecoder must be non-null");
-        }
-
-        this.mSecureRandom = secureRandom;
-        this.mEapSimTypeDataDecoder = eapSimTypeDataDecoder;
-        transitionTo(new CreatedState());
-    }
-
-    @Override
-    @EapMethod
-    int getEapMethod() {
-        return EAP_TYPE_SIM;
-    }
-
-    protected class CreatedState extends EapMethodState {
-        private final String mTAG = CreatedState.class.getSimpleName();
-
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            DecodeResult<EapSimTypeData> decodeResult =
-                    mEapSimTypeDataDecoder.decode(message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        decodeResult.atClientErrorCode);
-            }
-
-            EapSimTypeData eapSimTypeData = decodeResult.eapTypeData;
-            switch (eapSimTypeData.eapSubtype) {
-                case EAP_SIM_START:
-                    break;
-                case EAP_SIM_NOTIFICATION:
-                    return handleEapSimAkaNotification(
-                            mTAG,
-                            true, // isPreChallengeState
-                            message.eapIdentifier,
-                            eapSimTypeData);
-                default:
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            EAP_TYPE_SIM,
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            byte[] nonce = new byte[AtNonceMt.NONCE_MT_LENGTH];
-            mSecureRandom.nextBytes(nonce);
-            AtNonceMt atNonceMt;
-            try {
-                atNonceMt = new AtNonceMt(nonce);
-            } catch (EapSimAkaInvalidAttributeException ex) {
-                LOG.wtf(mTAG, "Exception thrown while creating AtNonceMt", ex);
-                return new EapError(ex);
-            }
-            return transitionAndProcess(new StartState(atNonceMt), message);
-        }
-    }
-
-    protected class StartState extends EapMethodState {
-        private final String mTAG = StartState.class.getSimpleName();
-        private final AtNonceMt mAtNonceMt;
-
-        private List<Integer> mVersions;
-
-        // use the EAP-Identity for the default value (RFC 4186#7)
-        @VisibleForTesting byte[] mIdentity = mEapIdentity;
-
-        protected StartState(AtNonceMt atNonceMt) {
-            this.mAtNonceMt = atNonceMt;
-        }
-
-        public EapResult process(EapMessage message) {
-            EapResult result = handleEapSuccessFailureNotification(mTAG, message);
-            if (result != null) {
-                return result;
-            }
-
-            DecodeResult<EapSimTypeData> decodeResult =
-                    mEapSimTypeDataDecoder.decode(message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        decodeResult.atClientErrorCode);
-            }
-
-            EapSimTypeData eapSimTypeData = decodeResult.eapTypeData;
-            switch (eapSimTypeData.eapSubtype) {
-                case EAP_SIM_START:
-                    break;
-                case EAP_SIM_NOTIFICATION:
-                    return handleEapSimAkaNotification(
-                            mTAG,
-                            true, // isPreChallengeState
-                            message.eapIdentifier,
-                            eapSimTypeData);
-                case EAP_SIM_CHALLENGE:
-                    // By virtue of being in the StartState, we have received (and processed) the
-                    // EAP-SIM/Start request. Receipt of an EAP-SIM/Challenge request indicates that
-                    // the server has accepted our EAP-SIM/Start response, including our identity
-                    // (if any).
-                    return transitionAndProcess(
-                            new ChallengeState(mVersions, mAtNonceMt, mIdentity), message);
-                default:
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            EAP_TYPE_SIM,
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            if (!isValidStartAttributes(eapSimTypeData)) {
-                LOG.e(mTAG, "Invalid attributes: " + eapSimTypeData.attributeMap.keySet());
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            List<EapSimAkaAttribute> responseAttributes = new ArrayList<>();
-            responseAttributes.add(mAtNonceMt);
-
-            // choose EAP-SIM version
-            AtVersionList atVersionList = (AtVersionList)
-                    eapSimTypeData.attributeMap.get(EAP_AT_VERSION_LIST);
-            mVersions = atVersionList.versions;
-            if (!mVersions.contains(AtSelectedVersion.SUPPORTED_VERSION)) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        AtClientErrorCode.UNSUPPORTED_VERSION);
-            }
-            responseAttributes.add(AtSelectedVersion.getSelectedVersion());
-
-            try {
-                AtIdentity atIdentity = getIdentityResponse(eapSimTypeData);
-                if (atIdentity != null) {
-                    responseAttributes.add(atIdentity);
-                }
-            } catch (EapSimAkaInvalidAttributeException ex) {
-                LOG.wtf(mTAG, "Exception thrown while making AtIdentity attribute", ex);
-                return new EapError(ex);
-            } catch (EapSimAkaIdentityUnavailableException ex) {
-                LOG.e(mTAG, "Unable to get IMSI for subId=" + mEapUiccConfig.subId);
-                return new EapError(ex);
-            }
-
-            return buildResponseMessage(
-                    EAP_TYPE_SIM,
-                    EAP_SIM_START,
-                    message.eapIdentifier,
-                    responseAttributes);
-        }
-
-        /**
-         * Returns true iff the given EapSimTypeData meets the following conditions:
-         *  - contains an AT_VERSION_LIST attribute
-         *  - contains at most one of AT_PERMANENT_ID_REQ, AT_ANY_ID_REQ, or AT_FULLAUTH_D_REQ
-         *      attributes
-         *  - does not contain AT_MAC, AT_IV, or AT_ENCR_DATA attributes
-         */
-        @VisibleForTesting
-        boolean isValidStartAttributes(EapSimTypeData eapSimTypeData) {
-            // must contain: version list
-            Set<Integer> attrs = eapSimTypeData.attributeMap.keySet();
-            if (!attrs.contains(EAP_AT_VERSION_LIST)) {
-                return false;
-            }
-
-            // may contain: ID request (but only 1)
-            int idRequests = 0;
-            if (attrs.contains(EAP_AT_PERMANENT_ID_REQ)) {
-                idRequests++;
-            }
-            if (attrs.contains(EAP_AT_ANY_ID_REQ)) {
-                idRequests++;
-            }
-            if (attrs.contains(EAP_AT_FULLAUTH_ID_REQ)) {
-                idRequests++;
-            }
-            if (idRequests > 1) {
-                return false;
-            }
-
-            // can't contain mac, iv, encr data
-            if (attrs.contains(EAP_AT_MAC)
-                    || attrs.contains(EAP_AT_IV)
-                    || attrs.contains(EAP_AT_ENCR_DATA)) {
-                return false;
-            }
-            return true;
-        }
-
-        @VisibleForTesting
-        @Nullable
-        AtIdentity getIdentityResponse(EapSimTypeData eapSimTypeData)
-                throws EapSimAkaInvalidAttributeException, EapSimAkaIdentityUnavailableException {
-            Set<Integer> attributes = eapSimTypeData.attributeMap.keySet();
-
-            // TODO(b/136180022): process separate ID requests differently (pseudonym vs permanent)
-            if (attributes.contains(EAP_AT_PERMANENT_ID_REQ)
-                    || attributes.contains(EAP_AT_FULLAUTH_ID_REQ)
-                    || attributes.contains(EAP_AT_ANY_ID_REQ)) {
-                String imsi = mTelephonyManager.getSubscriberId();
-                if (imsi == null) {
-                    throw new EapSimAkaIdentityUnavailableException(
-                            "IMSI for subId (" + mEapUiccConfig.subId + ") not available");
-                }
-
-                // Permanent Identity is "1" + IMSI (RFC 4186 Section 4.1.2.6)
-                String identity = "1" + imsi;
-                mIdentity = identity.getBytes(StandardCharsets.US_ASCII);
-                LOG.d(mTAG, "EAP-SIM/Identity=" + LOG.pii(identity));
-
-                return AtIdentity.getAtIdentity(mIdentity);
-            }
-
-            return null;
-        }
-    }
-
-    protected class ChallengeState extends EapMethodState {
-        private final String mTAG = ChallengeState.class.getSimpleName();
-        private final int mBytesPerShort = 2;
-        private final int mVersionLenBytes = 2;
-
-        // Lengths defined by TS 31.102 Section 7.1.2.1 (case 3)
-        // SRES stands for "SIM response"
-        // Kc stands for "cipher key"
-        private final int mSresLenBytes = 4;
-        private final int mKcLenBytes = 8;
-
-        private final List<Integer> mVersions;
-        private final byte[] mNonce;
-        @VisibleForTesting final byte[] mIdentity;
-
-        protected ChallengeState(List<Integer> versions, AtNonceMt atNonceMt, byte[] identity) {
-            mVersions = versions;
-            mNonce = atNonceMt.nonceMt;
-            mIdentity = identity;
-        }
-
-        public EapResult process(EapMessage message) {
-            if (message.eapCode == EAP_CODE_SUCCESS) {
-                transitionTo(new FinalState());
-                return new EapSuccess(mMsk, mEmsk);
-            } else if (message.eapCode == EAP_CODE_FAILURE) {
-                transitionTo(new FinalState());
-                return new EapFailure();
-            } else if (message.eapData.eapType == EAP_NOTIFICATION) {
-                return handleEapNotification(mTAG, message);
-            }
-
-            if (message.eapData.eapType != getEapMethod()) {
-                return new EapError(new EapInvalidRequestException(
-                        "Expected EAP Type " + getEapMethod()
-                                + ", received " + message.eapData.eapType));
-            }
-
-            DecodeResult<EapSimTypeData> decodeResult =
-                    mEapSimTypeDataDecoder.decode(message.eapData.eapTypeData);
-            if (!decodeResult.isSuccessfulDecode()) {
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        decodeResult.atClientErrorCode);
-            }
-
-            EapSimTypeData eapSimTypeData = decodeResult.eapTypeData;
-            switch (eapSimTypeData.eapSubtype) {
-                case EAP_SIM_NOTIFICATION:
-                    return handleEapSimAkaNotification(
-                            mTAG,
-                            false, // isPreChallengeState
-                            message.eapIdentifier,
-                            eapSimTypeData);
-                case EAP_SIM_CHALLENGE:
-                    break;
-                default:
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            EAP_TYPE_SIM,
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            if (!isValidChallengeAttributes(eapSimTypeData)) {
-                LOG.e(mTAG, "Invalid attributes: " + eapSimTypeData.attributeMap.keySet());
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            List<RandChallengeResult> randChallengeResults;
-            try {
-                randChallengeResults = getRandChallengeResults(eapSimTypeData);
-            } catch (EapSimAkaInvalidLengthException | BufferUnderflowException ex) {
-                LOG.e(mTAG, "Invalid SRES/Kc tuple returned from SIM", ex);
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        AtClientErrorCode.UNABLE_TO_PROCESS);
-            }  catch (EapSimAkaAuthenticationFailureException ex) {
-                return new EapError(ex);
-            }
-
-            try {
-                MessageDigest sha1 = MessageDigest.getInstance(MASTER_KEY_GENERATION_ALG);
-                byte[] mkInputData = getMkInputData(randChallengeResults);
-                generateAndPersistKeys(mTAG, sha1, new Fips186_2Prf(), mkInputData);
-            } catch (NoSuchAlgorithmException | BufferUnderflowException ex) {
-                LOG.e(mTAG, "Error while creating keys", ex);
-                return buildClientErrorResponse(
-                        message.eapIdentifier,
-                        EAP_TYPE_SIM,
-                        AtClientErrorCode.UNABLE_TO_PROCESS);
-            }
-
-            try {
-                if (!isValidMac(mTAG, message, eapSimTypeData, mNonce)) {
-                    return buildClientErrorResponse(
-                            message.eapIdentifier,
-                            EAP_TYPE_SIM,
-                            AtClientErrorCode.UNABLE_TO_PROCESS);
-                }
-            } catch (GeneralSecurityException | EapSilentException
-                    | EapSimAkaInvalidAttributeException ex) {
-                // if the MAC can't be generated, we can't continue
-                LOG.e(mTAG, "Error computing MAC for EapMessage", ex);
-                return new EapError(ex);
-            }
-
-            ByteBuffer sresValues =
-                    ByteBuffer.allocate(randChallengeResults.size() * mSresLenBytes);
-            for (RandChallengeResult result : randChallengeResults) {
-                sresValues.put(result.sres);
-            }
-
-            // server has been authenticated, so we can send a response
-            return buildResponseMessageWithMac(
-                    message.eapIdentifier,
-                    EAP_SIM_CHALLENGE,
-                    sresValues.array());
-        }
-
-        /**
-         * Returns true iff the given EapSimTypeData contains both AT_RAND and AT_MAC attributes.
-         */
-        @VisibleForTesting
-        boolean isValidChallengeAttributes(EapSimTypeData eapSimTypeData) {
-            Set<Integer> attrs = eapSimTypeData.attributeMap.keySet();
-            return attrs.contains(EAP_AT_RAND) && attrs.contains(EAP_AT_MAC);
-        }
-
-        @VisibleForTesting
-        List<RandChallengeResult> getRandChallengeResults(EapSimTypeData eapSimTypeData)
-                throws EapSimAkaInvalidLengthException, EapSimAkaAuthenticationFailureException {
-            AtRandSim atRand = (AtRandSim) eapSimTypeData.attributeMap.get(EAP_AT_RAND);
-            List<byte[]> randList = atRand.rands;
-            List<RandChallengeResult> challengeResults = new ArrayList<>();
-
-            for (byte[] rand : randList) {
-                // Rand (pre-Base64 formatting) needs to be formatted as [length][rand data]
-                ByteBuffer formattedRand = ByteBuffer.allocate(rand.length + 1);
-                formattedRand.put((byte) rand.length);
-                formattedRand.put(rand);
-
-                byte[] challengeResponseBytes =
-                        processUiccAuthentication(
-                                mTAG,
-                                TelephonyManager.AUTHTYPE_EAP_SIM,
-                                formattedRand.array());
-
-                RandChallengeResult randChallengeResult =
-                        getRandChallengeResultFromResponse(challengeResponseBytes);
-                challengeResults.add(randChallengeResult);
-
-                // Log rand/challenge as PII
-                LOG.d(
-                        mTAG,
-                        "RAND=" + LOG.pii(rand)
-                                + " SRES=" + LOG.pii(randChallengeResult.sres)
-                                + " Kc=" + LOG.pii(randChallengeResult.kc));
-            }
-
-            return challengeResults;
-        }
-
-        /**
-         * Parses the SRES and Kc values from the given challengeResponse. The values are returned
-         * in a Pair<byte[], byte[]>, where SRES and Kc are the first and second values,
-         * respectively.
-         */
-        @VisibleForTesting
-        RandChallengeResult getRandChallengeResultFromResponse(byte[] challengeResponse)
-                throws EapSimAkaInvalidLengthException {
-            ByteBuffer buffer = ByteBuffer.wrap(challengeResponse);
-            int lenSres = Byte.toUnsignedInt(buffer.get());
-            if (lenSres != mSresLenBytes) {
-                throw new EapSimAkaInvalidLengthException("Invalid SRES length specified");
-            }
-            byte[] sres = new byte[mSresLenBytes];
-            buffer.get(sres);
-
-            int lenKc = Byte.toUnsignedInt(buffer.get());
-            if (lenKc != mKcLenBytes) {
-                throw new EapSimAkaInvalidLengthException("Invalid Kc length specified");
-            }
-            byte[] kc = new byte[mKcLenBytes];
-            buffer.get(kc);
-
-            return new RandChallengeResult(sres, kc);
-        }
-
-        @VisibleForTesting
-        class RandChallengeResult {
-            public final byte[] sres;
-            public final byte[] kc;
-
-            RandChallengeResult(byte[] sres, byte[] kc) throws EapSimAkaInvalidLengthException {
-                this.sres = sres;
-                this.kc = kc;
-
-                if (sres.length != mSresLenBytes) {
-                    throw new EapSimAkaInvalidLengthException("Invalid SRES length");
-                }
-                if (kc.length != mKcLenBytes) {
-                    throw new EapSimAkaInvalidLengthException("Invalid Kc length");
-                }
-            }
-
-            @Override
-            public boolean equals(Object o) {
-                if (this == o) return true;
-                if (!(o instanceof RandChallengeResult)) return false;
-                RandChallengeResult that = (RandChallengeResult) o;
-                return Arrays.equals(sres, that.sres)
-                        && Arrays.equals(kc, that.kc);
-            }
-
-            @Override
-            public int hashCode() {
-                int result = Arrays.hashCode(sres);
-                result = 31 * result + Arrays.hashCode(kc);
-                return result;
-            }
-        }
-
-        private byte[] getMkInputData(List<RandChallengeResult> randChallengeResults) {
-            int numInputBytes =
-                    mIdentity.length
-                            + (randChallengeResults.size() * mKcLenBytes)
-                            + mNonce.length
-                            + (mVersions.size() * mBytesPerShort) // 2B per version
-                            + mVersionLenBytes;
-
-            ByteBuffer mkInputBuffer = ByteBuffer.allocate(numInputBytes);
-            mkInputBuffer.put(mIdentity);
-            for (RandChallengeResult randChallengeResult : randChallengeResults) {
-                mkInputBuffer.put(randChallengeResult.kc);
-            }
-            mkInputBuffer.put(mNonce);
-            for (int i : mVersions) {
-                mkInputBuffer.putShort((short) i);
-            }
-            mkInputBuffer.putShort((short) AtSelectedVersion.SUPPORTED_VERSION);
-            return mkInputBuffer.array();
-        }
-    }
-
-    EapSimTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) {
-        return new EapSimTypeData(EAP_SIM_CLIENT_ERROR, Arrays.asList(clientErrorCode));
-    }
-
-    EapSimTypeData getEapSimAkaTypeData(int eapSubtype, List<EapSimAkaAttribute> attributes) {
-        return new EapSimTypeData(eapSubtype, attributes);
-    }
-}
diff --git a/src/java/com/android/internal/net/eap/statemachine/EapStateMachine.java b/src/java/com/android/internal/net/eap/statemachine/EapStateMachine.java
deleted file mode 100644
index f3e933e..0000000
--- a/src/java/com/android/internal/net/eap/statemachine/EapStateMachine.java
+++ /dev/null
@@ -1,371 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapAuthenticator.LOG;
-import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY;
-import static com.android.internal.net.eap.message.EapData.EAP_NAK;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_STRING;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_RESPONSE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_STRING;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.net.eap.EapSessionConfig.EapAkaPrimeConfig;
-import android.net.eap.EapSessionConfig.EapMethodConfig;
-import android.net.eap.EapSessionConfig.EapMsChapV2Config;
-import android.net.eap.EapSessionConfig.EapSimConfig;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.EapSilentException;
-import com.android.internal.net.eap.exceptions.UnsupportedEapTypeException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapData.EapMethod;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.utils.SimpleStateMachine;
-
-import java.nio.charset.StandardCharsets;
-import java.security.SecureRandom;
-
-/**
- * EapStateMachine represents the valid paths for a single EAP Authentication procedure.
- *
- * <p>EAP Authentication procedures will always follow the path:
- *
- * CreatedState --> IdentityState --> Method State --+--> SuccessState
- *      |                                 ^          |
- *      +---------------------------------+          +--> FailureState
- *
- */
-public class EapStateMachine extends SimpleStateMachine<byte[], EapResult> {
-    private static final String TAG = EapStateMachine.class.getSimpleName();
-
-    private final Context mContext;
-    private final EapSessionConfig mEapSessionConfig;
-    private final SecureRandom mSecureRandom;
-
-    public EapStateMachine(
-            @NonNull Context context,
-            @NonNull EapSessionConfig eapSessionConfig,
-            @NonNull SecureRandom secureRandom) {
-        this.mContext = context;
-        this.mEapSessionConfig = eapSessionConfig;
-        this.mSecureRandom = secureRandom;
-
-        LOG.d(
-                TAG,
-                "Starting EapStateMachine with EAP-Identity="
-                        + LOG.pii(eapSessionConfig.eapIdentity)
-                        + " and configs=" + eapSessionConfig.eapConfigs.keySet());
-
-        transitionTo(new CreatedState());
-    }
-
-    @VisibleForTesting
-    protected SimpleStateMachine.SimpleState getState() {
-        return mState;
-    }
-
-    @VisibleForTesting
-    protected void transitionTo(EapState newState) {
-        LOG.d(
-                TAG,
-                "Transitioning from " + mState.getClass().getSimpleName()
-                        + " to " + newState.getClass().getSimpleName());
-        super.transitionTo(newState);
-    }
-
-    @VisibleForTesting
-    protected EapResult transitionAndProcess(EapState newState, byte[] packet) {
-        return super.transitionAndProcess(newState, packet);
-    }
-
-    protected abstract class EapState extends SimpleState {
-        protected DecodeResult decode(@NonNull byte[] packet) {
-            LOG.d(getClass().getSimpleName(),
-                    "Received packet=[" + LOG.pii(packet) + "]");
-
-            if (packet == null) {
-                return new DecodeResult(new EapError(
-                        new IllegalArgumentException("Attempting to decode null packet")));
-            }
-
-            try {
-                EapMessage eapMessage = EapMessage.decode(packet);
-
-                // Log inbound message in the format "EAP-<Code>/<Type>"
-                String eapDataString =
-                        (eapMessage.eapData == null)
-                                ? ""
-                                : "/" + EAP_TYPE_STRING.getOrDefault(
-                                        eapMessage.eapData.eapType,
-                                        "UNKNOWN (" + eapMessage.eapData.eapType + ")");
-                String msg = "Decoded message: EAP-"
-                        + EAP_CODE_STRING.getOrDefault(eapMessage.eapCode, "UNKNOWN")
-                        + eapDataString;
-                LOG.i(getClass().getSimpleName(), msg);
-
-                if (eapMessage.eapCode == EAP_CODE_RESPONSE) {
-                    EapInvalidRequestException cause =
-                            new EapInvalidRequestException("Received an EAP-Response message");
-                    return new DecodeResult(new EapError(cause));
-                } else if (eapMessage.eapCode == EAP_CODE_REQUEST
-                        && eapMessage.eapData.eapType == EAP_NAK) {
-                    // RFC 3748 Section 5.3.1 states that Nak type is only valid in responses
-                    EapInvalidRequestException cause =
-                            new EapInvalidRequestException("Received an EAP-Request of type Nak");
-                    return new DecodeResult(new EapError(cause));
-                }
-
-                return new DecodeResult(eapMessage);
-            } catch (UnsupportedEapTypeException ex) {
-                return new DecodeResult(
-                        EapMessage.getNakResponse(
-                                ex.eapIdentifier,
-                                mEapSessionConfig.eapConfigs.keySet()));
-            } catch (EapSilentException ex) {
-                return new DecodeResult(new EapError(ex));
-            }
-        }
-
-        protected final class DecodeResult {
-            public final EapMessage eapMessage;
-            public final EapResult eapResult;
-
-            public DecodeResult(EapMessage eapMessage) {
-                this.eapMessage = eapMessage;
-                this.eapResult = null;
-            }
-
-            public DecodeResult(EapResult eapResult) {
-                this.eapMessage = null;
-                this.eapResult = eapResult;
-            }
-
-            public boolean isValidEapMessage() {
-                return eapMessage != null;
-            }
-        }
-    }
-
-    protected class CreatedState extends EapState {
-        private final String mTAG = CreatedState.class.getSimpleName();
-
-        public EapResult process(@NonNull byte[] packet) {
-            DecodeResult decodeResult = decode(packet);
-            if (!decodeResult.isValidEapMessage()) {
-                return decodeResult.eapResult;
-            }
-            EapMessage message = decodeResult.eapMessage;
-
-            if (message.eapCode != EAP_CODE_REQUEST) {
-                return new EapError(
-                        new EapInvalidRequestException("Received non EAP-Request in CreatedState"));
-            }
-
-            // EapMessage#validate verifies that all EapMessage objects representing
-            // EAP-Request packets have a Type value
-            switch (message.eapData.eapType) {
-                case EAP_NOTIFICATION:
-                    return handleNotification(mTAG, message);
-
-                case EAP_IDENTITY:
-                    return transitionAndProcess(new IdentityState(), packet);
-
-                // all EAP methods should be handled by MethodState
-                default:
-                    return transitionAndProcess(new MethodState(), packet);
-            }
-        }
-    }
-
-    protected class IdentityState extends EapState {
-        private final String mTAG = IdentityState.class.getSimpleName();
-
-        public EapResult process(@NonNull byte[] packet) {
-            DecodeResult decodeResult = decode(packet);
-            if (!decodeResult.isValidEapMessage()) {
-                return decodeResult.eapResult;
-            }
-            EapMessage message = decodeResult.eapMessage;
-
-            if (message.eapCode != EAP_CODE_REQUEST) {
-                return new EapError(new EapInvalidRequestException(
-                        "Received non EAP-Request in IdentityState"));
-            }
-
-            // EapMessage#validate verifies that all EapMessage objects representing
-            // EAP-Request packets have a Type value
-            switch (message.eapData.eapType) {
-                case EAP_NOTIFICATION:
-                    return handleNotification(mTAG, message);
-
-                case EAP_IDENTITY:
-                    return getIdentityResponse(message.eapIdentifier);
-
-                // all EAP methods should be handled by MethodState
-                default:
-                    return transitionAndProcess(new MethodState(), packet);
-            }
-        }
-
-        @VisibleForTesting
-        EapResult getIdentityResponse(int eapIdentifier) {
-            try {
-                LOG.d(mTAG, "Returning EAP-Identity: " + LOG.pii(mEapSessionConfig.eapIdentity));
-                EapData identityData = new EapData(EAP_IDENTITY, mEapSessionConfig.eapIdentity);
-                return EapResponse.getEapResponse(
-                        new EapMessage(EAP_CODE_RESPONSE, eapIdentifier, identityData));
-            } catch (EapSilentException ex) {
-                // this should never happen - only identifier and identity bytes are variable
-                LOG.wtf(mTAG,  "Failed to create Identity response for message with identifier="
-                        + LOG.pii(eapIdentifier));
-                return new EapError(ex);
-            }
-        }
-    }
-
-    protected class MethodState extends EapState {
-        private final String mTAG = MethodState.class.getSimpleName();
-
-        @VisibleForTesting
-        EapMethodStateMachine mEapMethodStateMachine;
-
-        // Not all EAP Method implementations may support EAP-Notifications, so allow the EAP-Method
-        // to handle any EAP-REQUEST/Notification messages (RFC 3748 Section 5.2)
-        public EapResult process(@NonNull byte[] packet) {
-            DecodeResult decodeResult = decode(packet);
-            if (!decodeResult.isValidEapMessage()) {
-                return decodeResult.eapResult;
-            }
-            EapMessage eapMessage = decodeResult.eapMessage;
-
-            if (mEapMethodStateMachine == null) {
-                if (eapMessage.eapCode == EAP_CODE_SUCCESS) {
-                    // EAP-SUCCESS is required to be the last EAP message sent during the EAP
-                    // protocol, so receiving a premature SUCCESS message is an unrecoverable error
-                    return new EapError(
-                            new EapInvalidRequestException(
-                                    "Received an EAP-Success in the MethodState"));
-                } else if (eapMessage.eapCode == EAP_CODE_FAILURE) {
-                    transitionTo(new FailureState());
-                    return new EapFailure();
-                } else if (eapMessage.eapData.eapType == EAP_NOTIFICATION) {
-                    // if no EapMethodStateMachine has been assigned and we receive an
-                    // EAP-Notification, we should log it and respond
-                    return handleNotification(mTAG, eapMessage);
-                }
-
-                int eapType = eapMessage.eapData.eapType;
-                mEapMethodStateMachine = buildEapMethodStateMachine(eapType);
-
-                if (mEapMethodStateMachine == null) {
-                    return EapMessage.getNakResponse(
-                            eapMessage.eapIdentifier,
-                            mEapSessionConfig.eapConfigs.keySet());
-                }
-            }
-
-            EapResult result = mEapMethodStateMachine.process(decodeResult.eapMessage);
-            if (result instanceof EapSuccess) {
-                transitionTo(new SuccessState());
-            } else if (result instanceof EapFailure) {
-                transitionTo(new FailureState());
-            }
-            return result;
-        }
-
-        @Nullable
-        private EapMethodStateMachine buildEapMethodStateMachine(@EapMethod int eapType) {
-            EapMethodConfig eapMethodConfig = mEapSessionConfig.eapConfigs.get(eapType);
-            if (eapMethodConfig == null) {
-                LOG.e(
-                        mTAG,
-                        "No configs provided for method: "
-                                + EAP_TYPE_STRING.getOrDefault(
-                                        eapType, "Unknown (" + eapType + ")"));
-                return null;
-            }
-
-            switch (eapType) {
-                case EAP_TYPE_SIM:
-                    EapSimConfig eapSimConfig = (EapSimConfig) eapMethodConfig;
-                    return new EapSimMethodStateMachine(
-                            mContext, mEapSessionConfig.eapIdentity, eapSimConfig, mSecureRandom);
-                case EAP_TYPE_AKA:
-                    EapAkaConfig eapAkaConfig = (EapAkaConfig) eapMethodConfig;
-                    boolean supportsEapAkaPrime =
-                            mEapSessionConfig.eapConfigs.containsKey(EAP_TYPE_AKA_PRIME);
-                    return new EapAkaMethodStateMachine(
-                            mContext,
-                            mEapSessionConfig.eapIdentity,
-                            eapAkaConfig,
-                            supportsEapAkaPrime);
-                case EAP_TYPE_AKA_PRIME:
-                    EapAkaPrimeConfig eapAkaPrimeConfig = (EapAkaPrimeConfig) eapMethodConfig;
-                    return new EapAkaPrimeMethodStateMachine(
-                            mContext, mEapSessionConfig.eapIdentity, eapAkaPrimeConfig);
-                case EAP_TYPE_MSCHAP_V2:
-                    EapMsChapV2Config eapMsChapV2Config = (EapMsChapV2Config) eapMethodConfig;
-                    return new EapMsChapV2MethodStateMachine(eapMsChapV2Config, mSecureRandom);
-                default:
-                    // received unsupported EAP Type. This should never happen.
-                    LOG.e(mTAG, "Received unsupported EAP Type=" + eapType);
-                    throw new IllegalArgumentException(
-                            "Received unsupported EAP Type in MethodState constructor");
-            }
-        }
-    }
-
-    protected class SuccessState extends EapState {
-        public EapResult process(byte[] packet) {
-            return new EapError(new EapInvalidRequestException(
-                    "Not possible to process messages in Success State"));
-        }
-    }
-
-    protected class FailureState extends EapState {
-        public EapResult process(byte[] message) {
-            return new EapError(new EapInvalidRequestException(
-                    "Not possible to process messages in Failure State"));
-        }
-    }
-
-    protected static EapResult handleNotification(String tag, EapMessage message) {
-        // Type-Data will be UTF-8 encoded ISO 10646 characters (RFC 3748 Section 5.2)
-        String content = new String(message.eapData.eapTypeData, StandardCharsets.UTF_8);
-        LOG.i(tag, "Received EAP-Request/Notification: [" + content + "]");
-        return EapMessage.getNotificationResponse(message.eapIdentifier);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/AbstractSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/AbstractSessionStateMachine.java
deleted file mode 100644
index 8212284..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/AbstractSessionStateMachine.java
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike;
-
-import static android.net.ipsec.ike.IkeManager.getIkeLog;
-
-import android.os.Looper;
-import android.os.Message;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * This class represents the common information of both IkeSessionStateMachine and
- * ChildSessionStateMachine
- */
-abstract class AbstractSessionStateMachine extends StateMachine {
-    private static final int CMD_SHARED_BASE = 0;
-    protected static final int CMD_CATEGORY_SIZE = 100;
-
-    /**
-     * Commands of Child local request that will be used in both IkeSessionStateMachine and
-     * ChildSessionStateMachine.
-     */
-    protected static final int CMD_CHILD_LOCAL_REQUEST_BASE = CMD_SHARED_BASE;
-
-    @VisibleForTesting
-    static final int CMD_LOCAL_REQUEST_CREATE_CHILD = CMD_CHILD_LOCAL_REQUEST_BASE + 1;
-
-    @VisibleForTesting
-    static final int CMD_LOCAL_REQUEST_DELETE_CHILD = CMD_CHILD_LOCAL_REQUEST_BASE + 2;
-
-    @VisibleForTesting
-    static final int CMD_LOCAL_REQUEST_REKEY_CHILD = CMD_CHILD_LOCAL_REQUEST_BASE + 3;
-
-    /** Timeout commands. */
-    protected static final int CMD_TIMEOUT_BASE = CMD_SHARED_BASE + CMD_CATEGORY_SIZE;
-    /** Timeout when the remote side fails to send a Rekey-Delete request. */
-    @VisibleForTesting static final int TIMEOUT_REKEY_REMOTE_DELETE = CMD_TIMEOUT_BASE + 1;
-
-    /** Commands for testing only */
-    protected static final int CMD_TEST_BASE = CMD_SHARED_BASE + 2 * CMD_CATEGORY_SIZE;
-    /** Force state machine to a target state for testing purposes. */
-    @VisibleForTesting static final int CMD_FORCE_TRANSITION = CMD_TEST_BASE + 1;
-
-    /** Private commands for subclasses */
-    protected static final int CMD_PRIVATE_BASE = CMD_SHARED_BASE + 3 * CMD_CATEGORY_SIZE;
-
-    protected static final SparseArray<String> SHARED_CMD_TO_STR;
-
-    static {
-        SHARED_CMD_TO_STR = new SparseArray<>();
-        SHARED_CMD_TO_STR.put(CMD_LOCAL_REQUEST_CREATE_CHILD, "Create Child");
-        SHARED_CMD_TO_STR.put(CMD_LOCAL_REQUEST_DELETE_CHILD, "Delete Child");
-        SHARED_CMD_TO_STR.put(CMD_LOCAL_REQUEST_REKEY_CHILD, "Rekey Child");
-        SHARED_CMD_TO_STR.put(TIMEOUT_REKEY_REMOTE_DELETE, "Timout rekey remote delete");
-        SHARED_CMD_TO_STR.put(CMD_FORCE_TRANSITION, "Force transition");
-    }
-
-    // Use a value greater than the retransmit-failure timeout.
-    static final long REKEY_DELETE_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(180L);
-
-    private final String mLogTag;
-
-    protected AbstractSessionStateMachine(String name, Looper looper) {
-        super(name, looper);
-        mLogTag = name;
-    }
-
-    /**
-     * Top level state for handling uncaught exceptions for all subclasses.
-     *
-     * <p>All other state in SessionStateMachine MUST extend this state.
-     *
-     * <p>Only errors this state should catch are unexpected internal failures. Since this may be
-     * run in critical processes, it must never take down the process if it fails
-     */
-    protected abstract class ExceptionHandlerBase extends State {
-        @Override
-        public final void enter() {
-            try {
-                enterState();
-            } catch (RuntimeException e) {
-                cleanUpAndQuit(e);
-            }
-        }
-
-        @Override
-        public final boolean processMessage(Message message) {
-            try {
-                String cmdName = SHARED_CMD_TO_STR.get(message.what);
-                if (cmdName == null) {
-                    cmdName = getCmdString(message.what);
-                }
-
-                // Unrecognized message will be logged by super class(Android StateMachine)
-                if (cmdName != null) logd("processStateMessage: " + cmdName);
-
-                return processStateMessage(message);
-            } catch (RuntimeException e) {
-                cleanUpAndQuit(e);
-                return HANDLED;
-            }
-        }
-
-        @Override
-        public final void exit() {
-            try {
-                exitState();
-            } catch (RuntimeException e) {
-                cleanUpAndQuit(e);
-            }
-        }
-
-        protected void enterState() {
-            // Do nothing. Subclasses MUST override it if they care.
-        }
-
-        protected boolean processStateMessage(Message message) {
-            return NOT_HANDLED;
-        }
-
-        protected void exitState() {
-            // Do nothing. Subclasses MUST override it if they care.
-        }
-
-        protected abstract void cleanUpAndQuit(RuntimeException e);
-
-        protected abstract String getCmdString(int cmd);
-    }
-
-    @Override
-    protected void log(String s) {
-        getIkeLog().d(mLogTag, s);
-    }
-
-    @Override
-    protected void logd(String s) {
-        getIkeLog().d(mLogTag, s);
-    }
-
-    protected void logd(String s, Throwable e) {
-        getIkeLog().d(mLogTag, s, e);
-    }
-
-    @Override
-    protected void logv(String s) {
-        getIkeLog().v(mLogTag, s);
-    }
-
-    @Override
-    protected void logi(String s) {
-        getIkeLog().i(mLogTag, s);
-    }
-
-    protected void logi(String s, Throwable cause) {
-        getIkeLog().i(mLogTag, s, cause);
-    }
-
-    @Override
-    protected void logw(String s) {
-        getIkeLog().w(mLogTag, s);
-    }
-
-    @Override
-    protected void loge(String s) {
-        getIkeLog().e(mLogTag, s);
-    }
-
-    @Override
-    protected void loge(String s, Throwable e) {
-        getIkeLog().e(mLogTag, s, e);
-    }
-
-    protected void logWtf(String s) {
-        getIkeLog().wtf(mLogTag, s);
-    }
-
-    protected void logWtf(String s, Throwable e) {
-        getIkeLog().wtf(mLogTag, s, e);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java
deleted file mode 100644
index 889d8c1..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachine.java
+++ /dev/null
@@ -1,2268 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike;
-
-import static android.net.ipsec.ike.IkeManager.getIkeLog;
-import static android.net.ipsec.ike.SaProposal.DH_GROUP_NONE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
-
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_IKE_AUTH;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.ExchangeType;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_USE_TRANSPORT_MODE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_CP;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_DELETE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_KE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NONCE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_SA;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_TS_INITIATOR;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_TS_RESPONDER;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_ESP;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.ResourceUnavailableException;
-import android.net.IpSecManager.SecurityParameterIndex;
-import android.net.IpSecManager.SpiUnavailableException;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionConfiguration;
-import android.net.ipsec.ike.ChildSessionOptions;
-import android.net.ipsec.ike.IkeTrafficSelector;
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.TunnelModeChildSessionOptions;
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeInternalException;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.os.Looper;
-import android.os.Message;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeExchangeSubType;
-import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecord;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidKeException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.exceptions.TemporaryFailureException;
-import com.android.internal.net.ipsec.ike.exceptions.TsUnacceptableException;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeDeletePayload;
-import com.android.internal.net.ipsec.ike.message.IkeKePayload;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeNoncePayload;
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NotifyType;
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.ChildProposal;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeTsPayload;
-import com.android.internal.util.State;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.security.GeneralSecurityException;
-import java.security.Provider;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * ChildSessionStateMachine tracks states and manages exchanges of this Child Session.
- *
- * <p>ChildSessionStateMachine has two types of states. One type are states where there is no
- * ongoing procedure affecting Child Session (non-procedure state), including Initial, Idle and
- * Receiving. All other states are "procedure" states which are named as follows:
- *
- * <pre>
- * State Name = [Procedure Type] + [Exchange Initiator] + [Exchange Type].
- * - An IKE procedure consists of one or two IKE exchanges:
- *      Procedure Type = {CreateChild | DeleteChild | Info | RekeyChild | SimulRekeyChild}.
- * - Exchange Initiator indicates whether local or remote peer is the exchange initiator:
- *      Exchange Initiator = {Local | Remote}
- * - Exchange type defines the function of this exchange.
- *      Exchange Type = {Create | Delete}
- * </pre>
- */
-public class ChildSessionStateMachine extends AbstractSessionStateMachine {
-    private static final String TAG = "ChildSessionStateMachine";
-
-    private static final int SPI_NOT_REGISTERED = 0;
-
-    // Time after which Child SA needs to be rekeyed
-    @VisibleForTesting static final long SA_SOFT_LIFETIME_MS = TimeUnit.HOURS.toMillis(2L);
-
-    private static final int CMD_GENERAL_BASE = CMD_PRIVATE_BASE;
-
-    /** Receive request for negotiating first Child SA. */
-    private static final int CMD_HANDLE_FIRST_CHILD_EXCHANGE = CMD_GENERAL_BASE + 1;
-    /** Receive a request from the remote. */
-    private static final int CMD_HANDLE_RECEIVED_REQUEST = CMD_GENERAL_BASE + 2;
-    /** Receive a reponse from the remote. */
-    private static final int CMD_HANDLE_RECEIVED_RESPONSE = CMD_GENERAL_BASE + 3;
-    /** Kill Session and close all alive Child SAs immediately. */
-    private static final int CMD_KILL_SESSION = CMD_GENERAL_BASE + 4;
-
-    private static final SparseArray<String> CMD_TO_STR;
-
-    static {
-        CMD_TO_STR = new SparseArray<>();
-        CMD_TO_STR.put(CMD_HANDLE_FIRST_CHILD_EXCHANGE, "Handle First Child");
-        CMD_TO_STR.put(CMD_HANDLE_RECEIVED_REQUEST, "Rcv request");
-        CMD_TO_STR.put(CMD_HANDLE_RECEIVED_RESPONSE, "Rcv response");
-        CMD_TO_STR.put(CMD_KILL_SESSION, "Kill session");
-    }
-
-    private final Context mContext;
-    private final IpSecManager mIpSecManager;
-
-    /** User provided configurations. */
-    private final ChildSessionOptions mChildSessionOptions;
-
-    private final Executor mUserCbExecutor;
-    private final ChildSessionCallback mUserCallback;
-
-    /** Callback to notify IKE Session the state changes. */
-    private final IChildSessionSmCallback mChildSmCallback;
-
-    // TODO: Also store ChildSessionCallback for notifying users.
-
-    /** Local address assigned on device. */
-    @VisibleForTesting InetAddress mLocalAddress;
-    /** Remote address configured by users. */
-    @VisibleForTesting InetAddress mRemoteAddress;
-
-    /**
-     * UDP-Encapsulated socket that allows IPsec traffic to pass through a NAT. Null if UDP
-     * encapsulation is not needed.
-     */
-    @VisibleForTesting @Nullable UdpEncapsulationSocket mUdpEncapSocket;
-
-    /** Crypto parameters. Updated upon initial negotiation or IKE SA rekey. */
-    @VisibleForTesting IkeMacPrf mIkePrf;
-
-    @VisibleForTesting byte[] mSkD;
-
-    /** Package private ChildSaProposal that represents the negotiated Child SA proposal. */
-    @VisibleForTesting ChildSaProposal mSaProposal;
-
-    /** Negotiated local Traffic Selector. */
-    @VisibleForTesting IkeTrafficSelector[] mLocalTs;
-    /** Negotiated remote Traffic Selector. */
-    @VisibleForTesting IkeTrafficSelector[] mRemoteTs;
-
-    @VisibleForTesting IkeCipher mChildCipher;
-    @VisibleForTesting IkeMacIntegrity mChildIntegrity;
-
-    /** Package private */
-    @VisibleForTesting ChildSaRecord mCurrentChildSaRecord;
-    /** Package private */
-    @VisibleForTesting ChildSaRecord mLocalInitNewChildSaRecord;
-    /** Package private */
-    @VisibleForTesting ChildSaRecord mRemoteInitNewChildSaRecord;
-
-    /** Package private */
-    @VisibleForTesting ChildSaRecord mChildSaRecordSurviving;
-
-    @VisibleForTesting final State mKillChildSessionParent = new KillChildSessionParent();
-
-    @VisibleForTesting final State mInitial = new Initial();
-    @VisibleForTesting final State mCreateChildLocalCreate = new CreateChildLocalCreate();
-    @VisibleForTesting final State mIdle = new Idle();
-    @VisibleForTesting final State mDeleteChildLocalDelete = new DeleteChildLocalDelete();
-    @VisibleForTesting final State mDeleteChildRemoteDelete = new DeleteChildRemoteDelete();
-    @VisibleForTesting final State mRekeyChildLocalCreate = new RekeyChildLocalCreate();
-    @VisibleForTesting final State mRekeyChildRemoteCreate = new RekeyChildRemoteCreate();
-    @VisibleForTesting final State mRekeyChildLocalDelete = new RekeyChildLocalDelete();
-    @VisibleForTesting final State mRekeyChildRemoteDelete = new RekeyChildRemoteDelete();
-
-    /**
-     * Builds a new uninitialized ChildSessionStateMachine
-     *
-     * <p>Upon creation, this state machine will await either the handleFirstChildExchange
-     * (IKE_AUTH), or the createChildSession (Additional child creation beyond the first child) to
-     * be called, both of which must pass keying and SA information.
-     *
-     * <p>This two-stage initialization is required to allow race-free user interaction with the IKE
-     * Session keyed on the child state machine callbacks.
-     *
-     * <p>Package private
-     */
-    ChildSessionStateMachine(
-            Looper looper,
-            Context context,
-            IpSecManager ipSecManager,
-            ChildSessionOptions sessionOptions,
-            Executor userCbExecutor,
-            ChildSessionCallback userCallback,
-            IChildSessionSmCallback childSmCallback) {
-        super(TAG, looper);
-
-        mContext = context;
-        mIpSecManager = ipSecManager;
-        mChildSessionOptions = sessionOptions;
-
-        mUserCbExecutor = userCbExecutor;
-        mUserCallback = userCallback;
-        mChildSmCallback = childSmCallback;
-
-        addState(mKillChildSessionParent);
-
-        addState(mInitial, mKillChildSessionParent);
-        addState(mCreateChildLocalCreate, mKillChildSessionParent);
-        addState(mIdle, mKillChildSessionParent);
-        addState(mDeleteChildLocalDelete, mKillChildSessionParent);
-        addState(mDeleteChildRemoteDelete, mKillChildSessionParent);
-        addState(mRekeyChildLocalCreate, mKillChildSessionParent);
-        addState(mRekeyChildRemoteCreate, mKillChildSessionParent);
-        addState(mRekeyChildLocalDelete, mKillChildSessionParent);
-        addState(mRekeyChildRemoteDelete, mKillChildSessionParent);
-
-        setInitialState(mInitial);
-    }
-
-    /**
-     * Interface for ChildSessionStateMachine to notify IkeSessionStateMachine of state changes.
-     *
-     * <p>Child Session may encounter an IKE Session fatal error in three cases with different
-     * handling rules:
-     *
-     * <pre>
-     * - When there is a fatal error in an inbound request, onOutboundPayloadsReady will be
-     *   called first to send out an error notification and then onFatalIkeSessionError(false)
-     *   will be called to locally close the IKE Session.
-     * - When there is a fatal error in an inbound response, only onFatalIkeSessionError(true)
-     *   will be called to notify the remote with a Delete request and then close the IKE Session.
-     * - When there is an fatal error notification in an inbound response, only
-     *   onFatalIkeSessionError(false) is called to close the IKE Session locally.
-     * </pre>
-     *
-     * <p>Package private.
-     */
-    interface IChildSessionSmCallback {
-        /** Notify that new Child SA is created. */
-        void onChildSaCreated(int remoteSpi, ChildSessionStateMachine childSession);
-
-        /** Notify that a Child SA is deleted. */
-        void onChildSaDeleted(int remoteSpi);
-
-        /** Schedule a future Child Rekey Request on the LocalRequestScheduler. */
-        void scheduleLocalRequest(ChildLocalRequest futureRequest, long delayedTime);
-
-        /** Schedule retry for a Child Rekey Request on the LocalRequestScheduler. */
-        void scheduleRetryLocalRequest(ChildLocalRequest futureRequest);
-
-        /** Notify the IKE Session to send out IKE message for this Child Session. */
-        void onOutboundPayloadsReady(
-                @ExchangeType int exchangeType,
-                boolean isResp,
-                List<IkePayload> payloadList,
-                ChildSessionStateMachine childSession);
-
-        /** Notify that a Child procedure has been finished. */
-        void onProcedureFinished(ChildSessionStateMachine childSession);
-
-        /**
-         * Notify the IKE Session State Machine that this Child has been fully shut down.
-         *
-         * <p>This method MUST be called after the user callbacks have been fired, and MUST always
-         * be called before the state machine can shut down.
-         */
-        void onChildSessionClosed(ChildSessionCallback userCallbacks);
-
-        /**
-         * Notify that a Child procedure has been finished and the IKE Session should close itself
-         * because of a fatal error.
-         *
-         * <p>The IKE Session should send a Delete IKE request before closing when needsNotifyRemote
-         * is true.
-         */
-        void onFatalIkeSessionError(boolean needsNotifyRemote);
-    }
-
-    /**
-     * Receive requesting and responding payloads for negotiating first Child SA.
-     *
-     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
-     * as an asynchronous job to the ChildStateMachine handler.
-     *
-     * @param reqPayloads SA negotiation related payloads in IKE_AUTH request.
-     * @param respPayloads SA negotiation related payloads in IKE_AUTH response.
-     * @param localAddress The local (outer) address of the Child Session.
-     * @param remoteAddress The remote (outer) address of the Child Session.
-     * @param udpEncapSocket The socket to use for UDP encapsulation, or NULL if no encap needed.
-     * @param ikePrf The pseudo-random function to use for key derivation
-     * @param skD The key for which to derive new keying information from.
-     */
-    public void handleFirstChildExchange(
-            List<IkePayload> reqPayloads,
-            List<IkePayload> respPayloads,
-            InetAddress localAddress,
-            InetAddress remoteAddress,
-            UdpEncapsulationSocket udpEncapSocket,
-            IkeMacPrf ikePrf,
-            byte[] skD) {
-
-        this.mLocalAddress = localAddress;
-        this.mRemoteAddress = remoteAddress;
-        this.mUdpEncapSocket = udpEncapSocket;
-        this.mIkePrf = ikePrf;
-        this.mSkD = skD;
-
-        int spi = registerProvisionalChildAndGetSpi(respPayloads);
-        sendMessage(
-                CMD_HANDLE_FIRST_CHILD_EXCHANGE,
-                new FirstChildNegotiationData(reqPayloads, respPayloads, spi));
-    }
-
-    /**
-     * Initiate Create Child procedure.
-     *
-     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
-     * as an asynchronous job to the ChildStateMachine handler.
-     *
-     * @param localAddress The local (outer) address from which traffic will originate.
-     * @param remoteAddress The remote (outer) address to which traffic will be sent.
-     * @param udpEncapSocket The socket to use for UDP encapsulation, or NULL if no encap needed.
-     * @param ikePrf The pseudo-random function to use for key derivation
-     * @param skD The key for which to derive new keying information from.
-     */
-    public void createChildSession(
-            InetAddress localAddress,
-            InetAddress remoteAddress,
-            UdpEncapsulationSocket udpEncapSocket,
-            IkeMacPrf ikePrf,
-            byte[] skD) {
-        this.mLocalAddress = localAddress;
-        this.mRemoteAddress = remoteAddress;
-        this.mUdpEncapSocket = udpEncapSocket;
-        this.mIkePrf = ikePrf;
-        this.mSkD = skD;
-
-        sendMessage(CMD_LOCAL_REQUEST_CREATE_CHILD);
-    }
-
-    /**
-     * Initiate Delete Child procedure.
-     *
-     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
-     * as an asynchronous job to the ChildStateMachine handler.
-     */
-    public void deleteChildSession() {
-        sendMessage(CMD_LOCAL_REQUEST_DELETE_CHILD);
-    }
-
-    /**
-     * Initiate Rekey Child procedure.
-     *
-     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
-     * as an asynchronous job to the ChildStateMachine handler.
-     */
-    public void rekeyChildSession() {
-        sendMessage(CMD_LOCAL_REQUEST_REKEY_CHILD);
-    }
-
-    /**
-     * Kill Child Session and all alive Child SAs without doing IKE exchange.
-     *
-     * <p>It is usually called when IKE Session is being closed.
-     */
-    public void killSession() {
-        sendMessage(CMD_KILL_SESSION);
-    }
-
-    private ChildLocalRequest makeRekeyLocalRequest() {
-        return new ChildLocalRequest(
-                CMD_LOCAL_REQUEST_REKEY_CHILD, mUserCallback, null /*childOptions*/);
-    }
-
-    private long getRekeyTimeout() {
-        // TODO: Make rekey timout fuzzy
-        return SA_SOFT_LIFETIME_MS;
-    }
-
-    /**
-     * Receive a request
-     *
-     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
-     * as an asynchronous job to the ChildStateMachine handler.
-     *
-     * @param exchangeSubtype the exchange subtype of this inbound request.
-     * @param exchangeType the exchange type in the request message.
-     * @param payloadList the Child-procedure-related payload list in the request message that needs
-     *     validation.
-     */
-    public void receiveRequest(
-            @IkeExchangeSubType int exchangeSubtype,
-            @ExchangeType int exchangeType,
-            List<IkePayload> payloadList) {
-        sendMessage(
-                CMD_HANDLE_RECEIVED_REQUEST,
-                new ReceivedRequest(exchangeSubtype, exchangeType, payloadList));
-    }
-
-    /**
-     * Receive a response.
-     *
-     * <p>This method is called synchronously from IkeStateMachine. It proxies the synchronous call
-     * as an asynchronous job to the ChildStateMachine handler.
-     *
-     * @param exchangeType the exchange type in the response message that needs validation.
-     * @param payloadList the Child-procedure-related payload list in the response message that
-     *     needs validation.
-     */
-    public void receiveResponse(@ExchangeType int exchangeType, List<IkePayload> payloadList) {
-        if (!isAwaitingCreateResp()) {
-            sendMessage(
-                    CMD_HANDLE_RECEIVED_RESPONSE, new ReceivedResponse(exchangeType, payloadList));
-        }
-
-        // If we are waiting for a Create/RekeyCreate response and the received message contains SA
-        // payload we need to register for this provisional Child.
-        int spi = registerProvisionalChildAndGetSpi(payloadList);
-        sendMessage(
-                CMD_HANDLE_RECEIVED_RESPONSE,
-                new ReceivedCreateResponse(exchangeType, payloadList, spi));
-    }
-
-    private boolean isAwaitingCreateResp() {
-        return (getCurrentState() == mCreateChildLocalCreate
-                || getCurrentState() == mRekeyChildLocalCreate);
-    }
-
-    /**
-     * Update SK_d with provided value when IKE SA is rekeyed.
-     *
-     * <p>It MUST be only called at the end of Rekey IKE procedure, which guarantees this Child
-     * Session is not in Create Child or Rekey Child procedure.
-     *
-     * @param skD the new skD in byte array.
-     */
-    public void setSkD(byte[] skD) {
-        mSkD = skD;
-    }
-
-    /**
-     * Register provisioning ChildSessionStateMachine in IChildSessionSmCallback
-     *
-     * <p>This method is for avoiding CHILD_SA_NOT_FOUND error in IkeSessionStateMachine when remote
-     * peer sends request for delete/rekey this Child SA before ChildSessionStateMachine sends
-     * FirstChildNegotiationData or Create response to itself.
-     */
-    private int registerProvisionalChildAndGetSpi(List<IkePayload> respPayloads) {
-        IkeSaPayload saPayload =
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_SA, IkeSaPayload.class, respPayloads);
-
-        if (saPayload == null) return SPI_NOT_REGISTERED;
-
-        // IkeSaPayload.Proposal stores SPI in long type so as to be applied to both 8-byte IKE SPI
-        // and 4-byte Child SPI. Here we cast the stored SPI to int to represent a Child SPI.
-        int remoteGenSpi = (int) (saPayload.proposalList.get(0).spi);
-        mChildSmCallback.onChildSaCreated(remoteGenSpi, this);
-        return remoteGenSpi;
-    }
-
-    private void replyErrorNotification(@NotifyType int notifyType) {
-        replyErrorNotification(notifyType, new byte[0]);
-    }
-
-    private void replyErrorNotification(@NotifyType int notifyType, byte[] notifyData) {
-        List<IkePayload> outPayloads = new ArrayList<>(1);
-        IkeNotifyPayload notifyPayload = new IkeNotifyPayload(notifyType, notifyData);
-        outPayloads.add(notifyPayload);
-
-        mChildSmCallback.onOutboundPayloadsReady(
-                EXCHANGE_TYPE_INFORMATIONAL, true /*isResp*/, outPayloads, this);
-    }
-
-    /** Notify users the deletion of a Child SA. MUST be called through mUserCbExecutor */
-    private void onIpSecTransformPairDeleted(ChildSaRecord childSaRecord) {
-        mUserCallback.onIpSecTransformDeleted(
-                childSaRecord.getOutboundIpSecTransform(), IpSecManager.DIRECTION_OUT);
-        mUserCallback.onIpSecTransformDeleted(
-                childSaRecord.getInboundIpSecTransform(), IpSecManager.DIRECTION_IN);
-    }
-
-    /**
-     * ReceivedRequest contains exchange subtype and payloads that are extracted from a request
-     * message to the current Child procedure.
-     */
-    private static class ReceivedRequest {
-        @IkeExchangeSubType public final int exchangeSubtype;
-        @ExchangeType public final int exchangeType;
-        public final List<IkePayload> requestPayloads;
-
-        ReceivedRequest(
-                @IkeExchangeSubType int eSubtype,
-                @ExchangeType int eType,
-                List<IkePayload> reqPayloads) {
-            exchangeSubtype = eSubtype;
-            exchangeType = eType;
-            requestPayloads = reqPayloads;
-        }
-    }
-
-    /**
-     * ReceivedResponse contains exchange type and payloads that are extracted from a response
-     * message to the current Child procedure.
-     */
-    private static class ReceivedResponse {
-        @ExchangeType public final int exchangeType;
-        public final List<IkePayload> responsePayloads;
-
-        ReceivedResponse(@ExchangeType int eType, List<IkePayload> respPayloads) {
-            exchangeType = eType;
-            responsePayloads = respPayloads;
-        }
-    }
-
-    private static class ReceivedCreateResponse extends ReceivedResponse {
-        public final int registeredSpi;
-
-        ReceivedCreateResponse(@ExchangeType int eType, List<IkePayload> respPayloads, int spi) {
-            super(eType, respPayloads);
-            registeredSpi = spi;
-        }
-    }
-
-    /**
-     * FirstChildNegotiationData contains payloads for negotiating first Child SA in IKE_AUTH
-     * request and IKE_AUTH response and callback to notify IkeSessionStateMachine the SA
-     * negotiation result.
-     */
-    private static class FirstChildNegotiationData extends ReceivedCreateResponse {
-        public final List<IkePayload> requestPayloads;
-
-        FirstChildNegotiationData(
-                List<IkePayload> reqPayloads, List<IkePayload> respPayloads, int spi) {
-            super(EXCHANGE_TYPE_IKE_AUTH, respPayloads, spi);
-            requestPayloads = reqPayloads;
-        }
-    }
-
-    /** Top level state for handling uncaught exceptions for all subclasses. */
-    abstract class ExceptionHandler extends ExceptionHandlerBase {
-        @Override
-        protected void cleanUpAndQuit(RuntimeException e) {
-            // TODO: b/140123526 Send a response if exception was caught when processing a request.
-
-            // Clean up all SaRecords.
-            closeAllSaRecords(false /*expectSaClosed*/);
-
-            mUserCbExecutor.execute(
-                    () -> {
-                        mUserCallback.onClosedExceptionally(new IkeInternalException(e));
-                    });
-            logWtf("Unexpected exception in " + getCurrentState().getName(), e);
-            quitNow();
-        }
-
-        @Override
-        protected String getCmdString(int cmd) {
-            return CMD_TO_STR.get(cmd);
-        }
-    }
-
-    /** Called when this StateMachine quits. */
-    @Override
-    protected void onQuitting() {
-        // Clean up all SaRecords.
-        closeAllSaRecords(true /*expectSaClosed*/);
-
-        mChildSmCallback.onProcedureFinished(this);
-        mChildSmCallback.onChildSessionClosed(mUserCallback);
-    }
-
-    private void closeAllSaRecords(boolean expectSaClosed) {
-        closeChildSaRecord(mCurrentChildSaRecord, expectSaClosed);
-        closeChildSaRecord(mLocalInitNewChildSaRecord, expectSaClosed);
-        closeChildSaRecord(mRemoteInitNewChildSaRecord, expectSaClosed);
-
-        mCurrentChildSaRecord = null;
-        mLocalInitNewChildSaRecord = null;
-        mRemoteInitNewChildSaRecord = null;
-    }
-
-    private void closeChildSaRecord(ChildSaRecord childSaRecord, boolean expectSaClosed) {
-        if (childSaRecord == null) return;
-
-        mUserCbExecutor.execute(
-                () -> {
-                    onIpSecTransformPairDeleted(childSaRecord);
-                });
-
-        mChildSmCallback.onChildSaDeleted(childSaRecord.getRemoteSpi());
-        childSaRecord.close();
-
-        if (!expectSaClosed) return;
-
-        logWtf(
-                "ChildSaRecord with local SPI: "
-                        + childSaRecord.getLocalSpi()
-                        + " is not correctly closed.");
-    }
-
-    private void handleChildFatalError(Exception error) {
-        IkeException ikeException =
-                error instanceof IkeException
-                        ? (IkeException) error
-                        : new IkeInternalException(error);
-
-        mUserCbExecutor.execute(
-                () -> {
-                    mUserCallback.onClosedExceptionally(ikeException);
-                });
-        loge("Child Session fatal error", ikeException);
-
-        // Clean up all SaRecords and quit
-        closeAllSaRecords(false /*expectSaClosed*/);
-        quitNow();
-    }
-
-    /**
-     * This state handles the request to close Child Session immediately without initiating any
-     * exchange.
-     *
-     * <p>Request for closing Child Session immediately is usually caused by the closing of IKE
-     * Session. All states MUST be a child state of KillChildSessionParent to handle the closing
-     * request.
-     */
-    private class KillChildSessionParent extends ExceptionHandler {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_KILL_SESSION:
-                    mUserCbExecutor.execute(
-                            () -> {
-                                mUserCallback.onClosed();
-                            });
-
-                    closeAllSaRecords(false /*expectSaClosed*/);
-
-                    quitNow();
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * CreateChildLocalCreateBase represents the common information for a locally-initiated initial
-     * Child SA negotiation for setting up this Child Session.
-     */
-    private abstract class CreateChildLocalCreateBase extends ExceptionHandler {
-        protected void validateAndBuildChild(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                @ExchangeType int exchangeType,
-                @ExchangeType int expectedExchangeType,
-                int registeredSpi) {
-            CreateChildResult createChildResult =
-                    CreateChildSaHelper.validateAndNegotiateInitChild(
-                            reqPayloads,
-                            respPayloads,
-                            exchangeType,
-                            expectedExchangeType,
-                            mChildSessionOptions.isTransportMode(),
-                            mIpSecManager,
-                            mRemoteAddress);
-            switch (createChildResult.status) {
-                case CREATE_STATUS_OK:
-                    try {
-                        setUpNegotiatedResult(createChildResult);
-
-                        ChildLocalRequest rekeyLocalRequest = makeRekeyLocalRequest();
-
-                        mCurrentChildSaRecord =
-                                ChildSaRecord.makeChildSaRecord(
-                                        mContext,
-                                        reqPayloads,
-                                        respPayloads,
-                                        createChildResult.initSpi,
-                                        createChildResult.respSpi,
-                                        mLocalAddress,
-                                        mRemoteAddress,
-                                        mUdpEncapSocket,
-                                        mIkePrf,
-                                        mChildIntegrity,
-                                        mChildCipher,
-                                        mSkD,
-                                        mChildSessionOptions.isTransportMode(),
-                                        true /*isLocalInit*/,
-                                        rekeyLocalRequest);
-
-                        mChildSmCallback.scheduleLocalRequest(rekeyLocalRequest, getRekeyTimeout());
-
-                        ChildSessionConfiguration sessionConfig =
-                                buildChildSessionConfigFromResp(createChildResult, respPayloads);
-                        mUserCbExecutor.execute(
-                                () -> {
-                                    mUserCallback.onIpSecTransformCreated(
-                                            mCurrentChildSaRecord.getInboundIpSecTransform(),
-                                            IpSecManager.DIRECTION_IN);
-                                    mUserCallback.onIpSecTransformCreated(
-                                            mCurrentChildSaRecord.getOutboundIpSecTransform(),
-                                            IpSecManager.DIRECTION_OUT);
-                                    mUserCallback.onOpened(sessionConfig);
-                                });
-
-                        transitionTo(mIdle);
-                    } catch (GeneralSecurityException
-                            | ResourceUnavailableException
-                            | SpiUnavailableException
-                            | IOException e) {
-                        // #makeChildSaRecord failed.
-
-                        // TODO: Initiate deletion
-                        mChildSmCallback.onChildSaDeleted(createChildResult.respSpi.getSpi());
-                        createChildResult.initSpi.close();
-                        createChildResult.respSpi.close();
-                        handleChildFatalError(e);
-                    }
-                    break;
-                case CREATE_STATUS_CHILD_ERROR_INVALID_MSG:
-                    // TODO: Initiate deletion
-                    handleCreationFailAndQuit(registeredSpi, createChildResult.exception);
-                    break;
-                case CREATE_STATUS_CHILD_ERROR_RCV_NOTIFY:
-                    handleCreationFailAndQuit(registeredSpi, createChildResult.exception);
-                    break;
-                default:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Unrecognized status: " + createChildResult.status));
-            }
-        }
-
-        private void setUpNegotiatedResult(CreateChildResult createChildResult) {
-            // Build crypto tools using negotiated ChildSaProposal. It is ensured by {@link
-            // IkeSaPayload#getVerifiedNegotiatedChildProposalPair} that the negotiated
-            // ChildSaProposal is valid. The negotiated ChildSaProposal has exactly one encryption
-            // algorithm. When it has a combined-mode encryption algorithm, it either does not have
-            // integrity algorithm or only has one NONE value integrity algorithm. When the
-            // negotiated ChildSaProposal has a normal encryption algorithm, it either does not have
-            // integrity algorithm or has one integrity algorithm with any supported value.
-
-            mSaProposal = createChildResult.negotiatedProposal;
-            Provider provider = IkeMessage.getSecurityProvider();
-            mChildCipher = IkeCipher.create(mSaProposal.getEncryptionTransforms()[0], provider);
-            if (mSaProposal.getIntegrityTransforms().length != 0
-                    && mSaProposal.getIntegrityTransforms()[0].id
-                            != SaProposal.INTEGRITY_ALGORITHM_NONE) {
-                mChildIntegrity =
-                        IkeMacIntegrity.create(mSaProposal.getIntegrityTransforms()[0], provider);
-            }
-
-            mLocalTs = createChildResult.initTs;
-            mRemoteTs = createChildResult.respTs;
-        }
-
-        private ChildSessionConfiguration buildChildSessionConfigFromResp(
-                CreateChildResult createChildResult, List<IkePayload> respPayloads) {
-            IkeConfigPayload configPayload =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                            PAYLOAD_TYPE_CP, IkeConfigPayload.class, respPayloads);
-
-            if (mChildSessionOptions.isTransportMode()
-                    || configPayload == null
-                    || configPayload.configType != IkeConfigPayload.CONFIG_TYPE_REPLY) {
-                if (configPayload != null) {
-                    logw("Unexpected config payload. Config Type: " + configPayload.configType);
-                }
-
-                return new ChildSessionConfiguration(
-                        Arrays.asList(createChildResult.initTs),
-                        Arrays.asList(createChildResult.respTs));
-            } else {
-                return new ChildSessionConfiguration(
-                        Arrays.asList(createChildResult.initTs),
-                        Arrays.asList(createChildResult.respTs),
-                        configPayload);
-            }
-        }
-
-        private void handleCreationFailAndQuit(int registeredSpi, IkeException exception) {
-            if (registeredSpi != SPI_NOT_REGISTERED) {
-                mChildSmCallback.onChildSaDeleted(registeredSpi);
-            }
-            handleChildFatalError(exception);
-        }
-    }
-
-    /** Initial state of ChildSessionStateMachine. */
-    class Initial extends CreateChildLocalCreateBase {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_FIRST_CHILD_EXCHANGE:
-                    FirstChildNegotiationData childNegotiationData =
-                            (FirstChildNegotiationData) message.obj;
-                    List<IkePayload> reqPayloads = childNegotiationData.requestPayloads;
-                    List<IkePayload> respPayloads = childNegotiationData.responsePayloads;
-
-                    // Negotiate Child SA. The exchangeType has been validated in
-                    // IkeSessionStateMachine. Won't validate it again here.
-                    validateAndBuildChild(
-                            reqPayloads,
-                            respPayloads,
-                            EXCHANGE_TYPE_IKE_AUTH,
-                            EXCHANGE_TYPE_IKE_AUTH,
-                            childNegotiationData.registeredSpi);
-
-                    return HANDLED;
-                case CMD_LOCAL_REQUEST_CREATE_CHILD:
-                    transitionTo(mCreateChildLocalCreate);
-                    return HANDLED;
-                case CMD_LOCAL_REQUEST_DELETE_CHILD:
-                    // This may happen when creation has been rescheduled to be after deletion.
-                    mUserCbExecutor.execute(
-                            () -> {
-                                mUserCallback.onClosed();
-                            });
-                    quitNow();
-                    return HANDLED;
-                case CMD_FORCE_TRANSITION:
-                    transitionTo((State) message.obj);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * CreateChildLocalCreate represents the state where Child Session initiates the Create Child
-     * exchange.
-     */
-    class CreateChildLocalCreate extends CreateChildLocalCreateBase {
-        private List<IkePayload> mRequestPayloads;
-
-        @Override
-        public void enterState() {
-            try {
-                mRequestPayloads =
-                        CreateChildSaHelper.getInitChildCreateReqPayloads(
-                                mIpSecManager,
-                                mLocalAddress,
-                                mChildSessionOptions,
-                                false /*isFirstChild*/);
-                mChildSmCallback.onOutboundPayloadsReady(
-                        EXCHANGE_TYPE_CREATE_CHILD_SA,
-                        false /*isResp*/,
-                        mRequestPayloads,
-                        ChildSessionStateMachine.this);
-            } catch (ResourceUnavailableException e) {
-                // Fail to assign SPI
-                handleChildFatalError(e);
-            }
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_RESPONSE:
-                    ReceivedCreateResponse rcvResp = (ReceivedCreateResponse) message.obj;
-                    validateAndBuildChild(
-                            mRequestPayloads,
-                            rcvResp.responsePayloads,
-                            rcvResp.exchangeType,
-                            EXCHANGE_TYPE_CREATE_CHILD_SA,
-                            rcvResp.registeredSpi);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * Idle represents a state when there is no ongoing IKE exchange affecting established Child SA.
-     */
-    class Idle extends ExceptionHandler {
-        @Override
-        public void enterState() {
-            mChildSmCallback.onProcedureFinished(ChildSessionStateMachine.this);
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_LOCAL_REQUEST_DELETE_CHILD:
-                    transitionTo(mDeleteChildLocalDelete);
-                    return HANDLED;
-                case CMD_LOCAL_REQUEST_REKEY_CHILD:
-                    transitionTo(mRekeyChildLocalCreate);
-                    return HANDLED;
-                case CMD_HANDLE_RECEIVED_REQUEST:
-                    ReceivedRequest req = (ReceivedRequest) message.obj;
-                    switch (req.exchangeSubtype) {
-                        case IKE_EXCHANGE_SUBTYPE_DELETE_CHILD:
-                            deferMessage(message);
-                            transitionTo(mDeleteChildRemoteDelete);
-                            return HANDLED;
-                        case IKE_EXCHANGE_SUBTYPE_REKEY_CHILD:
-                            deferMessage(message);
-                            transitionTo(mRekeyChildRemoteCreate);
-                            return HANDLED;
-                        default:
-                            return NOT_HANDLED;
-                    }
-                case CMD_FORCE_TRANSITION: // Testing command
-                    transitionTo((State) message.obj);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * DeleteResponderBase represents all states after Child Session is established
-     *
-     * <p>All post-init states share common functionality of being able to respond to Delete Child
-     * requests.
-     */
-    private abstract class DeleteResponderBase extends ExceptionHandler {
-        /**
-         * Check if the payload list has a Delete Payload that includes the remote SPI of the input
-         * ChildSaRecord.
-         */
-        protected boolean hasRemoteChildSpiForDelete(
-                List<IkePayload> payloads, ChildSaRecord expectedRecord) {
-            List<IkeDeletePayload> delPayloads =
-                    IkePayload.getPayloadListForTypeInProvidedList(
-                            PAYLOAD_TYPE_DELETE, IkeDeletePayload.class, payloads);
-
-            for (IkeDeletePayload delPayload : delPayloads) {
-                for (int spi : delPayload.spisToDelete) {
-                    if (spi == expectedRecord.getRemoteSpi()) return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Build and send payload list that has a Delete Payload that includes the local SPI of the
-         * input ChildSaRecord.
-         */
-        protected void sendDeleteChild(ChildSaRecord childSaRecord, boolean isResp) {
-            List<IkePayload> outIkePayloads = new ArrayList<>(1);
-            outIkePayloads.add(new IkeDeletePayload(new int[] {childSaRecord.getLocalSpi()}));
-
-            mChildSmCallback.onOutboundPayloadsReady(
-                    EXCHANGE_TYPE_INFORMATIONAL,
-                    isResp,
-                    outIkePayloads,
-                    ChildSessionStateMachine.this);
-        }
-
-        /**
-         * Helper method for responding to a session deletion request
-         *
-         * <p>Note that this method expects that the session is keyed on the mCurrentChildSaRecord
-         * and closing this Child SA indicates that the remote wishes to end the session as a whole.
-         * As such, this should not be used in rekey cases where there is any ambiguity as to which
-         * Child SA the session is reliant upon.
-         *
-         * <p>Note that this method will also quit the state machine
-         */
-        protected void handleDeleteSessionRequest(List<IkePayload> payloads) {
-            if (!hasRemoteChildSpiForDelete(payloads, mCurrentChildSaRecord)) {
-                cleanUpAndQuit(
-                        new IllegalStateException(
-                                "Found no remote SPI for mCurrentChildSaRecord in a Delete Child"
-                                        + " request."));
-            } else {
-
-                mUserCbExecutor.execute(
-                        () -> {
-                            mUserCallback.onClosed();
-                            onIpSecTransformPairDeleted(mCurrentChildSaRecord);
-                        });
-
-                sendDeleteChild(mCurrentChildSaRecord, true /*isResp*/);
-
-                mChildSmCallback.onChildSaDeleted(mCurrentChildSaRecord.getRemoteSpi());
-                mCurrentChildSaRecord.close();
-                mCurrentChildSaRecord = null;
-
-                quitNow();
-            }
-        }
-    }
-
-    /**
-     * DeleteBase abstracts deletion handling for all states initiating and responding to a Delete
-     * Child exchange
-     *
-     * <p>All subclasses of this state share common functionality that a deletion request is sent,
-     * and the response is received.
-     */
-    private abstract class DeleteBase extends DeleteResponderBase {
-        /** Validate payload types in Delete Child response. */
-        protected void validateDeleteRespPayloadAndExchangeType(
-                List<IkePayload> respPayloads, @ExchangeType int exchangeType)
-                throws IkeProtocolException {
-
-            if (exchangeType != EXCHANGE_TYPE_INFORMATIONAL) {
-                throw new InvalidSyntaxException(
-                        "Unexpected exchange type in Delete Child response: " + exchangeType);
-            }
-
-            for (IkePayload payload : respPayloads) {
-                handlePayload:
-                switch (payload.payloadType) {
-                    case PAYLOAD_TYPE_DELETE:
-                        // A Delete Payload is only required when it is not simultaneous deletion.
-                        // Included Child SPIs are verified in the subclass to make sure the remote
-                        // side is deleting the right SAs.
-                        break handlePayload;
-                    case PAYLOAD_TYPE_NOTIFY:
-                        IkeNotifyPayload notify = (IkeNotifyPayload) payload;
-                        if (!notify.isErrorNotify()) {
-                            logw(
-                                    "Unexpected or unknown status notification in Delete Child"
-                                            + " response: "
-                                            + notify.notifyType);
-                            break handlePayload;
-                        }
-
-                        throw notify.validateAndBuildIkeException();
-                    default:
-                        logw(
-                                "Unexpected payload type in Delete Child response: "
-                                        + payload.payloadType);
-                }
-            }
-        }
-    }
-
-    /**
-     * DeleteChildLocalDelete represents the state where Child Session initiates the Delete Child
-     * exchange.
-     */
-    class DeleteChildLocalDelete extends DeleteBase {
-        private boolean mSimulDeleteDetected = false;
-
-        @Override
-        public void enterState() {
-            mSimulDeleteDetected = false;
-            sendDeleteChild(mCurrentChildSaRecord, false /*isResp*/);
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_RESPONSE:
-                    try {
-                        ReceivedResponse resp = (ReceivedResponse) message.obj;
-                        validateDeleteRespPayloadAndExchangeType(
-                                resp.responsePayloads, resp.exchangeType);
-
-                        boolean currentSaSpiFound =
-                                hasRemoteChildSpiForDelete(
-                                        resp.responsePayloads, mCurrentChildSaRecord);
-                        if (!currentSaSpiFound && !mSimulDeleteDetected) {
-                            throw new InvalidSyntaxException(
-                                    "Found no remote SPI in received Delete response.");
-                        } else if (currentSaSpiFound && mSimulDeleteDetected) {
-                            // As required by the RFC 7296, in simultaneous delete case, the remote
-                            // side MUST NOT include SPI of mCurrentChildSaRecord. However, to
-                            // provide better interoperatibility, IKE library will keep IKE Session
-                            // alive and continue the deleting process.
-                            logw(
-                                    "Found remote SPI in the Delete response in a simultaneous"
-                                            + " deletion case");
-                        }
-
-                        mUserCbExecutor.execute(
-                                () -> {
-                                    mUserCallback.onClosed();
-                                    onIpSecTransformPairDeleted(mCurrentChildSaRecord);
-                                });
-
-                        mChildSmCallback.onChildSaDeleted(mCurrentChildSaRecord.getRemoteSpi());
-                        mCurrentChildSaRecord.close();
-                        mCurrentChildSaRecord = null;
-
-                        quitNow();
-                    } catch (IkeProtocolException e) {
-                        // Shut down Child Session and notify users the error.
-                        handleChildFatalError(e);
-                    }
-                    return HANDLED;
-                case CMD_HANDLE_RECEIVED_REQUEST:
-                    ReceivedRequest req = (ReceivedRequest) message.obj;
-                    switch (req.exchangeSubtype) {
-                        case IKE_EXCHANGE_SUBTYPE_DELETE_CHILD:
-                            // It has been verified in IkeSessionStateMachine that the incoming
-                            // request can be ONLY for mCurrentChildSaRecord at this point.
-                            if (!hasRemoteChildSpiForDelete(
-                                    req.requestPayloads, mCurrentChildSaRecord)) {
-                                // Program error
-                                cleanUpAndQuit(
-                                        new IllegalStateException(
-                                                "Found no remote SPI for mCurrentChildSaRecord in"
-                                                        + " a Delete request"));
-
-                            } else {
-                                mChildSmCallback.onOutboundPayloadsReady(
-                                        EXCHANGE_TYPE_INFORMATIONAL,
-                                        true /*isResp*/,
-                                        new LinkedList<>(),
-                                        ChildSessionStateMachine.this);
-                                mSimulDeleteDetected = true;
-                            }
-                            return HANDLED;
-                        case IKE_EXCHANGE_SUBTYPE_REKEY_CHILD:
-                            replyErrorNotification(ERROR_TYPE_TEMPORARY_FAILURE);
-                            return HANDLED;
-                        default:
-                            cleanUpAndQuit(
-                                    new IllegalStateException(
-                                            "Invalid exchange subtype for Child Session: "
-                                                    + req.exchangeSubtype));
-                            return HANDLED;
-                    }
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * DeleteChildRemoteDelete represents the state where Child Session receives the Delete Child
-     * request.
-     */
-    class DeleteChildRemoteDelete extends DeleteResponderBase {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_REQUEST:
-                    ReceivedRequest req = (ReceivedRequest) message.obj;
-                    if (req.exchangeSubtype == IKE_EXCHANGE_SUBTYPE_DELETE_CHILD) {
-                        handleDeleteSessionRequest(req.requestPayloads);
-                        return HANDLED;
-                    }
-                    return NOT_HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * RekeyChildLocalCreate represents the state where Child Session initiates the Rekey Child
-     * exchange.
-     *
-     * <p>As indicated in RFC 7296 section 2.8, "when rekeying, the new Child SA SHOULD NOT have
-     * different Traffic Selectors and algorithms than the old one."
-     */
-    class RekeyChildLocalCreate extends DeleteResponderBase {
-        private List<IkePayload> mRequestPayloads;
-
-        @Override
-        public void enterState() {
-            try {
-                // Build request with negotiated proposal and TS.
-                mRequestPayloads =
-                        CreateChildSaHelper.getRekeyChildCreateReqPayloads(
-                                mIpSecManager,
-                                mLocalAddress,
-                                mSaProposal,
-                                mLocalTs,
-                                mRemoteTs,
-                                mCurrentChildSaRecord.getLocalSpi(),
-                                mChildSessionOptions.isTransportMode());
-                mChildSmCallback.onOutboundPayloadsReady(
-                        EXCHANGE_TYPE_CREATE_CHILD_SA,
-                        false /*isResp*/,
-                        mRequestPayloads,
-                        ChildSessionStateMachine.this);
-            } catch (ResourceUnavailableException e) {
-                loge("Fail to assign Child SPI. Schedule a retry for rekey Child");
-                mChildSmCallback.scheduleRetryLocalRequest(
-                        (ChildLocalRequest) mCurrentChildSaRecord.getFutureRekeyEvent());
-                transitionTo(mIdle);
-            }
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_RESPONSE:
-                    ReceivedCreateResponse resp = (ReceivedCreateResponse) message.obj;
-                    CreateChildResult createChildResult =
-                            CreateChildSaHelper.validateAndNegotiateRekeyChildResp(
-                                    mRequestPayloads,
-                                    resp.responsePayloads,
-                                    resp.exchangeType,
-                                    EXCHANGE_TYPE_CREATE_CHILD_SA,
-                                    mChildSessionOptions.isTransportMode(),
-                                    mCurrentChildSaRecord,
-                                    mIpSecManager,
-                                    mRemoteAddress);
-
-                    switch (createChildResult.status) {
-                        case CREATE_STATUS_OK:
-                            try {
-                                // Do not need to update the negotiated proposal and TS because they
-                                // are not changed.
-
-                                ChildLocalRequest rekeyLocalRequest = makeRekeyLocalRequest();
-
-                                mLocalInitNewChildSaRecord =
-                                        ChildSaRecord.makeChildSaRecord(
-                                                mContext,
-                                                mRequestPayloads,
-                                                resp.responsePayloads,
-                                                createChildResult.initSpi,
-                                                createChildResult.respSpi,
-                                                mLocalAddress,
-                                                mRemoteAddress,
-                                                mUdpEncapSocket,
-                                                mIkePrf,
-                                                mChildIntegrity,
-                                                mChildCipher,
-                                                mSkD,
-                                                mChildSessionOptions.isTransportMode(),
-                                                true /*isLocalInit*/,
-                                                rekeyLocalRequest);
-
-                                mChildSmCallback.scheduleLocalRequest(
-                                        rekeyLocalRequest, getRekeyTimeout());
-
-                                mUserCbExecutor.execute(
-                                        () -> {
-                                            mUserCallback.onIpSecTransformCreated(
-                                                    mLocalInitNewChildSaRecord
-                                                            .getInboundIpSecTransform(),
-                                                    IpSecManager.DIRECTION_IN);
-                                            mUserCallback.onIpSecTransformCreated(
-                                                    mLocalInitNewChildSaRecord
-                                                            .getOutboundIpSecTransform(),
-                                                    IpSecManager.DIRECTION_OUT);
-                                        });
-
-                                transitionTo(mRekeyChildLocalDelete);
-                            } catch (GeneralSecurityException
-                                    | ResourceUnavailableException
-                                    | SpiUnavailableException
-                                    | IOException e) {
-                                // #makeChildSaRecord failed
-                                handleProcessRespOrSaCreationFailAndQuit(resp.registeredSpi, e);
-                                createChildResult.initSpi.close();
-                                createChildResult.respSpi.close();
-                            }
-                            break;
-                        case CREATE_STATUS_CHILD_ERROR_INVALID_MSG:
-                            handleProcessRespOrSaCreationFailAndQuit(
-                                    resp.registeredSpi, createChildResult.exception);
-                            break;
-                        case CREATE_STATUS_CHILD_ERROR_RCV_NOTIFY:
-                            if (createChildResult.exception instanceof TemporaryFailureException) {
-                                loge(
-                                        "Received TEMPORARY_FAILURE for rekey Child. Retry has"
-                                                + "already been scheduled by IKE Session.");
-                            } else {
-                                loge(
-                                        "Received error notification for rekey Child. Schedule a"
-                                                + " retry");
-                                mChildSmCallback.scheduleRetryLocalRequest(
-                                        (ChildLocalRequest)
-                                                mCurrentChildSaRecord.getFutureRekeyEvent());
-                            }
-
-                            transitionTo(mIdle);
-                            break;
-                        default:
-                            cleanUpAndQuit(
-                                    new IllegalStateException(
-                                            "Unrecognized status: " + createChildResult.status));
-                    }
-                    return HANDLED;
-                default:
-                    // TODO: Handle rekey and delete request
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void handleProcessRespOrSaCreationFailAndQuit(
-                int registeredSpi, Exception exception) {
-            // We don't retry rekey if failure was caused by invalid response or SA creation error.
-            // Reason is there is no way to notify the remote side the old SA is still alive but the
-            // new one has failed. Sending delete request for new SA indicates the rekey has
-            // finished and the new SA has died.
-
-            // TODO: Initiate deletion on newly created SA
-            if (registeredSpi != SPI_NOT_REGISTERED) {
-                mChildSmCallback.onChildSaDeleted(registeredSpi);
-            }
-            handleChildFatalError(exception);
-        }
-    }
-
-    /**
-     * RekeyChildRemoteCreate represents the state where Child Session receives a Rekey Child
-     * request.
-     *
-     * <p>As indicated in RFC 7296 section 2.8, "when rekeying, the new Child SA SHOULD NOT have
-     * different Traffic Selectors and algorithms than the old one."
-     *
-     * <p>Errors in this exchange with no specific protocol error code will all be classified to use
-     * NO_PROPOSAL_CHOSEN. The reason that we don't use NO_ADDITIONAL_SAS is because it indicates
-     * "responder is unwilling to accept any more Child SAs on this IKE SA.", according to RFC 7296.
-     * Sending this error may mislead the remote peer.
-     */
-    class RekeyChildRemoteCreate extends ExceptionHandler {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_REQUEST:
-                    ReceivedRequest req = (ReceivedRequest) message.obj;
-
-                    if (req.exchangeSubtype == IKE_EXCHANGE_SUBTYPE_REKEY_CHILD) {
-                        handleCreateChildRequest(req);
-                        return HANDLED;
-                    }
-
-                    return NOT_HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void handleCreateChildRequest(ReceivedRequest req) {
-            List<IkePayload> reqPayloads = null;
-            List<IkePayload> respPayloads = null;
-            try {
-                reqPayloads = req.requestPayloads;
-
-                // Build a rekey response payload list with our previously selected proposal,
-                // against which we will validate the received request. It is guaranteed in
-                // IkeSessionStateMachine#getIkeExchangeSubType that a SA Payload is included in the
-                // inbound request payload list.
-                IkeSaPayload reqSaPayload =
-                        IkePayload.getPayloadForTypeInProvidedList(
-                                PAYLOAD_TYPE_SA, IkeSaPayload.class, reqPayloads);
-                byte respProposalNumber = reqSaPayload.getNegotiatedProposalNumber(mSaProposal);
-
-                respPayloads =
-                        CreateChildSaHelper.getRekeyChildCreateRespPayloads(
-                                mIpSecManager,
-                                mLocalAddress,
-                                respProposalNumber,
-                                mSaProposal,
-                                mLocalTs,
-                                mRemoteTs,
-                                mCurrentChildSaRecord.getLocalSpi(),
-                                mChildSessionOptions.isTransportMode());
-            } catch (NoValidProposalChosenException e) {
-                handleCreationFailureAndBackToIdle(e);
-                return;
-            } catch (ResourceUnavailableException e) {
-                handleCreationFailureAndBackToIdle(
-                        new NoValidProposalChosenException("Fail to assign inbound SPI", e));
-                return;
-            }
-
-            CreateChildResult createChildResult =
-                    CreateChildSaHelper.validateAndNegotiateRekeyChildRequest(
-                            reqPayloads,
-                            respPayloads,
-                            req.exchangeType /*exchangeType*/,
-                            EXCHANGE_TYPE_CREATE_CHILD_SA /*expectedExchangeType*/,
-                            mChildSessionOptions.isTransportMode(),
-                            mIpSecManager,
-                            mRemoteAddress);
-
-            switch (createChildResult.status) {
-                case CREATE_STATUS_OK:
-                    try {
-                        // Do not need to update the negotiated proposal and TS
-                        // because they are not changed.
-
-                        ChildLocalRequest rekeyLocalRequest = makeRekeyLocalRequest();
-
-                        mRemoteInitNewChildSaRecord =
-                                ChildSaRecord.makeChildSaRecord(
-                                        mContext,
-                                        reqPayloads,
-                                        respPayloads,
-                                        createChildResult.initSpi,
-                                        createChildResult.respSpi,
-                                        mLocalAddress,
-                                        mRemoteAddress,
-                                        mUdpEncapSocket,
-                                        mIkePrf,
-                                        mChildIntegrity,
-                                        mChildCipher,
-                                        mSkD,
-                                        mChildSessionOptions.isTransportMode(),
-                                        false /*isLocalInit*/,
-                                        rekeyLocalRequest);
-
-                        mChildSmCallback.scheduleLocalRequest(rekeyLocalRequest, getRekeyTimeout());
-
-                        mChildSmCallback.onChildSaCreated(
-                                mRemoteInitNewChildSaRecord.getRemoteSpi(),
-                                ChildSessionStateMachine.this);
-
-                        // To avoid traffic loss, outbound transform should only be applied once
-                        // the remote has (implicitly) acknowledged our response via the
-                        // delete-old-SA request. This will be performed in the finishRekey()
-                        // method.
-                        mUserCbExecutor.execute(
-                                () -> {
-                                    mUserCallback.onIpSecTransformCreated(
-                                            mRemoteInitNewChildSaRecord.getInboundIpSecTransform(),
-                                            IpSecManager.DIRECTION_IN);
-                                });
-
-                        mChildSmCallback.onOutboundPayloadsReady(
-                                EXCHANGE_TYPE_CREATE_CHILD_SA,
-                                true /*isResp*/,
-                                respPayloads,
-                                ChildSessionStateMachine.this);
-
-                        transitionTo(mRekeyChildRemoteDelete);
-                    } catch (GeneralSecurityException
-                            | ResourceUnavailableException
-                            | SpiUnavailableException
-                            | IOException e) {
-                        // #makeChildSaRecord failed.
-                        createChildResult.initSpi.close();
-                        createChildResult.respSpi.close();
-
-                        handleCreationFailureAndBackToIdle(
-                                new NoValidProposalChosenException(
-                                        "Error in Child SA creation", e));
-                    }
-                    break;
-                case CREATE_STATUS_CHILD_ERROR_INVALID_MSG:
-                    IkeException error = createChildResult.exception;
-                    if (error instanceof IkeProtocolException) {
-                        handleCreationFailureAndBackToIdle((IkeProtocolException) error);
-                    } else {
-                        handleCreationFailureAndBackToIdle(
-                                new NoValidProposalChosenException(
-                                        "Error in validating Create Child request", error));
-                    }
-                    break;
-                case CREATE_STATUS_CHILD_ERROR_RCV_NOTIFY:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Unexpected processing status in Create Child request: "
-                                            + createChildResult.status));
-                    break;
-                default:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Unrecognized status: " + createChildResult.status));
-            }
-        }
-
-        private void handleCreationFailureAndBackToIdle(IkeProtocolException e) {
-            loge("Received invalid Rekey Child request. Reject with error notification", e);
-
-            ArrayList<IkePayload> payloads = new ArrayList<>(1);
-            payloads.add(e.buildNotifyPayload());
-            mChildSmCallback.onOutboundPayloadsReady(
-                    EXCHANGE_TYPE_CREATE_CHILD_SA,
-                    true /*isResp*/,
-                    payloads,
-                    ChildSessionStateMachine.this);
-
-            transitionTo(mIdle);
-        }
-    }
-
-    /**
-     * RekeyChildDeleteBase represents common behaviours of deleting stage during rekeying Child SA.
-     */
-    abstract class RekeyChildDeleteBase extends DeleteBase {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_REQUEST:
-                    try {
-                        if (isOnNewSa((ReceivedRequest) message.obj)) {
-                            finishRekey();
-                            deferMessage(message);
-                            transitionTo(mIdle);
-                            return HANDLED;
-                        }
-                        return NOT_HANDLED;
-                    } catch (IllegalStateException e) {
-                        cleanUpAndQuit(e);
-                        return HANDLED;
-                    }
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        private boolean isOnNewSa(ReceivedRequest req) {
-            switch (req.exchangeSubtype) {
-                case IKE_EXCHANGE_SUBTYPE_DELETE_CHILD:
-                    return hasRemoteChildSpiForDelete(req.requestPayloads, mChildSaRecordSurviving);
-                case IKE_EXCHANGE_SUBTYPE_REKEY_CHILD:
-                    return CreateChildSaHelper.hasRemoteChildSpiForRekey(
-                            req.requestPayloads, mChildSaRecordSurviving);
-                default:
-                    throw new IllegalStateException(
-                            "Invalid exchange subtype for Child Session: " + req.exchangeSubtype);
-            }
-        }
-
-        // Rekey timer for old SA will be cancelled as part of the closing of the SA.
-        protected void finishRekey() {
-            mUserCbExecutor.execute(
-                    () -> {
-                        onIpSecTransformPairDeleted(mCurrentChildSaRecord);
-                    });
-
-            mChildSmCallback.onChildSaDeleted(mCurrentChildSaRecord.getRemoteSpi());
-            mCurrentChildSaRecord.close();
-
-            mCurrentChildSaRecord = mChildSaRecordSurviving;
-
-            mLocalInitNewChildSaRecord = null;
-            mRemoteInitNewChildSaRecord = null;
-            mChildSaRecordSurviving = null;
-        }
-    }
-
-    /**
-     * RekeyChildLocalDelete represents the deleting stage of a locally-initiated Rekey Child
-     * procedure.
-     */
-    class RekeyChildLocalDelete extends RekeyChildDeleteBase {
-        @Override
-        public void enterState() {
-            mChildSaRecordSurviving = mLocalInitNewChildSaRecord;
-            sendDeleteChild(mCurrentChildSaRecord, false /*isResp*/);
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            if (super.processStateMessage(message) == HANDLED) {
-                return HANDLED;
-            }
-
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_RESPONSE:
-                    try {
-                        ReceivedResponse resp = (ReceivedResponse) message.obj;
-                        validateDeleteRespPayloadAndExchangeType(
-                                resp.responsePayloads, resp.exchangeType);
-
-                        boolean currentSaSpiFound =
-                                hasRemoteChildSpiForDelete(
-                                        resp.responsePayloads, mCurrentChildSaRecord);
-                        if (!currentSaSpiFound) {
-                            loge(
-                                    "Found no remote SPI for current SA in received Delete"
-                                        + " response. Shutting down old SA and finishing rekey.");
-                        }
-                    } catch (IkeProtocolException e) {
-                        loge(
-                                "Received Delete response with invalid syntax or error"
-                                    + " notifications. Shutting down old SA and finishing rekey.",
-                                e);
-                    }
-                    finishRekey();
-                    transitionTo(mIdle);
-                    return HANDLED;
-                default:
-                    // TODO: Handle requests on mCurrentChildSaRecord: Reply TEMPORARY_FAILURE to
-                    // a rekey request and reply empty INFORMATIONAL message to a delete request.
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * RekeyChildRemoteDelete represents the deleting stage of a remotely-initiated Rekey Child
-     * procedure.
-     */
-    class RekeyChildRemoteDelete extends RekeyChildDeleteBase {
-        @Override
-        public void enterState() {
-            mChildSaRecordSurviving = mRemoteInitNewChildSaRecord;
-            sendMessageDelayed(TIMEOUT_REKEY_REMOTE_DELETE, REKEY_DELETE_TIMEOUT_MS);
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            if (super.processStateMessage(message) == HANDLED) {
-                return HANDLED;
-            }
-
-            switch (message.what) {
-                case CMD_HANDLE_RECEIVED_REQUEST:
-                    ReceivedRequest req = (ReceivedRequest) message.obj;
-
-                    if (req.exchangeSubtype == IKE_EXCHANGE_SUBTYPE_DELETE_CHILD) {
-                        handleDeleteRequest(req.requestPayloads);
-
-                    } else {
-                        replyErrorNotification(ERROR_TYPE_TEMPORARY_FAILURE);
-                    }
-                    return HANDLED;
-                case TIMEOUT_REKEY_REMOTE_DELETE:
-                    // Receiving this signal means the remote side has received the outbound
-                    // Rekey-Create response since no retransmissions were received during the
-                    // waiting time. IKE library will assume the remote side has set up the new
-                    // Child SA and finish the rekey procedure. Users should be warned there is
-                    // a risk that the remote side failed to set up the new Child SA and all
-                    // outbound IPsec traffic protected by new Child SA will be dropped.
-
-                    // TODO:Consider finishing rekey procedure if the IKE Session receives a new
-                    // request. Since window size is one, receiving a new request indicates the
-                    // remote side has received the outbound Rekey-Create response
-
-                    finishRekey();
-                    transitionTo(mIdle);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void handleDeleteRequest(List<IkePayload> payloads) {
-            if (!hasRemoteChildSpiForDelete(payloads, mCurrentChildSaRecord)) {
-                // Request received on incorrect SA
-                cleanUpAndQuit(
-                        new IllegalStateException(
-                                "Found no remote SPI for current SA in received Delete"
-                                        + " response."));
-            } else {
-                sendDeleteChild(mCurrentChildSaRecord, true /*isResp*/);
-                finishRekey();
-                transitionTo(mIdle);
-            }
-        }
-
-        @Override
-        protected void finishRekey() {
-            mUserCbExecutor.execute(
-                    () -> {
-                        mUserCallback.onIpSecTransformCreated(
-                                mRemoteInitNewChildSaRecord.getOutboundIpSecTransform(),
-                                IpSecManager.DIRECTION_OUT);
-                    });
-
-            super.finishRekey();
-        }
-
-        @Override
-        public void exitState() {
-            removeMessages(TIMEOUT_REKEY_REMOTE_DELETE);
-        }
-    }
-
-    /**
-     * Package private helper class to generate IKE SA creation payloads, in both request and
-     * response directions.
-     */
-    static class CreateChildSaHelper {
-        /** Create payload list for creating the initial Child SA for this Child Session. */
-        public static List<IkePayload> getInitChildCreateReqPayloads(
-                IpSecManager ipSecManager,
-                InetAddress localAddress,
-                ChildSessionOptions childSessionOptions,
-                boolean isFirstChild)
-                throws ResourceUnavailableException {
-
-            ChildSaProposal[] saProposals = childSessionOptions.getSaProposals();
-
-            if (isFirstChild) {
-                for (int i = 0; i < saProposals.length; i++) {
-                    saProposals[i] =
-                            childSessionOptions.getSaProposals()[i].getCopyWithoutDhTransform();
-                }
-            }
-
-            List<IkePayload> payloadList =
-                    getChildCreatePayloads(
-                            IkeSaPayload.createChildSaRequestPayload(
-                                    saProposals, ipSecManager, localAddress),
-                            childSessionOptions.getLocalTrafficSelectors(),
-                            childSessionOptions.getRemoteTrafficSelectors(),
-                            childSessionOptions.isTransportMode());
-
-            if (!childSessionOptions.isTransportMode()) {
-                ConfigAttribute[] attributes =
-                        ((TunnelModeChildSessionOptions) childSessionOptions)
-                                .getConfigurationRequests();
-                IkeConfigPayload configPayload =
-                        new IkeConfigPayload(false /*isReply*/, Arrays.asList(attributes));
-                payloadList.add(configPayload);
-            }
-
-            return payloadList;
-        }
-
-        /** Create payload list as a rekey Child Session request. */
-        public static List<IkePayload> getRekeyChildCreateReqPayloads(
-                IpSecManager ipSecManager,
-                InetAddress localAddress,
-                ChildSaProposal currentProposal,
-                IkeTrafficSelector[] currentLocalTs,
-                IkeTrafficSelector[] currentRemoteTs,
-                int localSpi,
-                boolean isTransport)
-                throws ResourceUnavailableException {
-            List<IkePayload> payloads =
-                    getChildCreatePayloads(
-                            IkeSaPayload.createChildSaRequestPayload(
-                                    new ChildSaProposal[] {currentProposal},
-                                    ipSecManager,
-                                    localAddress),
-                            currentLocalTs,
-                            currentRemoteTs,
-                            isTransport);
-
-            payloads.add(
-                    new IkeNotifyPayload(
-                            PROTOCOL_ID_ESP, localSpi, NOTIFY_TYPE_REKEY_SA, new byte[0]));
-            return payloads;
-        }
-
-        /** Create payload list as a rekey Child Session response. */
-        public static List<IkePayload> getRekeyChildCreateRespPayloads(
-                IpSecManager ipSecManager,
-                InetAddress localAddress,
-                byte proposalNumber,
-                ChildSaProposal currentProposal,
-                IkeTrafficSelector[] currentLocalTs,
-                IkeTrafficSelector[] currentRemoteTs,
-                int localSpi,
-                boolean isTransport)
-                throws ResourceUnavailableException {
-            List<IkePayload> payloads =
-                    getChildCreatePayloads(
-                            IkeSaPayload.createChildSaResponsePayload(
-                                    proposalNumber, currentProposal, ipSecManager, localAddress),
-                            currentRemoteTs /*initTs*/,
-                            currentLocalTs /*respTs*/,
-                            isTransport);
-
-            payloads.add(
-                    new IkeNotifyPayload(
-                            PROTOCOL_ID_ESP, localSpi, NOTIFY_TYPE_REKEY_SA, new byte[0]));
-            return payloads;
-        }
-
-        /** Create payload list for creating a new Child SA. */
-        private static List<IkePayload> getChildCreatePayloads(
-                IkeSaPayload saPayload,
-                IkeTrafficSelector[] initTs,
-                IkeTrafficSelector[] respTs,
-                boolean isTransport)
-                throws ResourceUnavailableException {
-            List<IkePayload> payloadList = new ArrayList<>(5);
-
-            payloadList.add(saPayload);
-            payloadList.add(new IkeTsPayload(true /*isInitiator*/, initTs));
-            payloadList.add(new IkeTsPayload(false /*isInitiator*/, respTs));
-            payloadList.add(new IkeNoncePayload());
-
-            DhGroupTransform[] dhGroups =
-                    ((ChildProposal) saPayload.proposalList.get(0))
-                            .saProposal.getDhGroupTransforms();
-            if (dhGroups.length != 0 && dhGroups[0].id != DH_GROUP_NONE) {
-                payloadList.add(new IkeKePayload(dhGroups[0].id));
-            }
-
-            if (isTransport) payloadList.add(new IkeNotifyPayload(NOTIFY_TYPE_USE_TRANSPORT_MODE));
-
-            return payloadList;
-        }
-
-        /**
-         * Validate the received response of initial Create Child SA exchange and return the
-         * negotiation result.
-         */
-        public static CreateChildResult validateAndNegotiateInitChild(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                @ExchangeType int exchangeType,
-                @ExchangeType int expectedExchangeType,
-                boolean expectTransport,
-                IpSecManager ipSecManager,
-                InetAddress remoteAddress) {
-
-            return validateAndNegotiateChild(
-                    reqPayloads,
-                    respPayloads,
-                    exchangeType,
-                    expectedExchangeType,
-                    true /*isLocalInit*/,
-                    expectTransport,
-                    ipSecManager,
-                    remoteAddress);
-        }
-
-        /**
-         * Validate the received rekey-create request against locally built response (based on
-         * previously negotiated Child SA) and return the negotiation result.
-         */
-        public static CreateChildResult validateAndNegotiateRekeyChildRequest(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                @ExchangeType int exchangeType,
-                @ExchangeType int expectedExchangeType,
-                boolean expectTransport,
-                IpSecManager ipSecManager,
-                InetAddress remoteAddress) {
-
-            // It is guaranteed that a Rekey-Notify Payload with remote SPI of current Child SA is
-            // included in the reqPayloads. So we won't validate it again here.
-            return validateAndNegotiateChild(
-                    reqPayloads,
-                    respPayloads,
-                    exchangeType,
-                    expectedExchangeType,
-                    false /*isLocalInit*/,
-                    expectTransport,
-                    ipSecManager,
-                    remoteAddress);
-        }
-
-        /**
-         * Validate the received rekey-create response against locally built request and previously
-         * negotiated Child SA, and return the negotiation result.
-         */
-        public static CreateChildResult validateAndNegotiateRekeyChildResp(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                @ExchangeType int exchangeType,
-                @ExchangeType int expectedExchangeType,
-                boolean expectTransport,
-                ChildSaRecord expectedChildRecord,
-                IpSecManager ipSecManager,
-                InetAddress remoteAddress) {
-            // Validate rest of payloads and negotiate Child SA.
-            CreateChildResult childResult =
-                    validateAndNegotiateChild(
-                            reqPayloads,
-                            respPayloads,
-                            exchangeType,
-                            expectedExchangeType,
-                            true /*isLocalInit*/,
-                            expectTransport,
-                            ipSecManager,
-                            remoteAddress);
-
-            // TODO: Validate new Child SA does not have different Traffic Selectors
-
-            return childResult;
-        }
-
-        /**
-         * Check if SPI of Child SA that is expected to be rekeyed is included in the provided
-         * payload list.
-         */
-        public static boolean hasRemoteChildSpiForRekey(
-                List<IkePayload> payloads, ChildSaRecord expectedRecord) {
-            List<IkeNotifyPayload> notifyPayloads =
-                    IkePayload.getPayloadListForTypeInProvidedList(
-                            IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, payloads);
-
-            boolean hasExpectedRekeyNotify = false;
-            for (IkeNotifyPayload notifyPayload : notifyPayloads) {
-                if (notifyPayload.notifyType == NOTIFY_TYPE_REKEY_SA
-                        && notifyPayload.spi == expectedRecord.getRemoteSpi()) {
-                    hasExpectedRekeyNotify = true;
-                    break;
-                }
-            }
-
-            return hasExpectedRekeyNotify;
-        }
-
-        /** Validate the received payload list and negotiate Child SA. */
-        private static CreateChildResult validateAndNegotiateChild(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                @ExchangeType int exchangeType,
-                @ExchangeType int expectedExchangeType,
-                boolean isLocalInit,
-                boolean expectTransport,
-                IpSecManager ipSecManager,
-                InetAddress remoteAddress) {
-            List<IkePayload> inboundPayloads = isLocalInit ? respPayloads : reqPayloads;
-
-            try {
-                validatePayloadAndExchangeType(
-                        inboundPayloads,
-                        isLocalInit /*isResp*/,
-                        exchangeType,
-                        expectedExchangeType);
-            } catch (InvalidSyntaxException e) {
-                return new CreateChildResult(CREATE_STATUS_CHILD_ERROR_INVALID_MSG, e);
-            }
-
-            List<IkeNotifyPayload> notifyPayloads =
-                    IkePayload.getPayloadListForTypeInProvidedList(
-                            IkePayload.PAYLOAD_TYPE_NOTIFY,
-                            IkeNotifyPayload.class,
-                            inboundPayloads);
-
-            boolean hasTransportNotify = false;
-            for (IkeNotifyPayload notify : notifyPayloads) {
-                if (notify.isErrorNotify()) {
-                    try {
-                        IkeProtocolException exception = notify.validateAndBuildIkeException();
-                        if (isLocalInit) {
-                            return new CreateChildResult(
-                                    CREATE_STATUS_CHILD_ERROR_RCV_NOTIFY, exception);
-                        } else {
-                            logw("Received unexpected error notification: " + notify.notifyType);
-                        }
-                    } catch (InvalidSyntaxException e) {
-                        return new CreateChildResult(CREATE_STATUS_CHILD_ERROR_INVALID_MSG, e);
-                    }
-                }
-
-                switch (notify.notifyType) {
-                    case IkeNotifyPayload.NOTIFY_TYPE_ADDITIONAL_TS_POSSIBLE:
-                        // TODO: Store it as part of negotiation results that can be retrieved
-                        // by users.
-                        break;
-                    case IkeNotifyPayload.NOTIFY_TYPE_IPCOMP_SUPPORTED:
-                        // Ignore
-                        break;
-                    case IkeNotifyPayload.NOTIFY_TYPE_USE_TRANSPORT_MODE:
-                        hasTransportNotify = true;
-                        break;
-                    case IkeNotifyPayload.NOTIFY_TYPE_ESP_TFC_PADDING_NOT_SUPPORTED:
-                        // Ignore
-                        break;
-                    default:
-                        // Unknown and unexpected status notifications are ignored as per RFC7296.
-                        logw(
-                                "Received unknown or unexpected status notifications with notify"
-                                        + " type: "
-                                        + notify.notifyType);
-                }
-            }
-
-            Pair<ChildProposal, ChildProposal> childProposalPair = null;
-            try {
-                IkeSaPayload reqSaPayload =
-                        IkePayload.getPayloadForTypeInProvidedList(
-                                IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, reqPayloads);
-                IkeSaPayload respSaPayload =
-                        IkePayload.getPayloadForTypeInProvidedList(
-                                IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, respPayloads);
-
-                // This method either throws exception or returns non-null pair that contains two
-                // valid {@link ChildProposal} both with a {@link SecurityParameterIndex} allocated
-                // inside.
-                childProposalPair =
-                        IkeSaPayload.getVerifiedNegotiatedChildProposalPair(
-                                reqSaPayload, respSaPayload, ipSecManager, remoteAddress);
-                ChildSaProposal saProposal = childProposalPair.second.saProposal;
-
-                validateKePayloads(inboundPayloads, isLocalInit /*isResp*/, saProposal);
-
-                if (expectTransport != hasTransportNotify) {
-                    throw new NoValidProposalChosenException(
-                            "Failed the negotiation on Child SA mode (conflicting modes chosen).");
-                }
-
-                Pair<IkeTrafficSelector[], IkeTrafficSelector[]> tsPair =
-                        validateAndGetNegotiatedTsPair(reqPayloads, respPayloads);
-
-                return new CreateChildResult(
-                        childProposalPair.first.getChildSpiResource(),
-                        childProposalPair.second.getChildSpiResource(),
-                        saProposal,
-                        tsPair.first,
-                        tsPair.second);
-            } catch (IkeProtocolException
-                    | ResourceUnavailableException
-                    | SpiUnavailableException e) {
-                if (childProposalPair != null) {
-                    childProposalPair.first.getChildSpiResource().close();
-                    childProposalPair.second.getChildSpiResource().close();
-                }
-
-                if (e instanceof InvalidSyntaxException) {
-                    return new CreateChildResult(
-                            CREATE_STATUS_CHILD_ERROR_INVALID_MSG, (InvalidSyntaxException) e);
-                } else if (e instanceof IkeProtocolException) {
-                    return new CreateChildResult(
-                            CREATE_STATUS_CHILD_ERROR_INVALID_MSG,
-                            new InvalidSyntaxException(
-                                    "Processing error in received Create Child response", e));
-                } else {
-                    return new CreateChildResult(
-                            CREATE_STATUS_CHILD_ERROR_INVALID_MSG, new IkeInternalException(e));
-                }
-            }
-        }
-
-        // Validate syntax to make sure all necessary payloads exist and exchange type is correct.
-        private static void validatePayloadAndExchangeType(
-                List<IkePayload> inboundPayloads,
-                boolean isResp,
-                @ExchangeType int exchangeType,
-                @ExchangeType int expectedExchangeType)
-                throws InvalidSyntaxException {
-            boolean hasSaPayload = false;
-            boolean hasKePayload = false;
-            boolean hasNoncePayload = false;
-            boolean hasTsInitPayload = false;
-            boolean hasTsRespPayload = false;
-            boolean hasErrorNotify = false;
-
-            for (IkePayload payload : inboundPayloads) {
-                switch (payload.payloadType) {
-                    case PAYLOAD_TYPE_SA:
-                        hasSaPayload = true;
-                        break;
-                    case PAYLOAD_TYPE_KE:
-                        // Could not decide if KE Payload MUST or MUST NOT be included until SA
-                        // negotiation is done.
-                        hasKePayload = true;
-                        break;
-                    case PAYLOAD_TYPE_NONCE:
-                        hasNoncePayload = true;
-                        break;
-                    case PAYLOAD_TYPE_TS_INITIATOR:
-                        hasTsInitPayload = true;
-                        break;
-                    case PAYLOAD_TYPE_TS_RESPONDER:
-                        hasTsRespPayload = true;
-                        break;
-                    case PAYLOAD_TYPE_NOTIFY:
-                        if (((IkeNotifyPayload) payload).isErrorNotify()) hasErrorNotify = true;
-                        // Do not have enough context to handle all notifications. Handle them
-                        // together in higher layer.
-                        break;
-                    case PAYLOAD_TYPE_CP:
-                        // Handled in child creation state. Note Child Session can only handle
-                        // Config Payload in initial creation and can only handle a Config Reply.
-                        // For interoperability, Config Payloads received in rekey creation
-                        // or with other config types will be ignored.
-                        break;
-                    default:
-                        logw(
-                                "Received unexpected payload in Create Child SA message. Payload"
-                                        + " type: "
-                                        + payload.payloadType);
-                }
-            }
-
-            // Do not need to check exchange type of a request because it has been already verified
-            // in IkeSessionStateMachine
-            if (isResp
-                    && exchangeType != expectedExchangeType
-                    && exchangeType != EXCHANGE_TYPE_INFORMATIONAL) {
-                throw new InvalidSyntaxException("Received invalid exchange type: " + exchangeType);
-            }
-
-            if (exchangeType == EXCHANGE_TYPE_INFORMATIONAL
-                    && (hasSaPayload
-                            || hasKePayload
-                            || hasNoncePayload
-                            || hasTsInitPayload
-                            || hasTsRespPayload)) {
-                logw(
-                        "Unexpected payload found in an INFORMATIONAL message: SA, KE, Nonce,"
-                                + " TS-Initiator or TS-Responder");
-            }
-
-            if (isResp
-                    && !hasErrorNotify
-                    && (!hasSaPayload
-                            || !hasNoncePayload
-                            || !hasTsInitPayload
-                            || !hasTsRespPayload)) {
-                throw new InvalidSyntaxException(
-                        "SA, Nonce, TS-Initiator or TS-Responder missing.");
-            }
-        }
-
-        private static Pair<IkeTrafficSelector[], IkeTrafficSelector[]>
-                validateAndGetNegotiatedTsPair(
-                        List<IkePayload> reqPayloads, List<IkePayload> respPayloads)
-                        throws TsUnacceptableException {
-            IkeTrafficSelector[] initTs =
-                    validateAndGetNegotiatedTs(reqPayloads, respPayloads, true /*isInitTs*/);
-            IkeTrafficSelector[] respTs =
-                    validateAndGetNegotiatedTs(reqPayloads, respPayloads, false /*isInitTs*/);
-
-            return new Pair<IkeTrafficSelector[], IkeTrafficSelector[]>(initTs, respTs);
-        }
-
-        private static IkeTrafficSelector[] validateAndGetNegotiatedTs(
-                List<IkePayload> reqPayloads, List<IkePayload> respPayloads, boolean isInitTs)
-                throws TsUnacceptableException {
-            int tsType = isInitTs ? PAYLOAD_TYPE_TS_INITIATOR : PAYLOAD_TYPE_TS_RESPONDER;
-            IkeTsPayload reqPayload =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                            tsType, IkeTsPayload.class, reqPayloads);
-            IkeTsPayload respPayload =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                            tsType, IkeTsPayload.class, respPayloads);
-
-            if (!reqPayload.contains(respPayload)) {
-                throw new TsUnacceptableException();
-            }
-
-            // It is guaranteed by decoding inbound TS Payload and constructing outbound TS Payload
-            // that each TS Payload has at least one IkeTrafficSelector.
-            return respPayload.trafficSelectors;
-        }
-
-        @VisibleForTesting
-        static void validateKePayloads(
-                List<IkePayload> inboundPayloads,
-                boolean isResp,
-                ChildSaProposal negotiatedProposal)
-                throws IkeProtocolException {
-            DhGroupTransform[] dhTransforms = negotiatedProposal.getDhGroupTransforms();
-
-            if (dhTransforms.length > 1) {
-                throw new IllegalArgumentException(
-                        "Found multiple DH Group Transforms in the negotiated SA proposal");
-            }
-            boolean expectKePayload =
-                    dhTransforms.length == 1 && dhTransforms[0].id != DH_GROUP_NONE;
-
-            IkeKePayload kePayload =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                            PAYLOAD_TYPE_KE, IkeKePayload.class, inboundPayloads);
-
-            if (expectKePayload && (kePayload == null || dhTransforms[0].id != kePayload.dhGroup)) {
-                if (isResp) {
-                    throw new InvalidSyntaxException(
-                            "KE Payload missing or has mismatched DH Group with the negotiated"
-                                    + " proposal.");
-                } else {
-                    throw new InvalidKeException(dhTransforms[0].id);
-                }
-
-            } else if (!expectKePayload && kePayload != null && isResp) {
-                // It is valid when the remote request proposed multiple DH Groups with a KE
-                // payload, and the responder chose DH_GROUP_NONE.
-                throw new InvalidSyntaxException("Received unexpected KE Payload.");
-            }
-        }
-
-        private static void logw(String s) {
-            getIkeLog().w(TAG, s);
-        }
-    }
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        CREATE_STATUS_OK,
-        CREATE_STATUS_CHILD_ERROR_INVALID_MSG,
-        CREATE_STATUS_CHILD_ERROR_RCV_NOTIFY
-    })
-    @interface CreateStatus {}
-
-    /** The Child SA negotiation succeeds. */
-    private static final int CREATE_STATUS_OK = 0;
-    /** The inbound message is invalid in Child negotiation but is non-fatal for IKE Session. */
-    private static final int CREATE_STATUS_CHILD_ERROR_INVALID_MSG = 1;
-    /** The inbound message includes error notification that failed the Child negotiation. */
-    private static final int CREATE_STATUS_CHILD_ERROR_RCV_NOTIFY = 2;
-
-    private static class CreateChildResult {
-        @CreateStatus public final int status;
-        public final SecurityParameterIndex initSpi;
-        public final SecurityParameterIndex respSpi;
-        public final ChildSaProposal negotiatedProposal;
-        public final IkeTrafficSelector[] initTs;
-        public final IkeTrafficSelector[] respTs;
-        public final IkeException exception;
-
-        private CreateChildResult(
-                @CreateStatus int status,
-                SecurityParameterIndex initSpi,
-                SecurityParameterIndex respSpi,
-                ChildSaProposal negotiatedProposal,
-                IkeTrafficSelector[] initTs,
-                IkeTrafficSelector[] respTs,
-                IkeException exception) {
-            this.status = status;
-            this.initSpi = initSpi;
-            this.respSpi = respSpi;
-            this.negotiatedProposal = negotiatedProposal;
-            this.initTs = initTs;
-            this.respTs = respTs;
-            this.exception = exception;
-        }
-
-        /* Construct a CreateChildResult instance for a successful case. */
-        CreateChildResult(
-                SecurityParameterIndex initSpi,
-                SecurityParameterIndex respSpi,
-                ChildSaProposal negotiatedProposal,
-                IkeTrafficSelector[] initTs,
-                IkeTrafficSelector[] respTs) {
-            this(
-                    CREATE_STATUS_OK,
-                    initSpi,
-                    respSpi,
-                    negotiatedProposal,
-                    initTs,
-                    respTs,
-                    null /*exception*/);
-        }
-
-        /** Construct a CreateChildResult instance for an error case. */
-        CreateChildResult(@CreateStatus int status, IkeException exception) {
-            this(
-                    status,
-                    null /*initSpi*/,
-                    null /*respSpi*/,
-                    null /*negotiatedProposal*/,
-                    null /*initTs*/,
-                    null /*respTs*/,
-                    exception);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineFactory.java b/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineFactory.java
deleted file mode 100644
index 5282d02..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineFactory.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionOptions;
-import android.os.Looper;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.IChildSessionSmCallback;
-
-import java.util.concurrent.Executor;
-
-/** Package private factory for making ChildSessionStateMachine. */
-// TODO: Make it a inner Creator class of ChildSessionStateMachine
-final class ChildSessionStateMachineFactory {
-
-    private static IChildSessionFactoryHelper sChildSessionHelper = new ChildSessionFactoryHelper();
-
-    /** Package private. */
-    static ChildSessionStateMachine makeChildSessionStateMachine(
-            Looper looper,
-            Context context,
-            ChildSessionOptions sessionOptions,
-            Executor userCbExecutor,
-            ChildSessionCallback userCallbacks,
-            IChildSessionSmCallback childSmCallback) {
-        return sChildSessionHelper.makeChildSessionStateMachine(
-                looper, context, sessionOptions, userCbExecutor, userCallbacks, childSmCallback);
-    }
-
-    @VisibleForTesting
-    static void setChildSessionFactoryHelper(IChildSessionFactoryHelper helper) {
-        sChildSessionHelper = helper;
-    }
-
-    /**
-     * IChildSessionFactoryHelper provides a package private interface for constructing
-     * ChildSessionStateMachine.
-     *
-     * <p>IChildSessionFactoryHelper exists so that the interface is injectable for testing.
-     */
-    interface IChildSessionFactoryHelper {
-        ChildSessionStateMachine makeChildSessionStateMachine(
-                Looper looper,
-                Context context,
-                ChildSessionOptions sessionOptions,
-                Executor userCbExecutor,
-                ChildSessionCallback userCallbacks,
-                IChildSessionSmCallback childSmCallback);
-    }
-
-    /**
-     * ChildSessionFactoryHelper implements a method for constructing ChildSessionStateMachine.
-     *
-     * <p>Package private.
-     */
-    static class ChildSessionFactoryHelper implements IChildSessionFactoryHelper {
-        public ChildSessionStateMachine makeChildSessionStateMachine(
-                Looper looper,
-                Context context,
-                ChildSessionOptions sessionOptions,
-                Executor userCbExecutor,
-                ChildSessionCallback userCallbacks,
-                IChildSessionSmCallback childSmCallback) {
-            ChildSessionStateMachine childSession =
-                    new ChildSessionStateMachine(
-                            looper,
-                            context,
-                            (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE),
-                            sessionOptions,
-                            userCbExecutor,
-                            userCallbacks,
-                            childSmCallback);
-            childSession.start();
-            return childSession;
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeEapAuthenticatorFactory.java b/src/java/com/android/internal/net/ipsec/ike/IkeEapAuthenticatorFactory.java
deleted file mode 100644
index b0d6f12..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/IkeEapAuthenticatorFactory.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.os.Looper;
-
-import com.android.internal.net.eap.EapAuthenticator;
-import com.android.internal.net.eap.IEapCallback;
-
-/** Package private factory for building EapAuthenticator instances. */
-final class IkeEapAuthenticatorFactory {
-    /**
-     * Builds and returns a new EapAuthenticator
-     *
-     * @param looper Looper for running a message loop
-     * @param cbHandler Handler for posting callbacks to the given IEapCallback
-     * @param cb IEapCallback for callbacks to the client
-     * @param context Context for the EapAuthenticator
-     */
-    public EapAuthenticator newEapAuthenticator(
-            Looper looper, IEapCallback cb, Context context, EapSessionConfig eapSessionConfig) {
-        return new EapAuthenticator(looper, cb, context, eapSessionConfig);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java b/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
deleted file mode 100644
index b7bf870..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestScheduler.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike;
-
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionOptions;
-
-import java.util.LinkedList;
-
-/**
- * IkeLocalRequestScheduler caches all local requests scheduled by an IKE Session and notify the IKE
- * Session to process the request when it is allowed.
- *
- * <p>LocalRequestScheduler is running on the IkeSessionStateMachine thread.
- */
-public final class IkeLocalRequestScheduler {
-    private final LinkedList<LocalRequest> mRequestQueue = new LinkedList<>();
-
-    private final IProcedureConsumer mConsumer;
-
-    private boolean mLocalProcedureOngoing;
-    private boolean mRemoteProcedureOngoing;
-
-    /**
-     * Construct an instance of IkeLocalRequestScheduler
-     *
-     * @param consumer the interface to initiate new procedure.
-     */
-    public IkeLocalRequestScheduler(IProcedureConsumer consumer) {
-        mConsumer = consumer;
-    }
-
-    /** Add a new local request to the queue. */
-    public void addRequest(LocalRequest request) {
-        mRequestQueue.offer(request);
-    }
-
-    /** Add a new local request to the front of the queue. */
-    public void addRequestAtFront(LocalRequest request) {
-        mRequestQueue.offerFirst(request);
-    }
-
-    /**
-     * Notifies the scheduler that the caller is ready for a new procedure
-     *
-     * <p>Synchronously triggers the call to onNewProcedureReady.
-     */
-    public void readyForNextProcedure() {
-        while (!mRequestQueue.isEmpty()) {
-            LocalRequest request = mRequestQueue.poll();
-            if (!request.isCancelled()) {
-                mConsumer.onNewProcedureReady(request);
-                return;
-            }
-        }
-    }
-
-    /**
-     * This class represents a user requested or internally scheduled IKE procedure that will be
-     * initiated locally.
-     */
-    public static class LocalRequest {
-        public final int procedureType;
-        // TODO: Also store specific payloads for INFO exchange.
-        private boolean mIsCancelled;
-
-        LocalRequest(int type) {
-            procedureType = type;
-            mIsCancelled = false;
-        }
-
-        boolean isCancelled() {
-            return mIsCancelled;
-        }
-
-        void cancel() {
-            mIsCancelled = true;
-        }
-    }
-
-    /**
-     * This class represents a user requested or internally scheduled Child procedure that will be
-     * initiated locally.
-     */
-    public static class ChildLocalRequest extends LocalRequest {
-        public final ChildSessionCallback childSessionCallback;
-        public final ChildSessionOptions childSessionOptions;
-
-        ChildLocalRequest(
-                int type, ChildSessionCallback childCallback, ChildSessionOptions childOptions) {
-            super(type);
-            childSessionOptions = childOptions;
-            childSessionCallback = childCallback;
-        }
-    }
-
-    /** Interface to initiate a new IKE procedure */
-    public interface IProcedureConsumer {
-        /**
-         * Called when a new IKE procedure can be initiated.
-         *
-         * @param localRequest the request to be initiated.
-         */
-        void onNewProcedureReady(LocalRequest localRequest);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java b/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
deleted file mode 100644
index 03c419d..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachine.java
+++ /dev/null
@@ -1,4235 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ErrorType;
-
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL;
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_OK;
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_PARTIAL;
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_PROTECTED_ERROR;
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_UNPROTECTED_ERROR;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_CP;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_DELETE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_VENDOR;
-
-import android.annotation.IntDef;
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.ResourceUnavailableException;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionOptions;
-import android.net.ipsec.ike.IkeSaProposal;
-import android.net.ipsec.ike.IkeSessionCallback;
-import android.net.ipsec.ike.IkeSessionOptions;
-import android.net.ipsec.ike.IkeSessionOptions.IkeAuthConfig;
-import android.net.ipsec.ike.IkeSessionOptions.IkeAuthDigitalSignRemoteConfig;
-import android.net.ipsec.ike.IkeSessionOptions.IkeAuthPskConfig;
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeInternalException;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.system.ErrnoException;
-import android.system.Os;
-import android.system.OsConstants;
-import android.util.LongSparseArray;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.eap.EapAuthenticator;
-import com.android.internal.net.eap.IEapCallback;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.CreateChildSaHelper;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.message.IkeAuthDigitalSignPayload;
-import com.android.internal.net.ipsec.ike.message.IkeAuthPayload;
-import com.android.internal.net.ipsec.ike.message.IkeAuthPskPayload;
-import com.android.internal.net.ipsec.ike.message.IkeCertPayload;
-import com.android.internal.net.ipsec.ike.message.IkeCertX509CertPayload;
-import com.android.internal.net.ipsec.ike.message.IkeDeletePayload;
-import com.android.internal.net.ipsec.ike.message.IkeEapPayload;
-import com.android.internal.net.ipsec.ike.message.IkeHeader;
-import com.android.internal.net.ipsec.ike.message.IkeHeader.ExchangeType;
-import com.android.internal.net.ipsec.ike.message.IkeIdPayload;
-import com.android.internal.net.ipsec.ike.message.IkeInformationalPayload;
-import com.android.internal.net.ipsec.ike.message.IkeKePayload;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultError;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultOk;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultProtectedError;
-import com.android.internal.net.ipsec.ike.message.IkeNoncePayload;
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IkeProposal;
-import com.android.internal.net.ipsec.ike.message.IkeTsPayload;
-import com.android.internal.net.ipsec.ike.utils.Retransmitter;
-import com.android.internal.util.State;
-
-import dalvik.system.CloseGuard;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.SocketException;
-import java.security.GeneralSecurityException;
-import java.security.Provider;
-import java.security.SecureRandom;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * IkeSessionStateMachine tracks states and manages exchanges of this IKE session.
- *
- * <p>IkeSessionStateMachine has two types of states. One type are states where there is no ongoing
- * procedure affecting IKE session (non-procedure state), including Initial, Idle and Receiving. All
- * other states are "procedure" states which are named as follows:
- *
- * <pre>
- * State Name = [Procedure Type] + [Exchange Initiator] + [Exchange Type].
- * - An IKE procedure consists of one or two IKE exchanges:
- *      Procedure Type = {CreateIke | DeleteIke | Info | RekeyIke | SimulRekeyIke}.
- * - Exchange Initiator indicates whether local or remote peer is the exchange initiator:
- *      Exchange Initiator = {Local | Remote}
- * - Exchange type defines the function of this exchange. To make it more descriptive, we separate
- *      Delete Exchange from generic Informational Exchange:
- *      Exchange Type = {IkeInit | IkeAuth | Create | Delete | Info}
- * </pre>
- */
-public class IkeSessionStateMachine extends AbstractSessionStateMachine {
-
-    private static final String TAG = "IkeSessionStateMachine";
-
-    // TODO: b/140579254 Allow users to configure fragment size.
-
-    // Default fragment size in bytes.
-    @VisibleForTesting static final int DEFAULT_FRAGMENT_SIZE = 1280;
-
-    // TODO: Add SA_HARD_LIFETIME_MS
-
-    // Time after which IKE SA needs to be rekeyed
-    @VisibleForTesting static final long SA_SOFT_LIFETIME_MS = TimeUnit.HOURS.toMillis(3L);
-
-    // Default delay time for retrying a request
-    @VisibleForTesting static final long RETRY_INTERVAL_MS = TimeUnit.SECONDS.toMillis(15L);
-
-    // Close IKE Session when all responses during this time were TEMPORARY_FAILURE(s). This
-    // indicates that something has gone wrong, and we are out of sync.
-    @VisibleForTesting
-    static final long TEMP_FAILURE_RETRY_TIMEOUT_MS = TimeUnit.MINUTES.toMillis(5L);
-
-    // TODO: Allow users to configure IKE lifetime
-
-    // Package private IKE exchange subtypes describe the specific function of a IKE
-    // request/response exchange. It helps IkeSessionStateMachine to do message validation according
-    // to the subtype specific rules.
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        IKE_EXCHANGE_SUBTYPE_INVALID,
-        IKE_EXCHANGE_SUBTYPE_IKE_INIT,
-        IKE_EXCHANGE_SUBTYPE_IKE_AUTH,
-        IKE_EXCHANGE_SUBTYPE_DELETE_IKE,
-        IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-        IKE_EXCHANGE_SUBTYPE_REKEY_IKE,
-        IKE_EXCHANGE_SUBTYPE_REKEY_CHILD,
-        IKE_EXCHANGE_SUBTYPE_GENERIC_INFO
-    })
-    @interface IkeExchangeSubType {}
-
-    static final int IKE_EXCHANGE_SUBTYPE_INVALID = 0;
-    static final int IKE_EXCHANGE_SUBTYPE_IKE_INIT = 1;
-    static final int IKE_EXCHANGE_SUBTYPE_IKE_AUTH = 2;
-    static final int IKE_EXCHANGE_SUBTYPE_CREATE_CHILD = 3;
-    static final int IKE_EXCHANGE_SUBTYPE_DELETE_IKE = 4;
-    static final int IKE_EXCHANGE_SUBTYPE_DELETE_CHILD = 5;
-    static final int IKE_EXCHANGE_SUBTYPE_REKEY_IKE = 6;
-    static final int IKE_EXCHANGE_SUBTYPE_REKEY_CHILD = 7;
-    static final int IKE_EXCHANGE_SUBTYPE_GENERIC_INFO = 8;
-
-    private static final SparseArray<String> EXCHANGE_SUBTYPE_TO_STRING;
-
-    static {
-        EXCHANGE_SUBTYPE_TO_STRING = new SparseArray<>();
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_INVALID, "Invalid");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_IKE_INIT, "IKE INIT");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_IKE_AUTH, "IKE AUTH");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_CREATE_CHILD, "Create Child");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_DELETE_IKE, "Delete IKE");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_DELETE_CHILD, "Delete Child");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_REKEY_IKE, "Rekey IKE");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, "Rekey Child");
-        EXCHANGE_SUBTYPE_TO_STRING.put(IKE_EXCHANGE_SUBTYPE_GENERIC_INFO, "Generic Info");
-    }
-
-    /** Package private signals accessible for testing code. */
-    private static final int CMD_GENERAL_BASE = CMD_PRIVATE_BASE;
-
-    /** Receive encoded IKE packet on IkeSessionStateMachine. */
-    static final int CMD_RECEIVE_IKE_PACKET = CMD_GENERAL_BASE + 1;
-    /** Receive encoded IKE packet with unrecognized IKE SPI on IkeSessionStateMachine. */
-    static final int CMD_RECEIVE_PACKET_INVALID_IKE_SPI = CMD_GENERAL_BASE + 2;
-    /** Receive an remote request for a Child procedure. */
-    static final int CMD_RECEIVE_REQUEST_FOR_CHILD = CMD_GENERAL_BASE + 3;
-    /** Receive payloads from Child Session for building an outbound IKE message. */
-    static final int CMD_OUTBOUND_CHILD_PAYLOADS_READY = CMD_GENERAL_BASE + 4;
-    /** A Child Session has finished its procedure. */
-    static final int CMD_CHILD_PROCEDURE_FINISHED = CMD_GENERAL_BASE + 5;
-    /** Send request/response payloads to ChildSessionStateMachine for further processing. */
-    static final int CMD_HANDLE_FIRST_CHILD_NEGOTIATION = CMD_GENERAL_BASE + 6;
-    /** Receive a local request to execute from the scheduler */
-    static final int CMD_EXECUTE_LOCAL_REQ = CMD_GENERAL_BASE + 7;
-    /** Trigger a retransmission. */
-    public static final int CMD_RETRANSMIT = CMD_GENERAL_BASE + 8;
-    /** Send EAP request payloads to EapAuthenticator for further processing. */
-    static final int CMD_EAP_START_EAP_AUTH = CMD_GENERAL_BASE + 9;
-    /** Send the outbound IKE-wrapped EAP-Response message. */
-    static final int CMD_EAP_OUTBOUND_MSG_READY = CMD_GENERAL_BASE + 10;
-    /** Proxy to IkeSessionStateMachine handler to notify of errors */
-    static final int CMD_EAP_ERRORED = CMD_GENERAL_BASE + 11;
-    /** Proxy to IkeSessionStateMachine handler to notify of failures */
-    static final int CMD_EAP_FAILED = CMD_GENERAL_BASE + 12;
-    /** Proxy to IkeSessionStateMachine handler to notify of success, to continue to post-auth */
-    static final int CMD_EAP_FINISH_EAP_AUTH = CMD_GENERAL_BASE + 14;
-    /** Force state machine to a target state for testing purposes. */
-    static final int CMD_FORCE_TRANSITION = CMD_GENERAL_BASE + 99;
-
-    static final int CMD_IKE_LOCAL_REQUEST_BASE = CMD_GENERAL_BASE + CMD_CATEGORY_SIZE;
-    static final int CMD_LOCAL_REQUEST_CREATE_IKE = CMD_IKE_LOCAL_REQUEST_BASE + 1;
-    static final int CMD_LOCAL_REQUEST_DELETE_IKE = CMD_IKE_LOCAL_REQUEST_BASE + 2;
-    static final int CMD_LOCAL_REQUEST_REKEY_IKE = CMD_IKE_LOCAL_REQUEST_BASE + 3;
-    static final int CMD_LOCAL_REQUEST_INFO = CMD_IKE_LOCAL_REQUEST_BASE + 4;
-
-    private static final SparseArray<String> CMD_TO_STR;
-
-    static {
-        CMD_TO_STR = new SparseArray<>();
-        CMD_TO_STR.put(CMD_RECEIVE_IKE_PACKET, "Rcv packet");
-        CMD_TO_STR.put(CMD_RECEIVE_PACKET_INVALID_IKE_SPI, "Rcv invalid IKE SPI");
-        CMD_TO_STR.put(CMD_RECEIVE_REQUEST_FOR_CHILD, "Rcv Child request");
-        CMD_TO_STR.put(CMD_OUTBOUND_CHILD_PAYLOADS_READY, "Out child payloads ready");
-        CMD_TO_STR.put(CMD_CHILD_PROCEDURE_FINISHED, "Child procedure finished");
-        CMD_TO_STR.put(CMD_HANDLE_FIRST_CHILD_NEGOTIATION, "Negotiate first Child");
-        CMD_TO_STR.put(CMD_EXECUTE_LOCAL_REQ, "Execute local request");
-        CMD_TO_STR.put(CMD_RETRANSMIT, "Retransmit");
-        CMD_TO_STR.put(CMD_EAP_START_EAP_AUTH, "Start EAP");
-        CMD_TO_STR.put(CMD_EAP_OUTBOUND_MSG_READY, "EAP outbound msg ready");
-        CMD_TO_STR.put(CMD_EAP_ERRORED, "EAP errored");
-        CMD_TO_STR.put(CMD_EAP_FAILED, "EAP failed");
-        CMD_TO_STR.put(CMD_EAP_FINISH_EAP_AUTH, "Finish EAP");
-        CMD_TO_STR.put(CMD_LOCAL_REQUEST_CREATE_IKE, "Create IKE");
-        CMD_TO_STR.put(CMD_LOCAL_REQUEST_DELETE_IKE, "Delete IKE");
-        CMD_TO_STR.put(CMD_LOCAL_REQUEST_REKEY_IKE, "Rekey IKE");
-        CMD_TO_STR.put(CMD_LOCAL_REQUEST_INFO, "Info");
-    }
-
-    private final IkeSessionOptions mIkeSessionOptions;
-
-    /** Map that stores all IkeSaRecords, keyed by locally generated IKE SPI. */
-    private final LongSparseArray<IkeSaRecord> mLocalSpiToIkeSaRecordMap;
-    /**
-     * Map that stores all ChildSessionStateMachines, keyed by remotely generated Child SPI for
-     * sending IPsec packet. Different SPIs may point to the same ChildSessionStateMachine if this
-     * Child Session is doing Rekey.
-     */
-    private final SparseArray<ChildSessionStateMachine> mRemoteSpiToChildSessionMap;
-
-    private final Context mContext;
-    private final IpSecManager mIpSecManager;
-    private final IkeLocalRequestScheduler mScheduler;
-    private final Executor mUserCbExecutor;
-    private final IkeSessionCallback mIkeSessionCallback;
-    private final IkeEapAuthenticatorFactory mEapAuthenticatorFactory;
-    private final TempFailureHandler mTempFailHandler;
-
-    @VisibleForTesting
-    @GuardedBy("mChildCbToSessions")
-    final HashMap<ChildSessionCallback, ChildSessionStateMachine> mChildCbToSessions =
-            new HashMap<>();
-
-    /**
-     * Package private socket that sends and receives encoded IKE message. Initialized in Initial
-     * State.
-     */
-    @VisibleForTesting IkeSocket mIkeSocket;
-
-    /** Local address assigned on device. Initialized in Initial State. */
-    @VisibleForTesting InetAddress mLocalAddress;
-    /** Remote address configured by users. Initialized in Initial State. */
-    @VisibleForTesting InetAddress mRemoteAddress;
-    /** Local port assigned on device. Initialized in Initial State. */
-    @VisibleForTesting int mLocalPort;
-
-    /** Indicates if local node is behind a NAT. */
-    @VisibleForTesting boolean mIsLocalBehindNat;
-    /** Indicates if remote node is behind a NAT. */
-    @VisibleForTesting boolean mIsRemoteBehindNat;
-
-    /** Indicates if both sides support fragmentation. Set in IKE INIT */
-    @VisibleForTesting boolean mSupportFragment;
-
-    /** Package private IkeSaProposal that represents the negotiated IKE SA proposal. */
-    @VisibleForTesting IkeSaProposal mSaProposal;
-
-    @VisibleForTesting IkeCipher mIkeCipher;
-    @VisibleForTesting IkeMacIntegrity mIkeIntegrity;
-    @VisibleForTesting IkeMacPrf mIkePrf;
-
-    // FIXME: b/131265898 Pass these parameters from CreateIkeLocalIkeInit to CreateIkeLocalIkeAuth
-    // as entry data when Android StateMachine can support that.
-    @VisibleForTesting byte[] mIkeInitRequestBytes;
-    @VisibleForTesting byte[] mIkeInitResponseBytes;
-    @VisibleForTesting IkeNoncePayload mIkeInitNoncePayload;
-    @VisibleForTesting IkeNoncePayload mIkeRespNoncePayload;
-
-    // FIXME: b/131265898 Pass these parameters from CreateIkeLocalIkeAuth through to
-    // CreateIkeLocalIkeAuthPostEap as entry data when Android StateMachine can support that.
-    @VisibleForTesting IkeIdPayload mInitIdPayload;
-    @VisibleForTesting IkeIdPayload mRespIdPayload;
-    @VisibleForTesting List<IkePayload> mFirstChildReqList;
-
-    // FIXME: b/131265898 Move into CreateIkeLocalIkeAuth, and pass through to
-    // CreateIkeLocalIkeAuthPostEap once passing entry data is supported
-    private ChildSessionOptions mFirstChildSessionOptions;
-    private ChildSessionCallback mFirstChildCallbacks;
-
-    /** Package */
-    @VisibleForTesting IkeSaRecord mCurrentIkeSaRecord;
-    /** Package */
-    @VisibleForTesting IkeSaRecord mLocalInitNewIkeSaRecord;
-    /** Package */
-    @VisibleForTesting IkeSaRecord mRemoteInitNewIkeSaRecord;
-
-    /** Package */
-    @VisibleForTesting IkeSaRecord mIkeSaRecordSurviving;
-    /** Package */
-    @VisibleForTesting IkeSaRecord mIkeSaRecordAwaitingLocalDel;
-    /** Package */
-    @VisibleForTesting IkeSaRecord mIkeSaRecordAwaitingRemoteDel;
-
-    // States
-    @VisibleForTesting final State mInitial = new Initial();
-    @VisibleForTesting final State mIdle = new Idle();
-    @VisibleForTesting final State mChildProcedureOngoing = new ChildProcedureOngoing();
-    @VisibleForTesting final State mReceiving = new Receiving();
-    @VisibleForTesting final State mCreateIkeLocalIkeInit = new CreateIkeLocalIkeInit();
-    @VisibleForTesting final State mCreateIkeLocalIkeAuth = new CreateIkeLocalIkeAuth();
-    @VisibleForTesting final State mCreateIkeLocalIkeAuthInEap = new CreateIkeLocalIkeAuthInEap();
-
-    @VisibleForTesting
-    final State mCreateIkeLocalIkeAuthPostEap = new CreateIkeLocalIkeAuthPostEap();
-
-    @VisibleForTesting final State mRekeyIkeLocalCreate = new RekeyIkeLocalCreate();
-    @VisibleForTesting final State mSimulRekeyIkeLocalCreate = new SimulRekeyIkeLocalCreate();
-
-    @VisibleForTesting
-    final State mSimulRekeyIkeLocalDeleteRemoteDelete = new SimulRekeyIkeLocalDeleteRemoteDelete();
-
-    @VisibleForTesting final State mSimulRekeyIkeLocalDelete = new SimulRekeyIkeLocalDelete();
-    @VisibleForTesting final State mSimulRekeyIkeRemoteDelete = new SimulRekeyIkeRemoteDelete();
-    @VisibleForTesting final State mRekeyIkeLocalDelete = new RekeyIkeLocalDelete();
-    @VisibleForTesting final State mRekeyIkeRemoteDelete = new RekeyIkeRemoteDelete();
-    @VisibleForTesting final State mDeleteIkeLocalDelete = new DeleteIkeLocalDelete();
-    // TODO: Add InfoLocal.
-
-    /** Constructor for testing. */
-    @VisibleForTesting
-    public IkeSessionStateMachine(
-            Looper looper,
-            Context context,
-            IpSecManager ipSecManager,
-            IkeSessionOptions ikeOptions,
-            ChildSessionOptions firstChildOptions,
-            Executor userCbExecutor,
-            IkeSessionCallback ikeSessionCallback,
-            ChildSessionCallback firstChildSessionCallback,
-            IkeEapAuthenticatorFactory eapAuthenticatorFactory) {
-        super(TAG, looper);
-
-        mIkeSessionOptions = ikeOptions;
-        mEapAuthenticatorFactory = eapAuthenticatorFactory;
-
-        mTempFailHandler = new TempFailureHandler(looper);
-
-        // There are at most three IkeSaRecords co-existing during simultaneous rekeying.
-        mLocalSpiToIkeSaRecordMap = new LongSparseArray<>(3);
-        mRemoteSpiToChildSessionMap = new SparseArray<>();
-
-        mContext = context;
-        mIpSecManager = ipSecManager;
-
-        mUserCbExecutor = userCbExecutor;
-        mIkeSessionCallback = ikeSessionCallback;
-
-        mFirstChildSessionOptions = firstChildOptions;
-        mFirstChildCallbacks = firstChildSessionCallback;
-        registerChildSessionCallback(firstChildOptions, firstChildSessionCallback, true);
-
-        addState(mInitial);
-        addState(mCreateIkeLocalIkeInit);
-        addState(mCreateIkeLocalIkeAuth);
-        addState(mCreateIkeLocalIkeAuthInEap);
-        addState(mCreateIkeLocalIkeAuthPostEap);
-        addState(mIdle);
-        addState(mChildProcedureOngoing);
-        addState(mReceiving);
-        addState(mRekeyIkeLocalCreate);
-        addState(mSimulRekeyIkeLocalCreate, mRekeyIkeLocalCreate);
-        addState(mSimulRekeyIkeLocalDeleteRemoteDelete);
-        addState(mSimulRekeyIkeLocalDelete, mSimulRekeyIkeLocalDeleteRemoteDelete);
-        addState(mSimulRekeyIkeRemoteDelete, mSimulRekeyIkeLocalDeleteRemoteDelete);
-        addState(mRekeyIkeLocalDelete);
-        addState(mRekeyIkeRemoteDelete);
-        addState(mDeleteIkeLocalDelete);
-
-        setInitialState(mInitial);
-        mScheduler =
-                new IkeLocalRequestScheduler(
-                        localReq -> {
-                            sendMessageAtFrontOfQueue(CMD_EXECUTE_LOCAL_REQ, localReq);
-                        });
-
-        start();
-    }
-
-    /** Construct an instance of IkeSessionStateMachine. */
-    public IkeSessionStateMachine(
-            Looper looper,
-            Context context,
-            IpSecManager ipSecManager,
-            IkeSessionOptions ikeOptions,
-            ChildSessionOptions firstChildOptions,
-            Executor userCbExecutor,
-            IkeSessionCallback ikeSessionCallback,
-            ChildSessionCallback firstChildSessionCallback) {
-        this(
-                looper,
-                context,
-                ipSecManager,
-                ikeOptions,
-                firstChildOptions,
-                userCbExecutor,
-                ikeSessionCallback,
-                firstChildSessionCallback,
-                new IkeEapAuthenticatorFactory());
-    }
-
-    private boolean hasChildSessionCallback(ChildSessionCallback callback) {
-        synchronized (mChildCbToSessions) {
-            return mChildCbToSessions.containsKey(callback);
-        }
-    }
-
-    /**
-     * Synchronously builds and registers a child session.
-     *
-     * <p>Setup of the child state machines MUST be done in two stages to ensure that if an external
-     * caller calls openChildSession and then calls closeChildSession before the state machine has
-     * gotten a chance to negotiate the sessions, a valid callback mapping exists (and does not
-     * throw an exception that the callback was not found).
-     *
-     * <p>In the edge case where a child creation fails, and deletes itself, all pending requests
-     * will no longer find the session in the map. Assume it has errored/failed, and skip/ignore.
-     * This is safe, as closeChildSession() (previously) validated that the callback was registered.
-     */
-    @VisibleForTesting
-    void registerChildSessionCallback(
-            ChildSessionOptions childOptions,
-            ChildSessionCallback callbacks,
-            boolean isFirstChild) {
-        synchronized (mChildCbToSessions) {
-            if (!isFirstChild && getCurrentState() == null) {
-                throw new IllegalStateException(
-                        "Request rejected because IKE Session is being closed. ");
-            }
-
-            mChildCbToSessions.put(
-                    callbacks,
-                    ChildSessionStateMachineFactory.makeChildSessionStateMachine(
-                            getHandler().getLooper(),
-                            mContext,
-                            childOptions,
-                            mUserCbExecutor,
-                            callbacks,
-                            new ChildSessionSmCallback()));
-        }
-    }
-
-    /** Initiates IKE setup procedure. */
-    public void openSession() {
-        sendMessage(CMD_LOCAL_REQUEST_CREATE_IKE, new LocalRequest(CMD_LOCAL_REQUEST_CREATE_IKE));
-    }
-
-    /** Schedules a Create Child procedure. */
-    public void openChildSession(
-            ChildSessionOptions childSessionOptions, ChildSessionCallback childSessionCallback) {
-        if (childSessionCallback == null) {
-            throw new IllegalArgumentException("Child Session Callback must be provided");
-        }
-
-        if (hasChildSessionCallback(childSessionCallback)) {
-            throw new IllegalArgumentException("Child Session Callback handle already registered");
-        }
-
-        registerChildSessionCallback(
-                childSessionOptions, childSessionCallback, false /*isFirstChild*/);
-        sendMessage(
-                CMD_LOCAL_REQUEST_CREATE_CHILD,
-                new ChildLocalRequest(
-                        CMD_LOCAL_REQUEST_CREATE_CHILD, childSessionCallback, childSessionOptions));
-    }
-
-    /** Schedules a Delete Child procedure. */
-    public void closeChildSession(ChildSessionCallback childSessionCallback) {
-        if (childSessionCallback == null) {
-            throw new IllegalArgumentException("Child Session Callback must be provided");
-        }
-
-        if (!hasChildSessionCallback(childSessionCallback)) {
-            throw new IllegalArgumentException("Child Session Callback handle not registered");
-        }
-
-        sendMessage(
-                CMD_LOCAL_REQUEST_DELETE_CHILD,
-                new ChildLocalRequest(CMD_LOCAL_REQUEST_DELETE_CHILD, childSessionCallback, null));
-    }
-
-    /** Initiates Delete IKE procedure. */
-    public void closeSession() {
-        sendMessage(CMD_LOCAL_REQUEST_DELETE_IKE, new LocalRequest(CMD_LOCAL_REQUEST_DELETE_IKE));
-    }
-
-    /** Forcibly close IKE Session. */
-    public void killSession() {
-        // TODO: b/142977160 Support closing IKE Sesison immediately.
-    }
-
-    private void scheduleRekeySession(LocalRequest rekeyRequest) {
-        // TODO: Make rekey timeout fuzzy
-        sendMessageDelayed(CMD_LOCAL_REQUEST_REKEY_IKE, rekeyRequest, SA_SOFT_LIFETIME_MS);
-    }
-
-    private void scheduleRetry(LocalRequest localRequest) {
-        sendMessageDelayed(localRequest.procedureType, localRequest, RETRY_INTERVAL_MS);
-    }
-
-    // TODO: Support initiating Delete IKE exchange when IKE SA expires
-
-    // TODO: Add interfaces to initiate IKE exchanges.
-
-    /**
-     * This class is for handling temporary failure.
-     *
-     * <p>Receiving a TEMPORARY_FAILURE is caused by a temporary condition. IKE Session should be
-     * closed if it continues to receive this error after several minutes.
-     */
-    @VisibleForTesting
-    class TempFailureHandler extends Handler {
-        private static final int TEMP_FAILURE_RETRY_TIMEOUT = 1;
-
-        private boolean mTempFailureReceived = false;
-
-        TempFailureHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            if (msg.what == TEMP_FAILURE_RETRY_TIMEOUT) {
-                IOException error =
-                        new IOException(
-                                "Kept receiving TEMPORARY_FAILURE error. State information is out"
-                                        + " of sync.");
-                mUserCbExecutor.execute(
-                        () -> {
-                            mIkeSessionCallback.onClosedExceptionally(
-                                    new IkeInternalException(error));
-                        });
-                loge("Fatal error", error);
-
-                closeAllSaRecords(false /*expectSaClosed*/);
-                quitNow();
-            } else {
-                logWtf("Unknown message.what: " + msg.what);
-            }
-        }
-
-        /** Schedule retry when a request got rejected by TEMPORARY_FAILURE. */
-        public void handleTempFailure(LocalRequest localRequest) {
-            logd(
-                    "TempFailureHandler: Receive TEMPORARY FAILURE. Reschedule request: "
-                            + localRequest.procedureType);
-
-            // TODO: Support customized delay time when this is a rekey request and SA is going to
-            // expire soon.
-            scheduleRetry(localRequest);
-
-            if (!mTempFailureReceived) {
-                sendEmptyMessageDelayed(TEMP_FAILURE_RETRY_TIMEOUT, TEMP_FAILURE_RETRY_TIMEOUT_MS);
-                mTempFailureReceived = true;
-            }
-        }
-
-        /** Stop tracking temporary condition when request was not rejected by TEMPORARY_FAILURE. */
-        public void reset() {
-            logd("TempFailureHandler: Reset Temporary failure retry timeout");
-            removeMessages(TEMP_FAILURE_RETRY_TIMEOUT);
-            mTempFailureReceived = false;
-        }
-    }
-    /**
-     * This class represents a reserved IKE SPI.
-     *
-     * <p>This class is created to avoid assigning same SPI to the same address.
-     *
-     * <p>Objects of this type are used to track reserved IKE SPI to avoid SPI collision. They can
-     * be obtained by calling {@link #allocateSecurityParameterIndex()} and must be released by
-     * calling {@link #close()} when they are no longer needed.
-     *
-     * <p>This class follows the pattern of {@link IpSecManager.SecurityParameterIndex}.
-     *
-     * <p>TODO: Move this class to a central place, like IkeManager.
-     */
-    public static final class IkeSecurityParameterIndex implements AutoCloseable {
-        // Remember assigned IKE SPIs to avoid SPI collision.
-        private static final Set<Pair<InetAddress, Long>> sAssignedIkeSpis = new HashSet<>();
-        private static final int MAX_ASSIGN_IKE_SPI_ATTEMPTS = 100;
-        private static final SecureRandom IKE_SPI_RANDOM = new SecureRandom();
-
-        private final InetAddress mSourceAddress;
-        private final long mSpi;
-        private final CloseGuard mCloseGuard = CloseGuard.get();
-
-        private IkeSecurityParameterIndex(InetAddress sourceAddress, long spi) {
-            mSourceAddress = sourceAddress;
-            mSpi = spi;
-            mCloseGuard.open("close");
-        }
-
-        /**
-         * Get a new IKE SPI and maintain the reservation.
-         *
-         * @return an instance of IkeSecurityParameterIndex.
-         */
-        public static IkeSecurityParameterIndex allocateSecurityParameterIndex(
-                InetAddress sourceAddress) throws IOException {
-            // TODO: Create specific Exception for SPI assigning error.
-
-            for (int i = 0; i < MAX_ASSIGN_IKE_SPI_ATTEMPTS; i++) {
-                long spi = IKE_SPI_RANDOM.nextLong();
-                // Zero value can only be used in the IKE responder SPI field of an IKE INIT
-                // request.
-                if (spi != 0L
-                        && sAssignedIkeSpis.add(new Pair<InetAddress, Long>(sourceAddress, spi))) {
-                    return new IkeSecurityParameterIndex(sourceAddress, spi);
-                }
-            }
-
-            throw new IOException("Failed to generate IKE SPI.");
-        }
-
-        /**
-         * Get a new IKE SPI and maintain the reservation.
-         *
-         * @return an instance of IkeSecurityParameterIndex.
-         */
-        public static IkeSecurityParameterIndex allocateSecurityParameterIndex(
-                InetAddress sourceAddress, long requestedSpi) throws IOException {
-            if (sAssignedIkeSpis.add(new Pair<InetAddress, Long>(sourceAddress, requestedSpi))) {
-                return new IkeSecurityParameterIndex(sourceAddress, requestedSpi);
-            }
-
-            throw new IOException(
-                    "Failed to generate IKE SPI for "
-                            + requestedSpi
-                            + " with source address "
-                            + sourceAddress.getHostAddress());
-        }
-
-        /**
-         * Get the underlying SPI held by this object.
-         *
-         * @return the underlying IKE SPI.
-         */
-        public long getSpi() {
-            return mSpi;
-        }
-
-        /** Release an SPI that was previously reserved. */
-        @Override
-        public void close() {
-            sAssignedIkeSpis.remove(new Pair<InetAddress, Long>(mSourceAddress, mSpi));
-            mCloseGuard.close();
-        }
-
-        /** Check that the IkeSecurityParameterIndex was closed properly. */
-        @Override
-        protected void finalize() throws Throwable {
-            if (mCloseGuard != null) {
-                mCloseGuard.warnIfOpen();
-            }
-            close();
-        }
-    }
-
-    // TODO: Add methods for building and validating general Informational packet.
-
-    @VisibleForTesting
-    void addIkeSaRecord(IkeSaRecord record) {
-        mLocalSpiToIkeSaRecordMap.put(record.getLocalSpi(), record);
-
-        // In IKE_INIT exchange, local SPI was registered with this IkeSessionStateMachine before
-        // IkeSaRecord is created. Calling this method at the end of exchange will double-register
-        // the SPI but it is safe because the key and value are not changed.
-        mIkeSocket.registerIke(record.getLocalSpi(), this);
-
-        scheduleRekeySession(record.getFutureRekeyEvent());
-    }
-
-    @VisibleForTesting
-    void removeIkeSaRecord(IkeSaRecord record) {
-        mIkeSocket.unregisterIke(record.getLocalSpi());
-        mLocalSpiToIkeSaRecordMap.remove(record.getLocalSpi());
-    }
-
-    /**
-     * Receive IKE packet from remote server.
-     *
-     * <p>This method is called synchronously from IkeSocket. It proxies the synchronous call as an
-     * asynchronous job to the IkeSessionStateMachine handler.
-     *
-     * @param ikeHeader the decoded IKE header.
-     * @param ikePacketBytes the byte array of the entire received IKE packet.
-     */
-    public void receiveIkePacket(IkeHeader ikeHeader, byte[] ikePacketBytes) {
-        sendMessage(CMD_RECEIVE_IKE_PACKET, new ReceivedIkePacket(ikeHeader, ikePacketBytes));
-    }
-
-    /**
-     * ReceivedIkePacket is a package private data container consists of decoded IkeHeader and
-     * encoded IKE packet in a byte array.
-     */
-    static class ReceivedIkePacket {
-        /** Decoded IKE header */
-        public final IkeHeader ikeHeader;
-        /** Entire encoded IKE message including IKE header */
-        public final byte[] ikePacketBytes;
-
-        ReceivedIkePacket(IkeHeader ikeHeader, byte[] ikePacketBytes) {
-            this.ikeHeader = ikeHeader;
-            this.ikePacketBytes = ikePacketBytes;
-        }
-    }
-
-    /** Class to group parameters for negotiating the first Child SA. */
-    private static class FirstChildNegotiationData {
-        public final ChildSessionOptions childSessionOptions;
-        public final ChildSessionCallback childSessionCallback;
-        public final List<IkePayload> reqPayloads;
-        public final List<IkePayload> respPayloads;
-
-        FirstChildNegotiationData(
-                ChildSessionOptions childSessionOptions,
-                ChildSessionCallback childSessionCallback,
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads) {
-            this.childSessionOptions = childSessionOptions;
-            this.childSessionCallback = childSessionCallback;
-            this.reqPayloads = reqPayloads;
-            this.respPayloads = respPayloads;
-        }
-    }
-
-    /** Class to group parameters for building an outbound message for ChildSessions. */
-    private static class ChildOutboundData {
-        @ExchangeType public final int exchangeType;
-        public final boolean isResp;
-        public final List<IkePayload> payloadList;
-        public final ChildSessionStateMachine childSession;
-
-        ChildOutboundData(
-                @ExchangeType int exchangeType,
-                boolean isResp,
-                List<IkePayload> payloadList,
-                ChildSessionStateMachine childSession) {
-            this.exchangeType = exchangeType;
-            this.isResp = isResp;
-            this.payloadList = payloadList;
-            this.childSession = childSession;
-        }
-    }
-
-    /** Callback for ChildSessionStateMachine to notify IkeSessionStateMachine. */
-    @VisibleForTesting
-    class ChildSessionSmCallback implements ChildSessionStateMachine.IChildSessionSmCallback {
-        @Override
-        public void onChildSaCreated(int remoteSpi, ChildSessionStateMachine childSession) {
-            mRemoteSpiToChildSessionMap.put(remoteSpi, childSession);
-        }
-
-        @Override
-        public void onChildSaDeleted(int remoteSpi) {
-            mRemoteSpiToChildSessionMap.remove(remoteSpi);
-        }
-
-        @Override
-        public void scheduleLocalRequest(ChildLocalRequest futureRequest, long delayedTime) {
-            sendMessageDelayed(futureRequest.procedureType, futureRequest, delayedTime);
-        }
-
-        @Override
-        public void scheduleRetryLocalRequest(ChildLocalRequest childRequest) {
-            scheduleRetry(childRequest);
-        }
-
-        @Override
-        public void onOutboundPayloadsReady(
-                @ExchangeType int exchangeType,
-                boolean isResp,
-                List<IkePayload> payloadList,
-                ChildSessionStateMachine childSession) {
-            sendMessage(
-                    CMD_OUTBOUND_CHILD_PAYLOADS_READY,
-                    new ChildOutboundData(exchangeType, isResp, payloadList, childSession));
-        }
-
-        @Override
-        public void onProcedureFinished(ChildSessionStateMachine childSession) {
-            if (getHandler() == null) {
-                // If the state machine has quit (because IKE Session is being closed), do not send
-                // any message.
-                return;
-            }
-
-            sendMessage(CMD_CHILD_PROCEDURE_FINISHED, childSession);
-        }
-
-        @Override
-        public void onChildSessionClosed(ChildSessionCallback userCallbacks) {
-            synchronized (mChildCbToSessions) {
-                mChildCbToSessions.remove(userCallbacks);
-            }
-        }
-
-        @Override
-        public void onFatalIkeSessionError(boolean needsNotifyRemote) {
-            // TODO: If needsNotifyRemote is true, send a Delete IKE request and then kill the IKE
-            // Session. Otherwise, directly kill the IKE Session.
-        }
-    }
-
-    /** Top level state for handling uncaught exceptions for all subclasses. */
-    abstract class ExceptionHandler extends ExceptionHandlerBase {
-        @Override
-        protected void cleanUpAndQuit(RuntimeException e) {
-            // Clean up all SaRecords.
-            closeAllSaRecords(false /*expectSaClosed*/);
-
-            mUserCbExecutor.execute(
-                    () -> {
-                        mIkeSessionCallback.onClosedExceptionally(new IkeInternalException(e));
-                    });
-            logWtf("Unexpected exception in " + getCurrentState().getName(), e);
-            quitNow();
-        }
-
-        @Override
-        protected String getCmdString(int cmd) {
-            return CMD_TO_STR.get(cmd);
-        }
-    }
-
-    /** Called when this StateMachine quits. */
-    @Override
-    protected void onQuitting() {
-        // Clean up all SaRecords.
-        closeAllSaRecords(true /*expectSaClosed*/);
-
-        synchronized (mChildCbToSessions) {
-            for (ChildSessionStateMachine child : mChildCbToSessions.values()) {
-                // Fire asynchronous call for Child Sessions to do cleanup and remove itself
-                // from the map.
-                child.killSession();
-            }
-        }
-
-        if (mIkeSocket == null) return;
-        mIkeSocket.releaseReference(this);
-    }
-
-    private void closeAllSaRecords(boolean expectSaClosed) {
-        closeIkeSaRecord(mCurrentIkeSaRecord, expectSaClosed);
-        closeIkeSaRecord(mLocalInitNewIkeSaRecord, expectSaClosed);
-        closeIkeSaRecord(mRemoteInitNewIkeSaRecord, expectSaClosed);
-
-        mCurrentIkeSaRecord = null;
-        mLocalInitNewIkeSaRecord = null;
-        mRemoteInitNewIkeSaRecord = null;
-    }
-
-    private void closeIkeSaRecord(IkeSaRecord ikeSaRecord, boolean expectSaClosed) {
-        if (ikeSaRecord == null) return;
-
-        removeIkeSaRecord(ikeSaRecord);
-        ikeSaRecord.close();
-
-        if (!expectSaClosed) return;
-
-        logWtf(
-                "IkeSaRecord with local SPI: "
-                        + ikeSaRecord.getLocalSpi()
-                        + " is not correctly closed.");
-    }
-
-    private void handleIkeFatalError(Exception error) {
-        IkeException ikeException =
-                error instanceof IkeException
-                        ? (IkeException) error
-                        : new IkeInternalException(error);
-
-        // Clean up all SaRecords.
-        closeAllSaRecords(false /*expectSaClosed*/);
-        mUserCbExecutor.execute(
-                () -> {
-                    mIkeSessionCallback.onClosedExceptionally(ikeException);
-                });
-        loge("IKE Session fatal error in " + getCurrentState().getName(), ikeException);
-
-        quitNow();
-    }
-
-    /** Initial state of IkeSessionStateMachine. */
-    class Initial extends ExceptionHandler {
-        @Override
-        public void enterState() {
-            try {
-                mRemoteAddress = mIkeSessionOptions.getServerAddress();
-
-                boolean isIpv4 = mRemoteAddress instanceof Inet4Address;
-                FileDescriptor sock =
-                        Os.socket(
-                                isIpv4 ? OsConstants.AF_INET : OsConstants.AF_INET6,
-                                OsConstants.SOCK_DGRAM,
-                                OsConstants.IPPROTO_UDP);
-                Os.connect(sock, mRemoteAddress, IkeSocket.IKE_SERVER_PORT);
-                InetSocketAddress localAddr = (InetSocketAddress) Os.getsockname(sock);
-                mLocalAddress = localAddr.getAddress();
-                mLocalPort = localAddr.getPort();
-                Os.close(sock);
-
-                mIkeSocket =
-                        IkeSocket.getIkeSocket(
-                                mIkeSessionOptions.getUdpEncapsulationSocket(),
-                                IkeSessionStateMachine.this);
-            } catch (ErrnoException | SocketException e) {
-                handleIkeFatalError(e);
-            }
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_LOCAL_REQUEST_CREATE_IKE:
-                    transitionTo(mCreateIkeLocalIkeInit);
-                    return HANDLED;
-                case CMD_FORCE_TRANSITION:
-                    transitionTo((State) message.obj);
-                    return HANDLED;
-                default:
-                    return NOT_HANDLED;
-            }
-        }
-    }
-
-    /**
-     * Idle represents a state when there is no ongoing IKE exchange affecting established IKE SA.
-     */
-    class Idle extends LocalRequestQueuer {
-        @Override
-        public void enterState() {
-            mScheduler.readyForNextProcedure();
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_RECEIVE_IKE_PACKET:
-                    deferMessage(message);
-                    transitionTo(mReceiving);
-                    return HANDLED;
-
-                case CMD_FORCE_TRANSITION: // Testing command
-                    transitionTo((State) message.obj);
-                    return HANDLED;
-
-                case CMD_EXECUTE_LOCAL_REQ:
-                    executeLocalRequest((LocalRequest) message.obj, message);
-                    return HANDLED;
-
-                default:
-                    // Queue local requests, and trigger next procedure
-                    if (isLocalRequest(message.what)) {
-                        handleLocalRequest(message.what, (LocalRequest) message.obj);
-
-                        // Synchronously calls through to the scheduler callback, which will
-                        // post the CMD_EXECUTE_LOCAL_REQ to the front of the queue, ensuring
-                        // it is always the next request processed.
-                        mScheduler.readyForNextProcedure();
-                        return HANDLED;
-                    }
-                    return NOT_HANDLED;
-            }
-        }
-
-        private void executeLocalRequest(LocalRequest req, Message message) {
-            switch (req.procedureType) {
-                case CMD_LOCAL_REQUEST_REKEY_IKE:
-                    transitionTo(mRekeyIkeLocalCreate);
-                    break;
-                case CMD_LOCAL_REQUEST_DELETE_IKE:
-                    transitionTo(mDeleteIkeLocalDelete);
-                    break;
-                case CMD_LOCAL_REQUEST_CREATE_CHILD: // fallthrough
-                case CMD_LOCAL_REQUEST_REKEY_CHILD: // fallthrough
-                case CMD_LOCAL_REQUEST_DELETE_CHILD:
-                    deferMessage(message);
-                    transitionTo(mChildProcedureOngoing);
-                    break;
-                default:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Invalid local request procedure type: " + req.procedureType));
-            }
-        }
-    }
-
-    /**
-     * Gets IKE exchange subtype of a inbound IKE request message.
-     *
-     * <p>Knowing IKE exchange subtype of a inbound IKE request message helps IkeSessionStateMachine
-     * to validate this request using the specific rule.
-     *
-     * <p>It is not allowed to obtain exchange subtype from a inbound response message for two
-     * reasons. Firstly, the exchange subtype of a response message is the same with its
-     * corresponding request message. Secondly, trying to get the exchange subtype from a response
-     * message will easily fail when the response message contains only error notification payloads.
-     *
-     * @param ikeMessage inbound request IKE message to check.
-     * @return IKE exchange subtype.
-     */
-    @IkeExchangeSubType
-    private static int getIkeExchangeSubType(IkeMessage ikeMessage) {
-        IkeHeader ikeHeader = ikeMessage.ikeHeader;
-        if (ikeHeader.isResponseMsg) {
-            throw new IllegalStateException("IKE Exchange subtype invalid for response messages.");
-        }
-
-        switch (ikeHeader.exchangeType) {
-                // DPD omitted - should never be handled via handleRequestIkeMessage()
-            case IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT:
-                return IKE_EXCHANGE_SUBTYPE_IKE_INIT;
-            case IkeHeader.EXCHANGE_TYPE_IKE_AUTH:
-                return IKE_EXCHANGE_SUBTYPE_IKE_AUTH;
-            case IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA:
-                // It is guaranteed in the decoding process that SA Payload has at least one SA
-                // Proposal. Since Rekey IKE and Create Child (both initial creation and rekey
-                // creation) will cause a collision, although the RFC 7296 does not prohibit one SA
-                // Payload to contain both IKE proposals and Child proposals, containing two types
-                // does not make sense. IKE libary will reply according to the first SA Proposal
-                // type and ignore the other type.
-                IkeSaPayload saPayload =
-                        ikeMessage.getPayloadForType(
-                                IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-                if (saPayload == null) {
-                    return IKE_EXCHANGE_SUBTYPE_INVALID;
-                }
-
-                // If the received message has both SA(IKE) Payload and Notify-Rekey Payload, IKE
-                // library will treat it as a Rekey IKE request and ignore the Notify-Rekey
-                // Payload to provide better interoperability.
-                if (saPayload.proposalList.get(0).protocolId == IkePayload.PROTOCOL_ID_IKE) {
-                    return IKE_EXCHANGE_SUBTYPE_REKEY_IKE;
-                }
-
-                // If a Notify-Rekey Payload is found, this message is for rekeying a Child SA.
-                List<IkeNotifyPayload> notifyPayloads =
-                        ikeMessage.getPayloadListForType(
-                                IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-
-                // It is checked during decoding that there is at most one Rekey notification
-                // payload.
-                for (IkeNotifyPayload notifyPayload : notifyPayloads) {
-                    if (notifyPayload.notifyType == IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA) {
-                        return IKE_EXCHANGE_SUBTYPE_REKEY_CHILD;
-                    }
-                }
-
-                return IKE_EXCHANGE_SUBTYPE_CREATE_CHILD;
-            case IkeHeader.EXCHANGE_TYPE_INFORMATIONAL:
-                List<IkeDeletePayload> deletePayloads =
-                        ikeMessage.getPayloadListForType(
-                                IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class);
-
-                // If no Delete payload was found, this request is a generic informational request.
-                if (deletePayloads.isEmpty()) return IKE_EXCHANGE_SUBTYPE_GENERIC_INFO;
-
-                // IKEv2 protocol does not clearly disallow to have both a Delete IKE payload and a
-                // Delete Child payload in one IKE message. In this case, IKE library will only
-                // respond to the Delete IKE payload.
-                for (IkeDeletePayload deletePayload : deletePayloads) {
-                    if (deletePayload.protocolId == IkePayload.PROTOCOL_ID_IKE) {
-                        return IKE_EXCHANGE_SUBTYPE_DELETE_IKE;
-                    }
-                }
-                return IKE_EXCHANGE_SUBTYPE_DELETE_CHILD;
-            default:
-                throw new IllegalStateException(
-                        "Unrecognized exchange type in the validated IKE header: "
-                                + ikeHeader.exchangeType);
-        }
-    }
-
-    // Sends the provided IkeMessage using the current IKE SA record
-    @VisibleForTesting
-    void sendEncryptedIkeMessage(IkeMessage msg) {
-        sendEncryptedIkeMessage(mCurrentIkeSaRecord, msg);
-    }
-
-    // Sends the provided IkeMessage using the provided IKE SA record
-    @VisibleForTesting
-    void sendEncryptedIkeMessage(IkeSaRecord ikeSaRecord, IkeMessage msg) {
-        byte[][] packetList =
-                msg.encryptAndEncode(
-                        mIkeIntegrity,
-                        mIkeCipher,
-                        ikeSaRecord,
-                        mSupportFragment,
-                        DEFAULT_FRAGMENT_SIZE);
-        for (byte[] packet : packetList) {
-            mIkeSocket.sendIkePacket(packet, mRemoteAddress);
-        }
-        if (msg.ikeHeader.isResponseMsg) {
-            ikeSaRecord.updateLastSentRespAllPackets(Arrays.asList(packetList));
-        }
-    }
-
-    // Builds and sends IKE-level error notification response on the provided IKE SA record
-    @VisibleForTesting
-    void buildAndSendErrorNotificationResponse(
-            IkeSaRecord ikeSaRecord, int messageId, @ErrorType int errorType) {
-        IkeNotifyPayload error = new IkeNotifyPayload(errorType);
-        buildAndSendNotificationResponse(ikeSaRecord, messageId, error);
-    }
-
-    // Builds and sends error notification response on the provided IKE SA record
-    @VisibleForTesting
-    void buildAndSendNotificationResponse(
-            IkeSaRecord ikeSaRecord, int messageId, IkeNotifyPayload notifyPayload) {
-        IkeMessage msg =
-                buildEncryptedNotificationMessage(
-                        ikeSaRecord,
-                        new IkeInformationalPayload[] {notifyPayload},
-                        EXCHANGE_TYPE_INFORMATIONAL,
-                        true /*isResponse*/,
-                        messageId);
-
-        sendEncryptedIkeMessage(ikeSaRecord, msg);
-    }
-
-    // Builds an Encrypted IKE Informational Message for the given IkeInformationalPayload using the
-    // current IKE SA record.
-    @VisibleForTesting
-    IkeMessage buildEncryptedInformationalMessage(
-            IkeInformationalPayload[] payloads, boolean isResponse, int messageId) {
-        return buildEncryptedInformationalMessage(
-                mCurrentIkeSaRecord, payloads, isResponse, messageId);
-    }
-
-    // Builds an Encrypted IKE Informational Message for the given IkeInformationalPayload using the
-    // provided IKE SA record.
-    @VisibleForTesting
-    IkeMessage buildEncryptedInformationalMessage(
-            IkeSaRecord saRecord,
-            IkeInformationalPayload[] payloads,
-            boolean isResponse,
-            int messageId) {
-        return buildEncryptedNotificationMessage(
-                saRecord, payloads, IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, isResponse, messageId);
-    }
-
-    // Builds an Encrypted IKE Message for the given IkeInformationalPayload using the provided IKE
-    // SA record and exchange type.
-    @VisibleForTesting
-    IkeMessage buildEncryptedNotificationMessage(
-            IkeSaRecord saRecord,
-            IkeInformationalPayload[] payloads,
-            @ExchangeType int exchangeType,
-            boolean isResponse,
-            int messageId) {
-        IkeHeader header =
-                new IkeHeader(
-                        saRecord.getInitiatorSpi(),
-                        saRecord.getResponderSpi(),
-                        IkePayload.PAYLOAD_TYPE_SK,
-                        exchangeType,
-                        isResponse /*isResponseMsg*/,
-                        saRecord.isLocalInit /*fromIkeInitiator*/,
-                        messageId);
-
-        return new IkeMessage(header, Arrays.asList(payloads));
-    }
-
-    private abstract class LocalRequestQueuer extends ExceptionHandler {
-        /**
-         * Reroutes all local requests to the scheduler
-         *
-         * @param requestVal The command value of the request
-         * @param req The instance of the LocalRequest to be queued.
-         */
-        protected void handleLocalRequest(int requestVal, LocalRequest req) {
-            if (req.isCancelled()) return;
-
-            switch (requestVal) {
-                case CMD_LOCAL_REQUEST_DELETE_IKE:
-                    mScheduler.addRequestAtFront(req);
-                    return;
-
-                case CMD_LOCAL_REQUEST_REKEY_IKE: // Fallthrough
-                case CMD_LOCAL_REQUEST_INFO:
-                    mScheduler.addRequest(req);
-                    return;
-
-                case CMD_LOCAL_REQUEST_CREATE_CHILD: // Fallthrough
-                case CMD_LOCAL_REQUEST_REKEY_CHILD: // Fallthrough
-                case CMD_LOCAL_REQUEST_DELETE_CHILD:
-                    ChildLocalRequest childReq = (ChildLocalRequest) req;
-                    if (childReq.procedureType != requestVal) {
-                        cleanUpAndQuit(
-                                new IllegalArgumentException(
-                                        "ChildLocalRequest procedure type was invalid"));
-                    }
-                    mScheduler.addRequest(childReq);
-                    return;
-
-                default:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Unknown local request passed to handleLocalRequest"));
-            }
-        }
-
-        /** Check if received signal is a local request. */
-        protected boolean isLocalRequest(int msgWhat) {
-            if ((msgWhat >= CMD_IKE_LOCAL_REQUEST_BASE
-                            && msgWhat < CMD_IKE_LOCAL_REQUEST_BASE + CMD_CATEGORY_SIZE)
-                    || (msgWhat >= CMD_CHILD_LOCAL_REQUEST_BASE
-                            && msgWhat < CMD_CHILD_LOCAL_REQUEST_BASE + CMD_CATEGORY_SIZE)) {
-                return true;
-            }
-            return false;
-        }
-    }
-
-    /**
-     * Base state defines common behaviours when receiving an IKE packet.
-     *
-     * <p>State that represents an ongoing IKE procedure MUST extend BusyState to handle received
-     * IKE packet. Idle state will defer the received packet to a BusyState to process it.
-     */
-    private abstract class BusyState extends LocalRequestQueuer {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_RECEIVE_IKE_PACKET:
-                    handleReceivedIkePacket(message);
-                    return HANDLED;
-
-                case CMD_FORCE_TRANSITION:
-                    transitionTo((State) message.obj);
-                    return HANDLED;
-
-                case CMD_EXECUTE_LOCAL_REQ:
-                    logWtf("Invalid execute local request command in non-idle state");
-                    return NOT_HANDLED;
-
-                case CMD_RETRANSMIT:
-                    triggerRetransmit();
-                    return HANDLED;
-
-                default:
-                    // Queue local requests, and trigger next procedure
-                    if (isLocalRequest(message.what)) {
-                        handleLocalRequest(message.what, (LocalRequest) message.obj);
-                        return HANDLED;
-                    }
-                    return NOT_HANDLED;
-            }
-        }
-
-        /**
-         * Handler for retransmission timer firing
-         *
-         * <p>By default, the trigger is logged and dropped. States that have a retransmitter should
-         * override this function, and proxy the call to Retransmitter.retransmit()
-         */
-        protected void triggerRetransmit() {
-            logWtf("Retransmission trigger dropped in state: " + this.getClass().getSimpleName());
-        }
-
-        protected IkeSaRecord getIkeSaRecordForPacket(IkeHeader ikeHeader) {
-            if (ikeHeader.fromIkeInitiator) {
-                return mLocalSpiToIkeSaRecordMap.get(ikeHeader.ikeResponderSpi);
-            } else {
-                return mLocalSpiToIkeSaRecordMap.get(ikeHeader.ikeInitiatorSpi);
-            }
-        }
-
-        protected void handleReceivedIkePacket(Message message) {
-            // TODO: b/138411550 Notify subclasses when discarding a received packet. Receiving MUST
-            // go back to Idle state in this case.
-
-            String methodTag = "handleReceivedIkePacket: ";
-
-            ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
-            IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
-            byte[] ikePacketBytes = receivedIkePacket.ikePacketBytes;
-            IkeSaRecord ikeSaRecord = getIkeSaRecordForPacket(ikeHeader);
-
-            String msgDirection = ikeHeader.isResponseMsg ? "response" : "request";
-
-            // Drop packets that we don't have an SA for:
-            if (ikeSaRecord == null) {
-                // TODO: Print a summary of the IKE message (perhaps the IKE header)
-                cleanUpAndQuit(
-                        new IllegalStateException(
-                                "Received an IKE "
-                                        + msgDirection
-                                        + "but found no matching SA for it"));
-                return;
-            }
-
-            logd(
-                    methodTag
-                            + "Received an "
-                            + ikeHeader.getBasicInfoString()
-                            + " on IKE SA with local SPI: "
-                            + ikeSaRecord.getLocalSpi()
-                            + ". Packet size: "
-                            + ikePacketBytes.length);
-
-            if (ikeHeader.isResponseMsg) {
-                int expectedMsgId = ikeSaRecord.getLocalRequestMessageId();
-                if (expectedMsgId - 1 == ikeHeader.messageId) {
-                    logd(methodTag + "Received re-transmitted response. Discard it.");
-                    return;
-                }
-
-                DecodeResult decodeResult =
-                        IkeMessage.decode(
-                                expectedMsgId,
-                                mIkeIntegrity,
-                                mIkeCipher,
-                                ikeSaRecord,
-                                ikeHeader,
-                                ikePacketBytes,
-                                ikeSaRecord.getCollectedFragments(true /*isResp*/));
-                switch (decodeResult.status) {
-                    case DECODE_STATUS_OK:
-                        ikeSaRecord.incrementLocalRequestMessageId();
-                        ikeSaRecord.resetCollectedFragments(true /*isResp*/);
-
-                        DecodeResultOk resultOk = (DecodeResultOk) decodeResult;
-                        if (isTempFailure(resultOk.ikeMessage)) {
-                            handleTempFailure();
-                        } else {
-                            mTempFailHandler.reset();
-                        }
-
-                        handleResponseIkeMessage(resultOk.ikeMessage);
-                        break;
-                    case DECODE_STATUS_PARTIAL:
-                        ikeSaRecord.updateCollectedFragments(
-                                (DecodeResultPartial) decodeResult, true /*isResp*/);
-                        break;
-                    case DECODE_STATUS_PROTECTED_ERROR:
-                        IkeException ikeException = ((DecodeResultError) decodeResult).ikeException;
-                        logi(methodTag + "Protected error", ikeException);
-
-                        ikeSaRecord.incrementLocalRequestMessageId();
-                        ikeSaRecord.resetCollectedFragments(true /*isResp*/);
-
-                        handleResponseGenericProcessError(
-                                ikeSaRecord,
-                                new InvalidSyntaxException(
-                                        "Generic processing error in the received response",
-                                        ikeException));
-                        break;
-                    case DECODE_STATUS_UNPROTECTED_ERROR:
-                        logi(
-                                methodTag
-                                        + "Message authentication or decryption failed on received"
-                                        + " response. Discard it",
-                                ((DecodeResultError) decodeResult).ikeException);
-                        break;
-                    default:
-                        cleanUpAndQuit(
-                                new IllegalStateException(
-                                        "Unrecognized decoding status: " + decodeResult.status));
-                }
-
-            } else {
-                int expectedMsgId = ikeSaRecord.getRemoteRequestMessageId();
-                if (expectedMsgId - 1 == ikeHeader.messageId) {
-
-                    if (ikeSaRecord.isRetransmittedRequest(ikePacketBytes)) {
-                        logd("Received re-transmitted request. Retransmitting response");
-
-                        for (byte[] packet : ikeSaRecord.getLastSentRespAllPackets()) {
-                            mIkeSocket.sendIkePacket(packet, mRemoteAddress);
-                        }
-
-                        // TODO:Support resetting remote rekey delete timer.
-                    } else {
-                        logi(methodTag + "Received response with invalid message ID. Discard it.");
-                    }
-                } else {
-                    DecodeResult decodeResult =
-                            IkeMessage.decode(
-                                    expectedMsgId,
-                                    mIkeIntegrity,
-                                    mIkeCipher,
-                                    ikeSaRecord,
-                                    ikeHeader,
-                                    ikePacketBytes,
-                                    ikeSaRecord.getCollectedFragments(false /*isResp*/));
-                    switch (decodeResult.status) {
-                        case DECODE_STATUS_OK:
-                            ikeSaRecord.incrementRemoteRequestMessageId();
-                            ikeSaRecord.resetCollectedFragments(false /*isResp*/);
-
-                            DecodeResultOk resultOk = (DecodeResultOk) decodeResult;
-                            IkeMessage ikeMessage = resultOk.ikeMessage;
-                            ikeSaRecord.updateLastReceivedReqFirstPacket(resultOk.firstPacket);
-
-                            // Handle DPD here.
-                            if (ikeMessage.isDpdRequest()) {
-                                logd(methodTag + "Received DPD request");
-                                IkeMessage dpdResponse =
-                                        buildEncryptedInformationalMessage(
-                                                ikeSaRecord,
-                                                new IkeInformationalPayload[] {},
-                                                true,
-                                                ikeHeader.messageId);
-                                sendEncryptedIkeMessage(ikeSaRecord, dpdResponse);
-                                break;
-                            }
-
-                            int ikeExchangeSubType = getIkeExchangeSubType(ikeMessage);
-                            logd(
-                                    methodTag
-                                            + "Request exchange subtype: "
-                                            + EXCHANGE_SUBTYPE_TO_STRING.get(ikeExchangeSubType));
-
-                            if (ikeExchangeSubType == IKE_EXCHANGE_SUBTYPE_INVALID
-                                    || ikeExchangeSubType == IKE_EXCHANGE_SUBTYPE_IKE_INIT
-                                    || ikeExchangeSubType == IKE_EXCHANGE_SUBTYPE_IKE_AUTH) {
-
-                                // Reply with INVALID_SYNTAX and close IKE Session.
-                                buildAndSendErrorNotificationResponse(
-                                        mCurrentIkeSaRecord,
-                                        ikeHeader.messageId,
-                                        ERROR_TYPE_INVALID_SYNTAX);
-                                handleIkeFatalError(
-                                        new InvalidSyntaxException(
-                                                "Cannot handle message with invalid or unexpected"
-                                                        + " IkeExchangeSubType: "
-                                                        + ikeExchangeSubType));
-                                return;
-                            }
-                            handleRequestIkeMessage(ikeMessage, ikeExchangeSubType, message);
-                            break;
-                        case DECODE_STATUS_PARTIAL:
-                            ikeSaRecord.updateCollectedFragments(
-                                    (DecodeResultPartial) decodeResult, false /*isResp*/);
-                            break;
-                        case DECODE_STATUS_PROTECTED_ERROR:
-                            DecodeResultProtectedError resultError =
-                                    (DecodeResultProtectedError) decodeResult;
-
-                            IkeException ikeException = resultError.ikeException;
-                            logi(methodTag + "Protected error", resultError.ikeException);
-
-                            ikeSaRecord.incrementRemoteRequestMessageId();
-                            ikeSaRecord.resetCollectedFragments(false /*isResp*/);
-
-                            ikeSaRecord.updateLastReceivedReqFirstPacket(resultError.firstPacket);
-
-                            // IkeException MUST be already wrapped into an IkeProtocolException
-                            handleRequestGenericProcessError(
-                                    ikeSaRecord,
-                                    ikeHeader.messageId,
-                                    (IkeProtocolException) ikeException);
-                            break;
-                        case DECODE_STATUS_UNPROTECTED_ERROR:
-                            logi(
-                                    methodTag
-                                            + "Message authentication or decryption failed on"
-                                            + " received request. Discard it",
-                                    ((DecodeResultError) decodeResult).ikeException);
-                            break;
-                        default:
-                            cleanUpAndQuit(
-                                    new IllegalStateException(
-                                            "Unrecognized decoding status: "
-                                                    + decodeResult.status));
-                    }
-                }
-            }
-        }
-
-        private boolean isTempFailure(IkeMessage message) {
-            List<IkeNotifyPayload> notifyPayloads =
-                    message.getPayloadListForType(PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-
-            for (IkeNotifyPayload notify : notifyPayloads) {
-                if (notify.notifyType == ERROR_TYPE_TEMPORARY_FAILURE) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        protected void handleTempFailure() {
-            // Log and close IKE Session due to unexpected TEMPORARY_FAILURE. This error should
-            // only occur during CREATE_CHILD_SA exchange.
-            handleIkeFatalError(
-                    new InvalidSyntaxException("Received unexpected TEMPORARY_FAILURE"));
-
-            // States that accept a TEMPORARY MUST override this method to schedule a retry.
-        }
-
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            // Subclasses MUST override it if they care
-            cleanUpAndQuit(
-                    new IllegalStateException(
-                            "Do not support handling an encrypted request: " + ikeExchangeSubType));
-        }
-
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            // Subclasses MUST override it if they care
-            cleanUpAndQuit(
-                    new IllegalStateException("Do not support handling an encrypted response"));
-        }
-
-        /**
-         * Method for handling generic processing error of a request.
-         *
-         * <p>A generic processing error is usally syntax error, unsupported critical payload error
-         * and major version error. IKE SA that should reply with corresponding error notifications
-         */
-        protected void handleRequestGenericProcessError(
-                IkeSaRecord ikeSaRecord, int messageId, IkeProtocolException exception) {
-            IkeNotifyPayload errNotify = exception.buildNotifyPayload();
-            sendEncryptedIkeMessage(
-                    ikeSaRecord,
-                    buildEncryptedInformationalMessage(
-                            ikeSaRecord,
-                            new IkeInformationalPayload[] {errNotify},
-                            true /*isResponse*/,
-                            messageId));
-
-            // Receiver of INVALID_SYNTAX error notification should delete the IKE SA
-            if (exception.getErrorType() == ERROR_TYPE_INVALID_SYNTAX) {
-                handleIkeFatalError(exception);
-            }
-        }
-
-        /**
-         * Method for handling generic processing error of a response.
-         *
-         * <p>Detailed error is wrapped in the InvalidSyntaxException, which is usally syntax error,
-         * unsupported critical payload error and major version error. IKE SA that receives a
-         * response with these errors should be closed.
-         */
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException ikeException) {
-            // Subclasses MUST override it if they care
-            cleanUpAndQuit(
-                    new IllegalStateException(
-                            "Do not support handling generic processing error of encrypted"
-                                    + " response"));
-        }
-    }
-
-    /**
-     * Retransmitter represents a RAII class to send the initial request, and retransmit as needed.
-     *
-     * <p>The Retransmitter class will automatically start transmission upon creation.
-     */
-    @VisibleForTesting
-    class EncryptedRetransmitter extends Retransmitter {
-        private final IkeSaRecord mIkeSaRecord;
-
-        @VisibleForTesting
-        EncryptedRetransmitter(IkeMessage msg) {
-            this(mCurrentIkeSaRecord, msg);
-        }
-
-        private EncryptedRetransmitter(IkeSaRecord ikeSaRecord, IkeMessage msg) {
-            super(getHandler(), msg);
-
-            mIkeSaRecord = ikeSaRecord;
-
-            retransmit();
-        }
-
-        @Override
-        public void send(IkeMessage msg) {
-            sendEncryptedIkeMessage(mIkeSaRecord, msg);
-        }
-
-        @Override
-        public void handleRetransmissionFailure() {
-            handleIkeFatalError(new IOException("Retransmitting failure"));
-        }
-    }
-
-    /**
-     * DeleteResponderBase represents all states after IKE_INIT and IKE_AUTH.
-     *
-     * <p>All post-init states share common functionality of being able to respond to IKE_DELETE
-     * requests.
-     */
-    private abstract class DeleteResponderBase extends BusyState {
-        /** Builds a IKE Delete Response for the given IKE SA and request. */
-        protected IkeMessage buildIkeDeleteResp(IkeMessage req, IkeSaRecord ikeSaRecord) {
-            IkeInformationalPayload[] payloads = new IkeInformationalPayload[] {};
-            return buildEncryptedInformationalMessage(
-                    ikeSaRecord, payloads, true /* isResp */, req.ikeHeader.messageId);
-        }
-
-        /**
-         * Validates that the delete request is acceptable.
-         *
-         * <p>The request message must be guaranteed by previous checks to be of SUBTYPE_DELETE_IKE,
-         * and therefore contains an IkeDeletePayload. This is checked in getIkeExchangeSubType.
-         */
-        protected void validateIkeDeleteReq(IkeMessage req, IkeSaRecord expectedRecord)
-                throws InvalidSyntaxException {
-            if (expectedRecord != getIkeSaRecordForPacket(req.ikeHeader)) {
-                throw new InvalidSyntaxException("Delete request received in wrong SA");
-            }
-        }
-
-        /**
-         * Helper method for responding to a session deletion request
-         *
-         * <p>Note that this method expects that the session is keyed on the current IKE SA session,
-         * and closing the IKE SA indicates that the remote wishes to end the session as a whole. As
-         * such, this should not be used in rekey cases where there is any ambiguity as to which IKE
-         * SA the session is reliant upon.
-         *
-         * <p>Note that this method will also quit the state machine.
-         *
-         * @param ikeMessage The received session deletion request
-         */
-        protected void handleDeleteSessionRequest(IkeMessage ikeMessage) {
-            try {
-                validateIkeDeleteReq(ikeMessage, mCurrentIkeSaRecord);
-                IkeMessage resp = buildIkeDeleteResp(ikeMessage, mCurrentIkeSaRecord);
-
-                mUserCbExecutor.execute(
-                        () -> {
-                            mIkeSessionCallback.onClosed();
-                        });
-
-                sendEncryptedIkeMessage(mCurrentIkeSaRecord, resp);
-
-                removeIkeSaRecord(mCurrentIkeSaRecord);
-                mCurrentIkeSaRecord.close();
-                mCurrentIkeSaRecord = null;
-
-                quitNow();
-            } catch (InvalidSyntaxException e) {
-                // Got deletion of a non-Current IKE SA. Program error.
-                cleanUpAndQuit(new IllegalStateException(e));
-            }
-        }
-    }
-
-    /**
-     * DeleteBase abstracts deletion handling for all states initiating a delete exchange
-     *
-     * <p>All subclasses of this state share common functionality that a deletion request is sent,
-     * and the response is received.
-     */
-    private abstract class DeleteBase extends DeleteResponderBase {
-        /** Builds a IKE Delete Request for the given IKE SA. */
-        protected IkeMessage buildIkeDeleteReq(IkeSaRecord ikeSaRecord) {
-            IkeInformationalPayload[] payloads =
-                    new IkeInformationalPayload[] {new IkeDeletePayload()};
-            return buildEncryptedInformationalMessage(
-                    ikeSaRecord,
-                    payloads,
-                    false /* isResp */,
-                    ikeSaRecord.getLocalRequestMessageId());
-        }
-
-        protected void validateIkeDeleteResp(IkeMessage resp, IkeSaRecord expectedSaRecord)
-                throws InvalidSyntaxException {
-            if (expectedSaRecord != getIkeSaRecordForPacket(resp.ikeHeader)) {
-                throw new IllegalStateException("Response received on incorrect SA");
-            }
-
-            if (resp.ikeHeader.exchangeType != IkeHeader.EXCHANGE_TYPE_INFORMATIONAL) {
-                throw new InvalidSyntaxException(
-                        "Invalid exchange type; expected INFORMATIONAL, but got: "
-                                + resp.ikeHeader.exchangeType);
-            }
-
-            if (!resp.ikePayloadList.isEmpty()) {
-                throw new InvalidSyntaxException(
-                        "Unexpected payloads - IKE Delete response should be empty.");
-            }
-        }
-    }
-
-    /**
-     * Receiving represents a state when idle IkeSessionStateMachine receives an incoming packet.
-     *
-     * <p>If this incoming packet is fully handled by Receiving state and does not trigger any
-     * further state transition or deletion of whole IKE Session, IkeSessionStateMachine MUST
-     * transition back to Idle.
-     */
-    class Receiving extends RekeyIkeHandlerBase {
-        private boolean mProcedureFinished = true;
-
-        @Override
-        public void enterState() {
-            mProcedureFinished = true;
-        }
-
-        @Override
-        protected void handleReceivedIkePacket(Message message) {
-            super.handleReceivedIkePacket(message);
-
-            // If the received packet does not trigger a state transition or the packet causes this
-            // state machine to quit, transition back to Idle State. In the second case, state
-            // machine will first go back to Idle and then quit.
-            if (mProcedureFinished) transitionTo(mIdle);
-        }
-
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_REKEY_IKE:
-                    // Errors in this exchange with no specific protocol error code will all be
-                    // classified to use NO_PROPOSAL_CHOSEN. The reason that we don't use
-                    // NO_ADDITIONAL_SAS is because it indicates "responder is unwilling to accept
-                    // any more Child SAs on this IKE SA.", according to RFC 7296. Sending this
-                    // error may mislead the remote peer.
-                    try {
-                        validateIkeRekeyReq(ikeMessage);
-
-                        // TODO: Add support for limited re-negotiation of parameters
-
-                        // Build a rekey response payload with our previously selected proposal,
-                        // against which we will validate the received proposals.
-                        IkeSaPayload reqSaPayload =
-                                ikeMessage.getPayloadForType(
-                                        IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-                        byte respProposalNumber =
-                                reqSaPayload.getNegotiatedProposalNumber(mSaProposal);
-
-                        List<IkePayload> payloadList =
-                                CreateIkeSaHelper.getRekeyIkeSaResponsePayloads(
-                                        respProposalNumber, mSaProposal, mLocalAddress);
-
-                        // Build IKE header
-                        IkeHeader ikeHeader =
-                                new IkeHeader(
-                                        mCurrentIkeSaRecord.getInitiatorSpi(),
-                                        mCurrentIkeSaRecord.getResponderSpi(),
-                                        IkePayload.PAYLOAD_TYPE_SK,
-                                        IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                                        true /*isResponseMsg*/,
-                                        mCurrentIkeSaRecord.isLocalInit,
-                                        ikeMessage.ikeHeader.messageId);
-
-                        IkeMessage responseIkeMessage = new IkeMessage(ikeHeader, payloadList);
-
-                        // Build new SA first to ensure that we can find a valid proposal.
-                        mRemoteInitNewIkeSaRecord =
-                                validateAndBuildIkeSa(
-                                        ikeMessage, responseIkeMessage, false /*isLocalInit*/);
-
-                        sendEncryptedIkeMessage(responseIkeMessage);
-
-                        transitionTo(mRekeyIkeRemoteDelete);
-                        mProcedureFinished = false;
-                    } catch (IkeProtocolException e) {
-                        handleRekeyCreationFailure(ikeMessage.ikeHeader.messageId, e);
-                    } catch (GeneralSecurityException e) {
-                        handleRekeyCreationFailure(
-                                ikeMessage.ikeHeader.messageId,
-                                new NoValidProposalChosenException(
-                                        "Error in building new IKE SA", e));
-                    } catch (IOException e) {
-                        handleRekeyCreationFailure(
-                                ikeMessage.ikeHeader.messageId,
-                                new NoValidProposalChosenException(
-                                        "IKE SPI allocation collided - they reused an SPI.", e));
-                    }
-                    return;
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    handleDeleteSessionRequest(ikeMessage);
-                    return;
-                case IKE_EXCHANGE_SUBTYPE_CREATE_CHILD: // Fall through
-                case IKE_EXCHANGE_SUBTYPE_DELETE_CHILD: // Fall through
-                case IKE_EXCHANGE_SUBTYPE_REKEY_CHILD:
-                    deferMessage(
-                            obtainMessage(
-                                    CMD_RECEIVE_REQUEST_FOR_CHILD,
-                                    ikeExchangeSubType,
-                                    0 /*placeHolder*/,
-                                    ikeMessage));
-                    transitionTo(mChildProcedureOngoing);
-                    mProcedureFinished = false;
-                    return;
-                default:
-                    // TODO: Add support for generic INFORMATIONAL request
-            }
-        }
-
-        private void handleRekeyCreationFailure(int messageId, IkeProtocolException e) {
-            loge("Received invalid Rekey IKE request. Reject with error notification", e);
-
-            buildAndSendNotificationResponse(
-                    mCurrentIkeSaRecord, messageId, e.buildNotifyPayload());
-        }
-    }
-
-    /**
-     * This class represents a state when there is at least one ongoing Child procedure
-     * (Create/Rekey/Delete Child)
-     *
-     * <p>For a locally initiated Child procedure, this state is responsible for notifying Child
-     * Session to initiate the exchange, building outbound request IkeMessage with Child Session
-     * provided payload list and redirecting the inbound response to Child Session for validation.
-     *
-     * <p>For a remotely initiated Child procedure, this state is responsible for redirecting the
-     * inbound request to Child Session(s) and building outbound response IkeMessage with Child
-     * Session provided payload list. Exchange collision on a Child Session will be resolved inside
-     * the Child Session.
-     *
-     * <p>For a remotely initiated IKE procedure, this state will only accept a Delete IKE request
-     * and reject other types with TEMPORARY_FAILURE, since it causes conflict with the ongoing
-     * Child procedure.
-     *
-     * <p>For most inbound request/response, this state will first pick out and handle IKE related
-     * payloads and then send the rest of the payloads to Child Session for further validation. It
-     * is the Child Session's responsibility to check required payloads (and verify the exchange
-     * type) according to its procedure type. Only when receiving an inbound delete Child request,
-     * as the only case where multiple Child Sessions will be affected by one IkeMessage, this state
-     * will only send Delete Payload(s) to Child Session.
-     */
-    class ChildProcedureOngoing extends DeleteBase {
-        // It is possible that mChildInLocalProcedure is also in mChildInRemoteProcedures when both
-        // sides initiated exchange for the same Child Session.
-        private ChildSessionStateMachine mChildInLocalProcedure;
-        private Set<ChildSessionStateMachine> mChildInRemoteProcedures;
-
-        private ChildLocalRequest mLocalRequestOngoing;
-
-        private int mLastInboundRequestMsgId;
-        private List<IkePayload> mOutboundRespPayloads;
-        private Set<ChildSessionStateMachine> mAwaitingChildResponse;
-
-        private EncryptedRetransmitter mRetransmitter;
-
-        @Override
-        public void enterState() {
-            mChildInLocalProcedure = null;
-            mChildInRemoteProcedures = new HashSet<>();
-
-            mLocalRequestOngoing = null;
-
-            mLastInboundRequestMsgId = 0;
-            mOutboundRespPayloads = new LinkedList<>();
-            mAwaitingChildResponse = new HashSet<>();
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_RECEIVE_REQUEST_FOR_CHILD:
-                    // Handle remote request (and do state transition)
-                    handleRequestIkeMessage(
-                            (IkeMessage) message.obj,
-                            message.arg1 /*ikeExchangeSubType*/,
-                            null /*ReceivedIkePacket*/);
-                    return HANDLED;
-                case CMD_OUTBOUND_CHILD_PAYLOADS_READY:
-                    ChildOutboundData outboundData = (ChildOutboundData) message.obj;
-                    int exchangeType = outboundData.exchangeType;
-                    List<IkePayload> outboundPayloads = outboundData.payloadList;
-
-                    if (outboundData.isResp) {
-                        handleOutboundResponse(
-                                exchangeType, outboundPayloads, outboundData.childSession);
-                    } else {
-                        handleOutboundRequest(exchangeType, outboundPayloads);
-                    }
-
-                    return HANDLED;
-                case CMD_CHILD_PROCEDURE_FINISHED:
-                    ChildSessionStateMachine childSession = (ChildSessionStateMachine) message.obj;
-
-                    if (mChildInLocalProcedure == childSession) {
-                        mChildInLocalProcedure = null;
-                        mLocalRequestOngoing = null;
-                    }
-                    mChildInRemoteProcedures.remove(childSession);
-
-                    transitionToIdleIfAllProceduresDone();
-                    return HANDLED;
-                case CMD_HANDLE_FIRST_CHILD_NEGOTIATION:
-                    FirstChildNegotiationData childData = (FirstChildNegotiationData) message.obj;
-
-                    mChildInLocalProcedure = getChildSession(childData.childSessionCallback);
-                    if (mChildInLocalProcedure == null) {
-                        cleanUpAndQuit(new IllegalStateException("First child not found."));
-                        return HANDLED;
-                    }
-
-                    mChildInLocalProcedure.handleFirstChildExchange(
-                            childData.reqPayloads,
-                            childData.respPayloads,
-                            mLocalAddress,
-                            mRemoteAddress,
-                            getEncapSocketIfNeeded(),
-                            mIkePrf,
-                            mCurrentIkeSaRecord.getSkD());
-                    return HANDLED;
-                case CMD_EXECUTE_LOCAL_REQ:
-                    executeLocalRequest((ChildLocalRequest) message.obj);
-                    return HANDLED;
-                default:
-                    return super.processStateMessage(message);
-            }
-        }
-
-        @Override
-        protected void handleTempFailure() {
-            mTempFailHandler.handleTempFailure(mLocalRequestOngoing);
-        }
-
-        private void transitionToIdleIfAllProceduresDone() {
-            if (mChildInLocalProcedure == null && mChildInRemoteProcedures.isEmpty()) {
-                transitionTo(mIdle);
-            }
-        }
-
-        private ChildSessionStateMachine getChildSession(ChildSessionCallback callbacks) {
-            synchronized (mChildCbToSessions) {
-                return mChildCbToSessions.get(callbacks);
-            }
-        }
-
-        private UdpEncapsulationSocket getEncapSocketIfNeeded() {
-            boolean isNatDetected = mIsLocalBehindNat || mIsRemoteBehindNat;
-
-            return (isNatDetected ? mIkeSessionOptions.getUdpEncapsulationSocket() : null);
-        }
-
-        private void executeLocalRequest(ChildLocalRequest req) {
-            mChildInLocalProcedure = getChildSession(req.childSessionCallback);
-            mLocalRequestOngoing = req;
-
-            if (mChildInLocalProcedure == null) {
-                // This request has been validated to have a recognized target Child Session when
-                // it was sent to IKE Session at the begginnig. Failing to find this Child Session
-                // now means the Child creation has failed.
-                logd(
-                        "Child state machine not found for local request: "
-                                + req.procedureType
-                                + " Creation of Child Session may have been failed.");
-
-                transitionToIdleIfAllProceduresDone();
-                return;
-            }
-            switch (req.procedureType) {
-                case CMD_LOCAL_REQUEST_CREATE_CHILD:
-                    mChildInLocalProcedure.createChildSession(
-                            mLocalAddress,
-                            mRemoteAddress,
-                            getEncapSocketIfNeeded(),
-                            mIkePrf,
-                            mCurrentIkeSaRecord.getSkD());
-                    break;
-                case CMD_LOCAL_REQUEST_REKEY_CHILD:
-                    mChildInLocalProcedure.rekeyChildSession();
-                    break;
-                case CMD_LOCAL_REQUEST_DELETE_CHILD:
-                    mChildInLocalProcedure.deleteChildSession();
-                    break;
-                default:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Invalid Child procedure type: " + req.procedureType));
-                    break;
-            }
-        }
-
-        /**
-         * This method is called when this state receives an inbound request or when mReceiving
-         * received an inbound Child request and deferred it to this state.
-         */
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            // TODO: Grab a remote lock and hand payloads to the Child Session
-
-            mLastInboundRequestMsgId = ikeMessage.ikeHeader.messageId;
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_CREATE_CHILD:
-                    buildAndSendErrorNotificationResponse(
-                            mCurrentIkeSaRecord,
-                            ikeMessage.ikeHeader.messageId,
-                            ERROR_TYPE_NO_ADDITIONAL_SAS);
-                    break;
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    // Send response and quit state machine
-                    handleDeleteSessionRequest(ikeMessage);
-
-                    // Return immediately to avoid transitioning to mIdle
-                    return;
-                case IKE_EXCHANGE_SUBTYPE_DELETE_CHILD:
-                    handleInboundDeleteChildRequest(ikeMessage);
-                    break;
-                case IKE_EXCHANGE_SUBTYPE_REKEY_IKE:
-                    buildAndSendErrorNotificationResponse(
-                            mCurrentIkeSaRecord,
-                            ikeMessage.ikeHeader.messageId,
-                            ERROR_TYPE_TEMPORARY_FAILURE);
-                    break;
-                case IKE_EXCHANGE_SUBTYPE_REKEY_CHILD:
-                    handleInboundRekeyChildRequest(ikeMessage);
-                    break;
-                case IKE_EXCHANGE_SUBTYPE_GENERIC_INFO:
-                    // TODO:b/139943757 Handle general informational request
-                default:
-                    cleanUpAndQuit(
-                            new IllegalStateException(
-                                    "Invalid IKE exchange subtype: " + ikeExchangeSubType));
-                    return;
-            }
-            transitionToIdleIfAllProceduresDone();
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            mRetransmitter.stopRetransmitting();
-
-            List<IkePayload> handledPayloads = new LinkedList<>();
-
-            for (IkePayload payload : ikeMessage.ikePayloadList) {
-                switch (payload.payloadType) {
-                    case PAYLOAD_TYPE_NOTIFY:
-                        // TODO: Handle fatal IKE error notification and IKE status notification.
-                        break;
-                    case PAYLOAD_TYPE_VENDOR:
-                        // TODO: Handle Vendor ID Payload
-                        handledPayloads.add(payload);
-                        break;
-                    case PAYLOAD_TYPE_CP:
-                        // TODO: Handle IKE related configuration attributes and pass the payload to
-                        // Child to further handle internal IP address attributes.
-                        break;
-                    default:
-                        break;
-                }
-            }
-
-            List<IkePayload> payloads = new LinkedList<>();
-            payloads.addAll(ikeMessage.ikePayloadList);
-            payloads.removeAll(handledPayloads);
-
-            mChildInLocalProcedure.receiveResponse(ikeMessage.ikeHeader.exchangeType, payloads);
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException ikeException) {
-            mRetransmitter.stopRetransmitting();
-
-            sendEncryptedIkeMessage(buildIkeDeleteReq(mCurrentIkeSaRecord));
-            handleIkeFatalError(ikeException);
-        }
-
-        private void handleInboundDeleteChildRequest(IkeMessage ikeMessage) {
-            // It is guaranteed in #getIkeExchangeSubType that at least one Delete Child Payload
-            // exists.
-
-            HashMap<ChildSessionStateMachine, List<IkePayload>> childToDelPayloadsMap =
-                    new HashMap<>();
-            Set<Integer> spiHandled = new HashSet<>();
-
-            for (IkePayload payload : ikeMessage.ikePayloadList) {
-                switch (payload.payloadType) {
-                    case PAYLOAD_TYPE_VENDOR:
-                        // TODO: Investigate if Vendor ID Payload can be in an INFORMATIONAL
-                        // message.
-                        break;
-                    case PAYLOAD_TYPE_NOTIFY:
-                        logw(
-                                "Unexpected or unknown notification: "
-                                        + ((IkeNotifyPayload) payload).notifyType);
-                        break;
-                    case PAYLOAD_TYPE_DELETE:
-                        IkeDeletePayload delPayload = (IkeDeletePayload) payload;
-
-                        for (int spi : delPayload.spisToDelete) {
-                            ChildSessionStateMachine child = mRemoteSpiToChildSessionMap.get(spi);
-                            if (child == null) {
-                                // TODO: Investigate how other implementations handle that.
-                                logw("Child SA not found with received SPI: " + spi);
-                            } else if (!spiHandled.add(spi)) {
-                                logw("Received repeated Child SPI: " + spi);
-                            } else {
-                                // Store Delete Payload with its target ChildSession
-                                if (!childToDelPayloadsMap.containsKey(child)) {
-                                    childToDelPayloadsMap.put(child, new LinkedList<>());
-                                }
-                                List<IkePayload> delPayloads = childToDelPayloadsMap.get(child);
-
-                                // Avoid storing repeated Delete Payload
-                                if (!delPayloads.contains(delPayload)) delPayloads.add(delPayload);
-                            }
-                        }
-
-                        break;
-                    case PAYLOAD_TYPE_CP:
-                        // TODO: Handle it
-                        break;
-                    default:
-                        logw("Unexpected payload types found: " + payload.payloadType);
-                }
-            }
-
-            // If no Child SA is found, only reply with IKE related payloads or an empty
-            // message
-            if (childToDelPayloadsMap.isEmpty()) {
-                logd("No Child SA is found for this request.");
-                sendEncryptedIkeMessage(
-                        buildEncryptedInformationalMessage(
-                                new IkeInformationalPayload[0],
-                                true /*isResp*/,
-                                ikeMessage.ikeHeader.messageId));
-                return;
-            }
-
-            // Send Delete Payloads to Child Sessions
-            for (ChildSessionStateMachine child : childToDelPayloadsMap.keySet()) {
-                child.receiveRequest(
-                        IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-                        EXCHANGE_TYPE_INFORMATIONAL,
-                        childToDelPayloadsMap.get(child));
-                mAwaitingChildResponse.add(child);
-                mChildInRemoteProcedures.add(child);
-            }
-        }
-
-        private void handleInboundRekeyChildRequest(IkeMessage ikeMessage) {
-            // It is guaranteed in #getIkeExchangeSubType that at least one Notify-Rekey Child
-            // Payload exists.
-            List<IkePayload> handledPayloads = new LinkedList<>();
-            ChildSessionStateMachine targetChild = null;
-            Set<Integer> unrecognizedSpis = new HashSet<>();
-
-            for (IkePayload payload : ikeMessage.ikePayloadList) {
-                switch (payload.payloadType) {
-                    case PAYLOAD_TYPE_VENDOR:
-                        // TODO: Handle it.
-                        handledPayloads.add(payload);
-                        break;
-                    case PAYLOAD_TYPE_NOTIFY:
-                        IkeNotifyPayload notifyPayload = (IkeNotifyPayload) payload;
-                        if (NOTIFY_TYPE_REKEY_SA != notifyPayload.notifyType) break;
-
-                        int childSpi = notifyPayload.spi;
-                        ChildSessionStateMachine child = mRemoteSpiToChildSessionMap.get(childSpi);
-
-                        if (child == null) {
-                            // Remember unrecognized SPIs and reply error notification if no
-                            // recognized SPI found.
-                            unrecognizedSpis.add(childSpi);
-                            logw("Child SA not found with received SPI: " + childSpi);
-                        } else if (targetChild == null) {
-                            // Each message should have only one Notify-Rekey Payload. If there are
-                            // multiple of them, we only process the first valid one and ignore
-                            // others.
-                            targetChild = mRemoteSpiToChildSessionMap.get(childSpi);
-                        } else {
-                            logw("More than one Notify-Rekey Payload found with SPI: " + childSpi);
-                            handledPayloads.add(notifyPayload);
-                        }
-                        break;
-                    case PAYLOAD_TYPE_CP:
-                        // TODO: Handle IKE related configuration attributes and pass the payload to
-                        // Child to further handle internal IP address attributes.
-                        break;
-                    default:
-                        break;
-                }
-            }
-
-            // Reject request with error notification.
-            if (targetChild == null) {
-                IkeInformationalPayload[] errorPayloads =
-                        new IkeInformationalPayload[unrecognizedSpis.size()];
-                int i = 0;
-                for (Integer spi : unrecognizedSpis) {
-                    errorPayloads[i++] =
-                            new IkeNotifyPayload(
-                                    IkePayload.PROTOCOL_ID_ESP,
-                                    spi,
-                                    ERROR_TYPE_CHILD_SA_NOT_FOUND,
-                                    new byte[0]);
-                }
-
-                IkeMessage msg =
-                        buildEncryptedNotificationMessage(
-                                mCurrentIkeSaRecord,
-                                errorPayloads,
-                                EXCHANGE_TYPE_INFORMATIONAL,
-                                true /*isResponse*/,
-                                ikeMessage.ikeHeader.messageId);
-
-                sendEncryptedIkeMessage(mCurrentIkeSaRecord, msg);
-                return;
-            }
-
-            // Normal path
-            List<IkePayload> payloads = new LinkedList<>();
-            payloads.addAll(ikeMessage.ikePayloadList);
-            payloads.removeAll(handledPayloads);
-
-            mAwaitingChildResponse.add(targetChild);
-            mChildInRemoteProcedures.add(targetChild);
-
-            targetChild.receiveRequest(
-                    IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, ikeMessage.ikeHeader.exchangeType, payloads);
-        }
-
-        private void handleOutboundRequest(int exchangeType, List<IkePayload> outboundPayloads) {
-            IkeHeader ikeHeader =
-                    new IkeHeader(
-                            mCurrentIkeSaRecord.getInitiatorSpi(),
-                            mCurrentIkeSaRecord.getResponderSpi(),
-                            IkePayload.PAYLOAD_TYPE_SK,
-                            exchangeType,
-                            false /*isResp*/,
-                            mCurrentIkeSaRecord.isLocalInit,
-                            mCurrentIkeSaRecord.getLocalRequestMessageId());
-            IkeMessage ikeMessage = new IkeMessage(ikeHeader, outboundPayloads);
-
-            mRetransmitter = new EncryptedRetransmitter(ikeMessage);
-        }
-
-        private void handleOutboundResponse(
-                int exchangeType,
-                List<IkePayload> outboundPayloads,
-                ChildSessionStateMachine childSession) {
-            // For each request IKE passed to Child, Child will send back to IKE a response. Even
-            // if the Child Sesison is under simultaneous deletion, it will send back an empty
-            // payload list.
-            mOutboundRespPayloads.addAll(outboundPayloads);
-            mAwaitingChildResponse.remove(childSession);
-            if (!mAwaitingChildResponse.isEmpty()) return;
-
-            IkeHeader ikeHeader =
-                    new IkeHeader(
-                            mCurrentIkeSaRecord.getInitiatorSpi(),
-                            mCurrentIkeSaRecord.getResponderSpi(),
-                            IkePayload.PAYLOAD_TYPE_SK,
-                            exchangeType,
-                            true /*isResp*/,
-                            mCurrentIkeSaRecord.isLocalInit,
-                            mLastInboundRequestMsgId);
-            IkeMessage ikeMessage = new IkeMessage(ikeHeader, mOutboundRespPayloads);
-            sendEncryptedIkeMessage(ikeMessage);
-        }
-    }
-
-    /** CreateIkeLocalIkeInit represents state when IKE library initiates IKE_INIT exchange. */
-    @VisibleForTesting
-    public class CreateIkeLocalIkeInit extends BusyState {
-        private IkeSecurityParameterIndex mLocalIkeSpiResource;
-        private IkeSecurityParameterIndex mRemoteIkeSpiResource;
-        private Retransmitter mRetransmitter;
-
-        // TODO: Support negotiating IKE fragmentation
-
-        @Override
-        public void enterState() {
-            try {
-                IkeMessage request = buildIkeInitReq();
-
-                // Register local SPI to receive the IKE INIT response.
-                mIkeSocket.registerIke(
-                        request.ikeHeader.ikeInitiatorSpi, IkeSessionStateMachine.this);
-
-                mIkeInitRequestBytes = request.encode();
-                mIkeInitNoncePayload =
-                        request.getPayloadForType(
-                                IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class);
-                mRetransmitter = new UnencryptedRetransmitter(request);
-            } catch (IOException e) {
-                // Fail to assign IKE SPI
-                handleIkeFatalError(e);
-            }
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_RECEIVE_IKE_PACKET:
-                    handleReceivedIkePacket(message);
-                    return HANDLED;
-
-                default:
-                    return super.processStateMessage(message);
-            }
-        }
-
-        protected void handleReceivedIkePacket(Message message) {
-            String methodTag = "handleReceivedIkePacket: ";
-
-            ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
-            IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
-            byte[] ikePacketBytes = receivedIkePacket.ikePacketBytes;
-
-            logd(
-                    methodTag
-                            + "Received an "
-                            + ikeHeader.getBasicInfoString()
-                            + ". Packet size: "
-                            + ikePacketBytes.length);
-
-            if (ikeHeader.isResponseMsg) {
-                DecodeResult decodeResult = IkeMessage.decode(0, ikeHeader, ikePacketBytes);
-
-                switch (decodeResult.status) {
-                    case DECODE_STATUS_OK:
-                        handleResponseIkeMessage(((DecodeResultOk) decodeResult).ikeMessage);
-                        mIkeInitResponseBytes = ikePacketBytes;
-
-                        // SA negotiation failed
-                        if (mCurrentIkeSaRecord == null) break;
-
-                        mCurrentIkeSaRecord.incrementLocalRequestMessageId();
-                        break;
-                    case DECODE_STATUS_PARTIAL:
-                        // Fall through. We don't support IKE fragmentation here. We should never
-                        // get this status.
-                    case DECODE_STATUS_PROTECTED_ERROR:
-                        // IKE INIT response is not protected. So we should never get this status
-                        cleanUpAndQuit(
-                                new IllegalStateException(
-                                        "Unexpected decoding status: " + decodeResult.status));
-                        break;
-                    case DECODE_STATUS_UNPROTECTED_ERROR:
-                        logi(
-                                "Discard unencrypted response with syntax error",
-                                ((DecodeResultError) decodeResult).ikeException);
-                        break;
-                    default:
-                        cleanUpAndQuit(
-                                new IllegalStateException(
-                                        "Invalid decoding status: " + decodeResult.status));
-                }
-
-            } else {
-                // TODO: Also prettyprint IKE header in the log.
-                logi("Received a request while waiting for IKE_INIT response. Discard it.");
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            boolean ikeInitSuccess = false;
-            try {
-                validateIkeInitResp(mRetransmitter.getMessage(), ikeMessage);
-
-                mCurrentIkeSaRecord =
-                        IkeSaRecord.makeFirstIkeSaRecord(
-                                mRetransmitter.getMessage(),
-                                ikeMessage,
-                                mLocalIkeSpiResource,
-                                mRemoteIkeSpiResource,
-                                mIkePrf,
-                                mIkeIntegrity == null ? 0 : mIkeIntegrity.getKeyLength(),
-                                mIkeCipher.getKeyLength(),
-                                new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
-
-                addIkeSaRecord(mCurrentIkeSaRecord);
-                ikeInitSuccess = true;
-
-                transitionTo(mCreateIkeLocalIkeAuth);
-            } catch (IkeProtocolException | GeneralSecurityException | IOException e) {
-                // TODO: Try another DH group to buld KE Payload if receiving InvalidKeException
-                handleIkeFatalError(e);
-            } finally {
-                if (!ikeInitSuccess) {
-                    if (mLocalIkeSpiResource != null) {
-                        mLocalIkeSpiResource.close();
-                        mLocalIkeSpiResource = null;
-                    }
-                    if (mRemoteIkeSpiResource != null) {
-                        mRemoteIkeSpiResource.close();
-                        mRemoteIkeSpiResource = null;
-                    }
-                }
-            }
-        }
-
-        private IkeMessage buildIkeInitReq() throws IOException {
-            // Generate IKE SPI
-            mLocalIkeSpiResource =
-                    IkeSecurityParameterIndex.allocateSecurityParameterIndex(mLocalAddress);
-            long initSpi = mLocalIkeSpiResource.getSpi();
-            long respSpi = 0;
-
-            // It is validated in IkeSessionOptions.Builder to ensure IkeSessionOptions has at least
-            // one IkeSaProposal and all SaProposals are valid for IKE SA negotiation.
-            IkeSaProposal[] saProposals = mIkeSessionOptions.getSaProposals();
-            List<IkePayload> payloadList =
-                    CreateIkeSaHelper.getIkeInitSaRequestPayloads(
-                            saProposals,
-                            initSpi,
-                            respSpi,
-                            mLocalAddress,
-                            mRemoteAddress,
-                            mLocalPort,
-                            IkeSocket.IKE_SERVER_PORT);
-            payloadList.add(
-                    new IkeNotifyPayload(
-                            IkeNotifyPayload.NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED));
-
-            // TODO: Add Notification Payloads according to user configurations.
-
-            // Build IKE header
-            IkeHeader ikeHeader =
-                    new IkeHeader(
-                            initSpi,
-                            respSpi,
-                            IkePayload.PAYLOAD_TYPE_SA,
-                            IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT,
-                            false /*isResponseMsg*/,
-                            true /*fromIkeInitiator*/,
-                            0 /*messageId*/);
-
-            return new IkeMessage(ikeHeader, payloadList);
-        }
-
-        private void validateIkeInitResp(IkeMessage reqMsg, IkeMessage respMsg)
-                throws IkeProtocolException, IOException {
-            IkeHeader respIkeHeader = respMsg.ikeHeader;
-            mRemoteIkeSpiResource =
-                    IkeSecurityParameterIndex.allocateSecurityParameterIndex(
-                            mIkeSessionOptions.getServerAddress(), respIkeHeader.ikeResponderSpi);
-
-            int exchangeType = respIkeHeader.exchangeType;
-            if (exchangeType != IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT) {
-                throw new InvalidSyntaxException(
-                        "Expected EXCHANGE_TYPE_IKE_SA_INIT but received: " + exchangeType);
-            }
-
-            IkeSaPayload respSaPayload = null;
-            IkeKePayload respKePayload = null;
-
-            /**
-             * There MAY be multiple NAT_DETECTION_SOURCE_IP payloads in a message if the sender
-             * does not know which of several network attachments will be used to send the packet.
-             */
-            List<IkeNotifyPayload> natSourcePayloads = new LinkedList<>();
-            IkeNotifyPayload natDestPayload = null;
-
-            boolean hasNoncePayload = false;
-
-            for (IkePayload payload : respMsg.ikePayloadList) {
-                switch (payload.payloadType) {
-                    case IkePayload.PAYLOAD_TYPE_SA:
-                        respSaPayload = (IkeSaPayload) payload;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_KE:
-                        respKePayload = (IkeKePayload) payload;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_CERT_REQUEST:
-                        throw new UnsupportedOperationException(
-                                "Do not support handling Cert Request Payload.");
-                        // TODO: Handle it when using certificate based authentication. Otherwise,
-                        // ignore it.
-                    case IkePayload.PAYLOAD_TYPE_NONCE:
-                        hasNoncePayload = true;
-                        mIkeRespNoncePayload = (IkeNoncePayload) payload;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_VENDOR:
-                        // Do not support any vendor defined protocol extensions. Ignore
-                        // all Vendor ID Payloads.
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_NOTIFY:
-                        IkeNotifyPayload notifyPayload = (IkeNotifyPayload) payload;
-
-                        if (notifyPayload.isErrorNotify()) {
-                            throw notifyPayload.validateAndBuildIkeException();
-                        }
-
-                        switch (notifyPayload.notifyType) {
-                            case NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP:
-                                natSourcePayloads.add(notifyPayload);
-                                break;
-                            case NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP:
-                                if (natDestPayload != null) {
-                                    throw new InvalidSyntaxException(
-                                            "More than one"
-                                                    + " NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP"
-                                                    + " found");
-                                }
-                                natDestPayload = notifyPayload;
-                                break;
-                            case NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED:
-                                mSupportFragment = true;
-                                break;
-                            default:
-                                // Unknown and unexpected status notifications are ignored as per
-                                // RFC7296.
-                                logw(
-                                        "Received unknown or unexpected status notifications with"
-                                                + " notify type: "
-                                                + notifyPayload.notifyType);
-                        }
-
-                        break;
-                    default:
-                        logw(
-                                "Received unexpected payload in IKE INIT response. Payload type: "
-                                        + payload.payloadType);
-                }
-            }
-
-            if (respSaPayload == null
-                    || respKePayload == null
-                    || natSourcePayloads.isEmpty()
-                    || natDestPayload == null
-                    || !hasNoncePayload) {
-                throw new InvalidSyntaxException(
-                        "SA, KE, Nonce, Notify-NAT-Detection-Source, or"
-                                + " Notify-NAT-Detection-Destination payload missing.");
-            }
-
-            IkeSaPayload reqSaPayload =
-                    reqMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-            mSaProposal =
-                    IkeSaPayload.getVerifiedNegotiatedIkeProposalPair(
-                                    reqSaPayload, respSaPayload, mRemoteAddress)
-                            .second
-                            .saProposal;
-
-            // Build IKE crypto tools using mSaProposal. It is ensured that mSaProposal is valid and
-            // has exactly one Transform for each Transform type. Only exception is when
-            // combined-mode cipher is used, there will be either no integrity algorithm or an
-            // INTEGRITY_ALGORITHM_NONE type algorithm.
-            Provider provider = IkeMessage.getSecurityProvider();
-            mIkeCipher = IkeCipher.create(mSaProposal.getEncryptionTransforms()[0], provider);
-            if (!mIkeCipher.isAead()) {
-                mIkeIntegrity =
-                        IkeMacIntegrity.create(mSaProposal.getIntegrityTransforms()[0], provider);
-            }
-            mIkePrf = IkeMacPrf.create(mSaProposal.getPrfTransforms()[0], provider);
-
-            IkeKePayload reqKePayload =
-                    reqMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class);
-            if (reqKePayload.dhGroup != respKePayload.dhGroup
-                    && respKePayload.dhGroup != mSaProposal.getDhGroupTransforms()[0].id) {
-                throw new InvalidSyntaxException("Received KE payload with mismatched DH group.");
-            }
-
-            // NAT detection
-            long initIkeSpi = respMsg.ikeHeader.ikeInitiatorSpi;
-            long respIkeSpi = respMsg.ikeHeader.ikeResponderSpi;
-            mIsLocalBehindNat = true;
-            mIsRemoteBehindNat = true;
-
-            // Check if local node is behind NAT
-            byte[] expectedLocalNatData =
-                    IkeNotifyPayload.generateNatDetectionData(
-                            initIkeSpi, respIkeSpi, mLocalAddress, mLocalPort);
-            mIsLocalBehindNat = !Arrays.equals(expectedLocalNatData, natDestPayload.notifyData);
-
-            // Check if the remote node is behind NAT
-            byte[] expectedRemoteNatData =
-                    IkeNotifyPayload.generateNatDetectionData(
-                            initIkeSpi, respIkeSpi, mRemoteAddress, IkeSocket.IKE_SERVER_PORT);
-            for (IkeNotifyPayload natPayload : natSourcePayloads) {
-                // If none of the received hash matches the expected value, the remote node is
-                // behind NAT.
-                if (Arrays.equals(expectedRemoteNatData, natPayload.notifyData)) {
-                    mIsRemoteBehindNat = false;
-                }
-            }
-        }
-
-        @Override
-        public void exitState() {
-            super.exitState();
-            mRetransmitter.stopRetransmitting();
-        }
-
-        private class UnencryptedRetransmitter extends Retransmitter {
-            private UnencryptedRetransmitter(IkeMessage msg) {
-                super(getHandler(), msg);
-
-                retransmit();
-            }
-
-            @Override
-            public void send(IkeMessage msg) {
-                // Sends unencrypted
-                mIkeSocket.sendIkePacket(msg.encode(), mRemoteAddress);
-            }
-
-            @Override
-            public void handleRetransmissionFailure() {
-                handleIkeFatalError(new IOException("Retransmitting IKE INIT request failure"));
-            }
-        }
-    }
-
-    /**
-     * CreateIkeLocalIkeAuthBase represents the common state and functionality required to perform
-     * IKE AUTH exchanges in both the EAP and non-EAP flows.
-     */
-    abstract class CreateIkeLocalIkeAuthBase extends DeleteBase {
-        protected Retransmitter mRetransmitter;
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        // TODO: b/139482382 If receiving a remote request while waiting for the last IKE AUTH
-        // response, defer it to next state.
-
-        protected IkeMessage buildIkeAuthReqMessage(List<IkePayload> payloadList) {
-            // Build IKE header
-            IkeHeader ikeHeader =
-                    new IkeHeader(
-                            mCurrentIkeSaRecord.getInitiatorSpi(),
-                            mCurrentIkeSaRecord.getResponderSpi(),
-                            IkePayload.PAYLOAD_TYPE_SK,
-                            IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                            false /*isResponseMsg*/,
-                            true /*fromIkeInitiator*/,
-                            mCurrentIkeSaRecord.getLocalRequestMessageId());
-
-            return new IkeMessage(ikeHeader, payloadList);
-        }
-
-        protected void authenticatePsk(
-                byte[] psk, IkeAuthPayload authPayload, IkeIdPayload respIdPayload)
-                throws AuthenticationFailedException {
-            if (authPayload.authMethod != IkeAuthPayload.AUTH_METHOD_PRE_SHARED_KEY) {
-                throw new AuthenticationFailedException(
-                        "Expected the remote/server to use PSK-based authentication but"
-                                + " they used: "
-                                + authPayload.authMethod);
-            }
-
-            IkeAuthPskPayload pskPayload = (IkeAuthPskPayload) authPayload;
-            pskPayload.verifyInboundSignature(
-                    psk,
-                    mIkeInitResponseBytes,
-                    mCurrentIkeSaRecord.nonceInitiator,
-                    respIdPayload.getEncodedPayloadBody(),
-                    mIkePrf,
-                    mCurrentIkeSaRecord.getSkPr());
-        }
-
-        protected List<IkePayload> extractChildPayloadsFromMessage(IkeMessage ikeMessage)
-                throws InvalidSyntaxException {
-            IkeSaPayload saPayload =
-                    ikeMessage.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-            IkeTsPayload tsInitPayload =
-                    ikeMessage.getPayloadForType(
-                            IkePayload.PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class);
-            IkeTsPayload tsRespPayload =
-                    ikeMessage.getPayloadForType(
-                            IkePayload.PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class);
-
-            List<IkeNotifyPayload> notifyPayloads =
-                    ikeMessage.getPayloadListForType(
-                            IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-
-            boolean hasErrorNotify = false;
-            List<IkePayload> list = new LinkedList<>();
-            for (IkeNotifyPayload payload : notifyPayloads) {
-                if (payload.isNewChildSaNotify()) {
-                    list.add(payload);
-                    if (payload.isErrorNotify()) {
-                        hasErrorNotify = true;
-                    }
-                }
-            }
-
-            // If there is no error notification, SA, TS-initiator and TS-responder MUST all be
-            // included in this message.
-            if (!hasErrorNotify
-                    && (saPayload == null || tsInitPayload == null || tsRespPayload == null)) {
-                throw new InvalidSyntaxException(
-                        "SA, TS-Initiator or TS-Responder payload is missing.");
-            }
-
-            list.add(saPayload);
-            list.add(tsInitPayload);
-            list.add(tsRespPayload);
-            return list;
-        }
-
-        protected void performFirstChildNegotiation(
-                List<IkePayload> childReqList, List<IkePayload> childRespList) {
-            childReqList.add(mIkeInitNoncePayload);
-            childRespList.add(mIkeRespNoncePayload);
-
-            deferMessage(
-                    obtainMessage(
-                            CMD_HANDLE_FIRST_CHILD_NEGOTIATION,
-                            new FirstChildNegotiationData(
-                                    mFirstChildSessionOptions,
-                                    mFirstChildCallbacks,
-                                    childReqList,
-                                    childRespList)));
-
-            mUserCbExecutor.execute(
-                    () -> {
-                        mIkeSessionCallback.onOpened(null /*sessionConfiguration*/);
-                        // TODO: Construct and pass a real IkeSessionConfiguration
-                    });
-            transitionTo(mChildProcedureOngoing);
-        }
-    }
-
-    /**
-     * CreateIkeLocalIkeAuth represents state when IKE library initiates IKE_AUTH exchange.
-     *
-     * <p>If using EAP, CreateIkeLocalIkeAuth will transition to CreateIkeLocalIkeAuthInEap state
-     * after validating the IKE AUTH response.
-     */
-    class CreateIkeLocalIkeAuth extends CreateIkeLocalIkeAuthBase {
-        private boolean mUseEap;
-
-        @Override
-        public void enterState() {
-            try {
-                super.enterState();
-                mRetransmitter = new EncryptedRetransmitter(buildIkeAuthReq());
-                mUseEap =
-                        (IkeSessionOptions.IKE_AUTH_METHOD_EAP
-                                == mIkeSessionOptions.getLocalAuthConfig().mAuthMethod);
-            } catch (ResourceUnavailableException e) {
-                // Handle IPsec SPI assigning failure.
-                handleIkeFatalError(e);
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                int exchangeType = ikeMessage.ikeHeader.exchangeType;
-                if (exchangeType != IkeHeader.EXCHANGE_TYPE_IKE_AUTH) {
-                    throw new InvalidSyntaxException(
-                            "Expected EXCHANGE_TYPE_IKE_AUTH but received: " + exchangeType);
-                }
-
-                List<IkePayload> childReqList =
-                        extractChildPayloadsFromMessage(mRetransmitter.getMessage());
-
-                if (mUseEap) {
-                    validateIkeAuthRespWithEapPayload(ikeMessage);
-
-                    // childReqList needed after EAP completed, so persist to IkeSessionStateMachine
-                    // state.
-                    mFirstChildReqList = childReqList;
-
-                    IkeEapPayload ikeEapPayload =
-                            ikeMessage.getPayloadForType(
-                                    IkePayload.PAYLOAD_TYPE_EAP, IkeEapPayload.class);
-
-                    deferMessage(obtainMessage(CMD_EAP_START_EAP_AUTH, ikeEapPayload));
-                    transitionTo(mCreateIkeLocalIkeAuthInEap);
-                } else {
-                    validateIkeAuthRespWithChildPayloads(ikeMessage);
-
-                    performFirstChildNegotiation(
-                            childReqList, extractChildPayloadsFromMessage(ikeMessage));
-                }
-            } catch (IkeProtocolException e) {
-                if (!mUseEap) {
-                    // Notify the remote because they may have set up the IKE SA.
-                    sendEncryptedIkeMessage(buildIkeDeleteReq(mCurrentIkeSaRecord));
-                }
-                handleIkeFatalError(e);
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException ikeException) {
-            mRetransmitter.stopRetransmitting();
-
-            if (!mUseEap) {
-                // Notify the remote because they may have set up the IKE SA.
-                sendEncryptedIkeMessage(buildIkeDeleteReq(mCurrentIkeSaRecord));
-            }
-            handleIkeFatalError(ikeException);
-        }
-
-        private IkeMessage buildIkeAuthReq() throws ResourceUnavailableException {
-            List<IkePayload> payloadList = new LinkedList<>();
-
-            // Build Identification payloads
-            mInitIdPayload =
-                    new IkeIdPayload(
-                            true /*isInitiator*/, mIkeSessionOptions.getLocalIdentification());
-            IkeIdPayload respIdPayload =
-                    new IkeIdPayload(
-                            false /*isInitiator*/, mIkeSessionOptions.getRemoteIdentification());
-            payloadList.add(mInitIdPayload);
-            payloadList.add(respIdPayload);
-
-            // Build Authentication payload
-            IkeAuthConfig authConfig = mIkeSessionOptions.getLocalAuthConfig();
-            switch (authConfig.mAuthMethod) {
-                case IkeSessionOptions.IKE_AUTH_METHOD_PSK:
-                    IkeAuthPskPayload pskPayload =
-                            new IkeAuthPskPayload(
-                                    ((IkeAuthPskConfig) authConfig).mPsk,
-                                    mIkeInitRequestBytes,
-                                    mCurrentIkeSaRecord.nonceResponder,
-                                    mInitIdPayload.getEncodedPayloadBody(),
-                                    mIkePrf,
-                                    mCurrentIkeSaRecord.getSkPi());
-                    payloadList.add(pskPayload);
-                    break;
-                case IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE:
-                    // TODO: Support authentication based on public key signature.
-                    throw new UnsupportedOperationException(
-                            "Do not support public-key based authentication.");
-                case IkeSessionOptions.IKE_AUTH_METHOD_EAP:
-                    // Do not include AUTH payload when using EAP.
-                    break;
-                default:
-                    cleanUpAndQuit(
-                            new IllegalArgumentException(
-                                    "Unrecognized authentication method: "
-                                            + authConfig.mAuthMethod));
-            }
-
-            payloadList.addAll(
-                    CreateChildSaHelper.getInitChildCreateReqPayloads(
-                            mIpSecManager,
-                            mLocalAddress,
-                            mFirstChildSessionOptions,
-                            true /*isFirstChild*/));
-
-            return buildIkeAuthReqMessage(payloadList);
-        }
-
-        private void validateIkeAuthRespWithEapPayload(IkeMessage respMsg)
-                throws IkeProtocolException {
-            IkeEapPayload ikeEapPayload =
-                    respMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_EAP, IkeEapPayload.class);
-            if (ikeEapPayload == null) {
-                throw new AuthenticationFailedException("Missing EAP payload");
-            }
-
-            // TODO: check that we don't receive any ChildSaRespPayloads here
-
-            List<IkePayload> nonEapPayloads = new LinkedList<>();
-            nonEapPayloads.addAll(respMsg.ikePayloadList);
-            nonEapPayloads.remove(ikeEapPayload);
-            validateIkeAuthResp(nonEapPayloads);
-        }
-
-        private void validateIkeAuthRespWithChildPayloads(IkeMessage respMsg)
-                throws IkeProtocolException {
-            // Extract and validate existence of payloads for first Child SA setup.
-            List<IkePayload> childSaRespPayloads = extractChildPayloadsFromMessage(respMsg);
-
-            List<IkePayload> nonChildPayloads = new LinkedList<>();
-            nonChildPayloads.addAll(respMsg.ikePayloadList);
-            nonChildPayloads.removeAll(childSaRespPayloads);
-
-            validateIkeAuthResp(nonChildPayloads);
-        }
-
-        private void validateIkeAuthResp(List<IkePayload> payloadList) throws IkeProtocolException {
-            // Validate IKE Authentication
-            IkeAuthPayload authPayload = null;
-            List<IkeCertPayload> certPayloads = new LinkedList<>();
-
-            for (IkePayload payload : payloadList) {
-                switch (payload.payloadType) {
-                    case IkePayload.PAYLOAD_TYPE_ID_RESPONDER:
-                        mRespIdPayload = (IkeIdPayload) payload;
-                        if (!mIkeSessionOptions
-                                .getRemoteIdentification()
-                                .equals(mRespIdPayload.ikeId)) {
-                            throw new AuthenticationFailedException(
-                                    "Unrecognized Responder Identification.");
-                        }
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_AUTH:
-                        authPayload = (IkeAuthPayload) payload;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_CERT:
-                        certPayloads.add((IkeCertPayload) payload);
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_NOTIFY:
-                        IkeNotifyPayload notifyPayload = (IkeNotifyPayload) payload;
-                        if (notifyPayload.isErrorNotify()) {
-                            throw notifyPayload.validateAndBuildIkeException();
-                        } else {
-                            // Unknown and unexpected status notifications are ignored as per
-                            // RFC7296.
-                            logw(
-                                    "Received unknown or unexpected status notifications with"
-                                            + " notify type: "
-                                            + notifyPayload.notifyType);
-                        }
-                        break;
-                    default:
-                        logw(
-                                "Received unexpected payload in IKE AUTH response. Payload"
-                                        + " type: "
-                                        + payload.payloadType);
-                }
-            }
-
-            // Verify existence of payloads
-            if (mRespIdPayload == null || authPayload == null) {
-                throw new AuthenticationFailedException("ID-Responder or Auth payload is missing.");
-            }
-
-            // Authenticate the remote peer.
-            authenticate(authPayload, mRespIdPayload, certPayloads);
-        }
-
-        private void authenticate(
-                IkeAuthPayload authPayload,
-                IkeIdPayload respIdPayload,
-                List<IkeCertPayload> certPayloads)
-                throws AuthenticationFailedException {
-            switch (mIkeSessionOptions.getRemoteAuthConfig().mAuthMethod) {
-                case IkeSessionOptions.IKE_AUTH_METHOD_PSK:
-                    authenticatePsk(
-                            ((IkeAuthPskConfig) mIkeSessionOptions.getRemoteAuthConfig()).mPsk,
-                            authPayload,
-                            respIdPayload);
-                    break;
-                case IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE:
-                    authenticateDigitalSignature(
-                            certPayloads,
-                            ((IkeAuthDigitalSignRemoteConfig)
-                                            mIkeSessionOptions.getRemoteAuthConfig())
-                                    .mTrustAnchor,
-                            authPayload,
-                            respIdPayload);
-                    break;
-                default:
-                    cleanUpAndQuit(
-                            new IllegalArgumentException(
-                                    "Unrecognized auth method: " + authPayload.authMethod));
-            }
-        }
-
-        private void authenticateDigitalSignature(
-                List<IkeCertPayload> certPayloads,
-                TrustAnchor trustAnchor,
-                IkeAuthPayload authPayload,
-                IkeIdPayload respIdPayload)
-                throws AuthenticationFailedException {
-            if (authPayload.authMethod != IkeAuthPayload.AUTH_METHOD_RSA_DIGITAL_SIGN
-                    && authPayload.authMethod != IkeAuthPayload.AUTH_METHOD_GENERIC_DIGITAL_SIGN) {
-                throw new AuthenticationFailedException(
-                        "Expected the remote/server to use digital-signature-based authentication"
-                                + " but they used: "
-                                + authPayload.authMethod);
-            }
-
-            X509Certificate endCert = null;
-            List<X509Certificate> certList = new LinkedList<>();
-
-            // TODO: b/122676944 Extract CRL from IkeCrlPayload when we support IkeCrlPayload
-            for (IkeCertPayload certPayload : certPayloads) {
-                X509Certificate cert = ((IkeCertX509CertPayload) certPayload).certificate;
-
-                // The first certificate MUST be the end entity certificate.
-                if (endCert == null) endCert = cert;
-                certList.add(cert);
-            }
-
-            if (endCert == null) {
-                throw new AuthenticationFailedException(
-                        "The remote/server failed to provide a end certificate");
-            }
-
-            Set<TrustAnchor> trustAnchorSet = new HashSet<>();
-            trustAnchorSet.add(trustAnchor);
-
-            IkeCertPayload.validateCertificates(
-                    endCert, certList, null /*crlList*/, trustAnchorSet);
-
-            IkeAuthDigitalSignPayload signPayload = (IkeAuthDigitalSignPayload) authPayload;
-            signPayload.verifyInboundSignature(
-                    endCert,
-                    mIkeInitResponseBytes,
-                    mCurrentIkeSaRecord.nonceInitiator,
-                    respIdPayload.getEncodedPayloadBody(),
-                    mIkePrf,
-                    mCurrentIkeSaRecord.getSkPr());
-        }
-
-        @Override
-        public void exitState() {
-            mRetransmitter.stopRetransmitting();
-        }
-    }
-
-    /**
-     * CreateIkeLocalIkeAuthInEap represents the state when the IKE library authenticates the client
-     * with an EAP session.
-     */
-    class CreateIkeLocalIkeAuthInEap extends CreateIkeLocalIkeAuthBase {
-        private EapAuthenticator mEapAuthenticator;
-
-        @Override
-        public void enterState() {
-            IkeSessionOptions.IkeAuthEapConfig ikeAuthEapConfig =
-                    (IkeSessionOptions.IkeAuthEapConfig) mIkeSessionOptions.getLocalAuthConfig();
-
-            mEapAuthenticator =
-                    mEapAuthenticatorFactory.newEapAuthenticator(
-                            getHandler().getLooper(),
-                            new IkeEapCallback(),
-                            mContext,
-                            ikeAuthEapConfig.mEapConfig);
-        }
-
-        @Override
-        public boolean processStateMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_EAP_START_EAP_AUTH:
-                    IkeEapPayload ikeEapPayload = (IkeEapPayload) msg.obj;
-                    mEapAuthenticator.processEapMessage(ikeEapPayload.eapMessage);
-
-                    return HANDLED;
-                case CMD_EAP_OUTBOUND_MSG_READY:
-                    byte[] eapMsgBytes = (byte[]) msg.obj;
-                    IkeEapPayload eapPayload = new IkeEapPayload(eapMsgBytes);
-
-                    // Setup new retransmitter with EAP response
-                    mRetransmitter =
-                            new EncryptedRetransmitter(
-                                    buildIkeAuthReqMessage(Arrays.asList(eapPayload)));
-
-                    return HANDLED;
-                case CMD_EAP_ERRORED:
-                    handleIkeFatalError(new AuthenticationFailedException((Throwable) msg.obj));
-                    return HANDLED;
-                case CMD_EAP_FAILED:
-                    AuthenticationFailedException exception =
-                            new AuthenticationFailedException("EAP Authentication Failed");
-
-                    handleIkeFatalError(exception);
-                    return HANDLED;
-                case CMD_EAP_FINISH_EAP_AUTH:
-                    deferMessage(msg);
-                    transitionTo(mCreateIkeLocalIkeAuthPostEap);
-
-                    return HANDLED;
-                default:
-                    return super.processStateMessage(msg);
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                mRetransmitter.stopRetransmitting();
-
-                int exchangeType = ikeMessage.ikeHeader.exchangeType;
-                if (exchangeType != IkeHeader.EXCHANGE_TYPE_IKE_AUTH) {
-                    throw new InvalidSyntaxException(
-                            "Expected EXCHANGE_TYPE_IKE_AUTH but received: " + exchangeType);
-                }
-
-                IkeEapPayload eapPayload = null;
-                for (IkePayload payload : ikeMessage.ikePayloadList) {
-                    switch (payload.payloadType) {
-                        case IkePayload.PAYLOAD_TYPE_EAP:
-                            eapPayload = (IkeEapPayload) payload;
-                            break;
-                        case IkePayload.PAYLOAD_TYPE_NOTIFY:
-                            IkeNotifyPayload notifyPayload = (IkeNotifyPayload) payload;
-                            if (notifyPayload.isErrorNotify()) {
-                                throw notifyPayload.validateAndBuildIkeException();
-                            } else {
-                                // Unknown and unexpected status notifications are ignored as per
-                                // RFC7296.
-                                logw(
-                                        "Received unknown or unexpected status notifications with"
-                                                + " notify type: "
-                                                + notifyPayload.notifyType);
-                            }
-                            break;
-                        default:
-                            logw(
-                                    "Received unexpected payload in IKE AUTH response. Payload"
-                                            + " type: "
-                                            + payload.payloadType);
-                    }
-                }
-
-                if (eapPayload == null) {
-                    throw new AuthenticationFailedException("EAP Payload is missing.");
-                }
-
-                mEapAuthenticator.processEapMessage(eapPayload.eapMessage);
-            } catch (IkeProtocolException exception) {
-                handleIkeFatalError(exception);
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException ikeException) {
-            mRetransmitter.stopRetransmitting();
-            handleIkeFatalError(ikeException);
-        }
-
-        private class IkeEapCallback implements IEapCallback {
-            @Override
-            public void onSuccess(byte[] msk, byte[] emsk) {
-                // Extended MSK not used in IKEv2, drop.
-                sendMessage(CMD_EAP_FINISH_EAP_AUTH, msk);
-            }
-
-            @Override
-            public void onFail() {
-                sendMessage(CMD_EAP_FAILED);
-            }
-
-            @Override
-            public void onResponse(byte[] eapMsg) {
-                sendMessage(CMD_EAP_OUTBOUND_MSG_READY, eapMsg);
-            }
-
-            @Override
-            public void onError(Throwable cause) {
-                sendMessage(CMD_EAP_ERRORED, cause);
-            }
-        }
-    }
-
-    /**
-     * CreateIkeLocalIkeAuthPostEap represents the state when the IKE library is performing the
-     * post-EAP PSK-base authentication run.
-     */
-    class CreateIkeLocalIkeAuthPostEap extends CreateIkeLocalIkeAuthBase {
-        private byte[] mEapMsk = new byte[0];
-
-        @Override
-        public boolean processStateMessage(Message msg) {
-            switch (msg.what) {
-                case CMD_EAP_FINISH_EAP_AUTH:
-                    mEapMsk = (byte[]) msg.obj;
-
-                    IkeAuthPskPayload pskPayload =
-                            new IkeAuthPskPayload(
-                                    mEapMsk,
-                                    mIkeInitRequestBytes,
-                                    mCurrentIkeSaRecord.nonceResponder,
-                                    mInitIdPayload.getEncodedPayloadBody(),
-                                    mIkePrf,
-                                    mCurrentIkeSaRecord.getSkPi());
-                    IkeMessage postEapAuthMsg = buildIkeAuthReqMessage(Arrays.asList(pskPayload));
-                    mRetransmitter = new EncryptedRetransmitter(postEapAuthMsg);
-
-                    return HANDLED;
-                default:
-                    return super.processStateMessage(msg);
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                int exchangeType = ikeMessage.ikeHeader.exchangeType;
-                if (exchangeType != IkeHeader.EXCHANGE_TYPE_IKE_AUTH) {
-                    throw new InvalidSyntaxException(
-                            "Expected EXCHANGE_TYPE_IKE_AUTH but received: " + exchangeType);
-                }
-
-                // Extract and validate existence of payloads for first Child SA setup.
-                List<IkePayload> childSaRespPayloads = extractChildPayloadsFromMessage(ikeMessage);
-
-                List<IkePayload> nonChildPayloads = new LinkedList<>();
-                nonChildPayloads.addAll(ikeMessage.ikePayloadList);
-                nonChildPayloads.removeAll(childSaRespPayloads);
-
-                validateIkeAuthRespPostEap(nonChildPayloads);
-
-                performFirstChildNegotiation(mFirstChildReqList, childSaRespPayloads);
-            } catch (IkeProtocolException e) {
-                // Notify the remote because they may have set up the IKE SA.
-                sendEncryptedIkeMessage(buildIkeDeleteReq(mCurrentIkeSaRecord));
-                handleIkeFatalError(e);
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException ikeException) {
-            mRetransmitter.stopRetransmitting();
-            // Notify the remote because they may have set up the IKE SA.
-            sendEncryptedIkeMessage(buildIkeDeleteReq(mCurrentIkeSaRecord));
-            handleIkeFatalError(ikeException);
-        }
-
-        private void validateIkeAuthRespPostEap(List<IkePayload> payloadList)
-                throws IkeProtocolException {
-            IkeAuthPayload authPayload = null;
-
-            for (IkePayload payload : payloadList) {
-                switch (payload.payloadType) {
-                    case IkePayload.PAYLOAD_TYPE_AUTH:
-                        authPayload = (IkeAuthPayload) payload;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_NOTIFY:
-                        IkeNotifyPayload notifyPayload = (IkeNotifyPayload) payload;
-                        if (notifyPayload.isErrorNotify()) {
-                            throw notifyPayload.validateAndBuildIkeException();
-                        } else {
-                            // Unknown and unexpected status notifications are ignored as per
-                            // RFC7296.
-                            logw(
-                                    "Received unknown or unexpected status notifications with"
-                                            + " notify type: "
-                                            + notifyPayload.notifyType);
-                        }
-                        break;
-                    default:
-                        logw(
-                                "Received unexpected payload in IKE AUTH response. Payload"
-                                        + " type: "
-                                        + payload.payloadType);
-                }
-            }
-
-            // Verify existence of payloads
-            if (authPayload == null) {
-                throw new AuthenticationFailedException("Post-EAP Auth payload missing.");
-            }
-
-            authenticatePsk(mEapMsk, authPayload, mRespIdPayload);
-        }
-
-        @Override
-        public void exitState() {
-            mRetransmitter.stopRetransmitting();
-        }
-    }
-
-    private abstract class RekeyIkeHandlerBase extends DeleteBase {
-        private void validateIkeRekeyCommon(IkeMessage ikeMessage) throws InvalidSyntaxException {
-            boolean hasSaPayload = false;
-            boolean hasKePayload = false;
-            boolean hasNoncePayload = false;
-            for (IkePayload payload : ikeMessage.ikePayloadList) {
-                switch (payload.payloadType) {
-                    case IkePayload.PAYLOAD_TYPE_SA:
-                        hasSaPayload = true;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_KE:
-                        hasKePayload = true;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_NONCE:
-                        hasNoncePayload = true;
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_VENDOR:
-                        // Vendor payloads allowed, but not verified
-                        break;
-                    case IkePayload.PAYLOAD_TYPE_NOTIFY:
-                        // Notification payloads allowed, but left to handler methods to process.
-                        break;
-                    default:
-                        logw(
-                                "Received unexpected payload in IKE REKEY request. Payload type: "
-                                        + payload.payloadType);
-                }
-            }
-
-            if (!hasSaPayload || !hasKePayload || !hasNoncePayload) {
-                throw new InvalidSyntaxException("SA, KE or Nonce payload missing.");
-            }
-        }
-
-        @VisibleForTesting
-        void validateIkeRekeyReq(IkeMessage ikeMessage) throws InvalidSyntaxException {
-            // Skip validation of exchange type since it has been done during decoding request.
-
-            List<IkeNotifyPayload> notificationPayloads =
-                    ikeMessage.getPayloadListForType(
-                            IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-            for (IkeNotifyPayload notifyPayload : notificationPayloads) {
-                if (notifyPayload.isErrorNotify()) {
-                    logw("Error notifications invalid in request: " + notifyPayload.notifyType);
-                }
-            }
-
-            validateIkeRekeyCommon(ikeMessage);
-        }
-
-        @VisibleForTesting
-        void validateIkeRekeyResp(IkeMessage reqMsg, IkeMessage respMsg)
-                throws InvalidSyntaxException {
-            int exchangeType = respMsg.ikeHeader.exchangeType;
-            if (exchangeType != IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA
-                    && exchangeType != IkeHeader.EXCHANGE_TYPE_INFORMATIONAL) {
-                throw new InvalidSyntaxException(
-                        "Expected Rekey response (CREATE_CHILD_SA or INFORMATIONAL) but received: "
-                                + exchangeType);
-            }
-
-            List<IkeNotifyPayload> notificationPayloads =
-                    respMsg.getPayloadListForType(
-                            IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-            for (IkeNotifyPayload notifyPayload : notificationPayloads) {
-                if (notifyPayload.isErrorNotify()) {
-                    // Error notifications found. Stop validation for SA negotiation.
-                    return;
-                }
-            }
-
-            validateIkeRekeyCommon(respMsg);
-
-            // Verify DH groups matching
-            IkeKePayload reqKePayload =
-                    reqMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class);
-            IkeKePayload respKePayload =
-                    respMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class);
-            if (reqKePayload.dhGroup != respKePayload.dhGroup) {
-                throw new InvalidSyntaxException("Received KE payload with mismatched DH group.");
-            }
-        }
-
-        // It doesn't make sense to include multiple error notify payloads in one response. If it
-        // happens, IKE Session will only handle the most severe one.
-        protected boolean handleErrorNotifyIfExists(IkeMessage respMsg, boolean isSimulRekey) {
-            IkeNotifyPayload invalidSyntaxNotifyPayload = null;
-            IkeNotifyPayload tempFailureNotifyPayload = null;
-            IkeNotifyPayload firstErrorNotifyPayload = null;
-
-            List<IkeNotifyPayload> notificationPayloads =
-                    respMsg.getPayloadListForType(
-                            IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-            for (IkeNotifyPayload notifyPayload : notificationPayloads) {
-                if (!notifyPayload.isErrorNotify()) continue;
-
-                if (firstErrorNotifyPayload == null) firstErrorNotifyPayload = notifyPayload;
-
-                if (ERROR_TYPE_INVALID_SYNTAX == notifyPayload.notifyType) {
-                    invalidSyntaxNotifyPayload = notifyPayload;
-                } else if (ERROR_TYPE_TEMPORARY_FAILURE == notifyPayload.notifyType) {
-                    tempFailureNotifyPayload = notifyPayload;
-                }
-            }
-
-            // No error Notify Payload included in this response.
-            if (firstErrorNotifyPayload == null) return NOT_HANDLED;
-
-            // Handle Invalid Syntax if it exists
-            if (invalidSyntaxNotifyPayload != null) {
-                try {
-                    IkeProtocolException exception =
-                            invalidSyntaxNotifyPayload.validateAndBuildIkeException();
-                    handleIkeFatalError(exception);
-                } catch (InvalidSyntaxException e) {
-                    // Error notify payload has invalid syntax
-                    handleIkeFatalError(e);
-                }
-                return HANDLED;
-            }
-
-            if (tempFailureNotifyPayload != null) {
-                // Handle Temporary Failure if exists
-                loge("Received TEMPORARY_FAILURE for rekey IKE. Already handled during decoding.");
-            } else {
-                // Handle other errors
-                loge(
-                        "Received error notification: "
-                                + firstErrorNotifyPayload.notifyType
-                                + " for rekey IKE. Schedule a retry");
-                if (!isSimulRekey) {
-                    scheduleRetry(mCurrentIkeSaRecord.getFutureRekeyEvent());
-                }
-            }
-
-            if (isSimulRekey) {
-                transitionTo(mRekeyIkeRemoteDelete);
-            } else {
-                transitionTo(mIdle);
-            }
-            return HANDLED;
-        }
-
-        protected IkeSaRecord validateAndBuildIkeSa(
-                IkeMessage reqMsg, IkeMessage respMessage, boolean isLocalInit)
-                throws IkeProtocolException, GeneralSecurityException, IOException {
-            InetAddress initAddr = isLocalInit ? mLocalAddress : mRemoteAddress;
-            InetAddress respAddr = isLocalInit ? mRemoteAddress : mLocalAddress;
-
-            Pair<IkeProposal, IkeProposal> negotiatedProposals = null;
-            try {
-                IkeSaPayload reqSaPayload =
-                        reqMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-                IkeSaPayload respSaPayload =
-                        respMessage.getPayloadForType(
-                                IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-
-                // Throw exception or return valid negotiated proposal with allocated SPIs
-                negotiatedProposals =
-                        IkeSaPayload.getVerifiedNegotiatedIkeProposalPair(
-                                reqSaPayload, respSaPayload, mRemoteAddress);
-                IkeProposal reqProposal = negotiatedProposals.first;
-                IkeProposal respProposal = negotiatedProposals.second;
-
-                Provider provider = IkeMessage.getSecurityProvider();
-                IkeMacPrf newPrf;
-                IkeCipher newCipher;
-                IkeMacIntegrity newIntegrity = null;
-
-                newCipher =
-                        IkeCipher.create(
-                                respProposal.saProposal.getEncryptionTransforms()[0], provider);
-                if (!newCipher.isAead()) {
-                    newIntegrity =
-                            IkeMacIntegrity.create(
-                                    respProposal.saProposal.getIntegrityTransforms()[0], provider);
-                }
-                newPrf = IkeMacPrf.create(respProposal.saProposal.getPrfTransforms()[0], provider);
-
-                // Build new SaRecord
-                IkeSaRecord newSaRecord =
-                        IkeSaRecord.makeRekeyedIkeSaRecord(
-                                mCurrentIkeSaRecord,
-                                mIkePrf,
-                                reqMsg,
-                                respMessage,
-                                reqProposal.getIkeSpiResource(),
-                                respProposal.getIkeSpiResource(),
-                                newPrf,
-                                newIntegrity == null ? 0 : newIntegrity.getKeyLength(),
-                                newCipher.getKeyLength(),
-                                isLocalInit,
-                                new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
-
-                addIkeSaRecord(newSaRecord);
-
-                mIkeCipher = newCipher;
-                mIkePrf = newPrf;
-                mIkeIntegrity = newIntegrity;
-
-                return newSaRecord;
-            } catch (IkeProtocolException | GeneralSecurityException | IOException e) {
-                if (negotiatedProposals != null) {
-                    negotiatedProposals.first.getIkeSpiResource().close();
-                    negotiatedProposals.second.getIkeSpiResource().close();
-                }
-                throw e;
-            }
-        }
-    }
-
-    /** RekeyIkeLocalCreate represents state when IKE library initiates Rekey IKE exchange. */
-    class RekeyIkeLocalCreate extends RekeyIkeHandlerBase {
-        protected Retransmitter mRetransmitter;
-
-        @Override
-        public void enterState() {
-            try {
-                mRetransmitter = new EncryptedRetransmitter(buildIkeRekeyReq());
-            } catch (IOException e) {
-                loge("Fail to assign IKE SPI for rekey. Schedule a retry.", e);
-                scheduleRetry(mCurrentIkeSaRecord.getFutureRekeyEvent());
-                transitionTo(mIdle);
-            }
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        protected void handleTempFailure() {
-            mTempFailHandler.handleTempFailure(mCurrentIkeSaRecord.getFutureRekeyEvent());
-        }
-
-        /**
-         * Builds a IKE Rekey request, reusing the current proposal
-         *
-         * <p>As per RFC 7296, rekey messages are of format: { HDR { SK { SA, Ni, KEi } } }
-         *
-         * <p>This method currently reuses agreed upon proposal.
-         */
-        private IkeMessage buildIkeRekeyReq() throws IOException {
-            // TODO: Evaluate if we need to support different proposals for rekeys
-            IkeSaProposal[] saProposals = new IkeSaProposal[] {mSaProposal};
-
-            // No need to allocate SPIs; they will be allocated as part of the
-            // getRekeyIkeSaRequestPayloads
-            List<IkePayload> payloadList =
-                    CreateIkeSaHelper.getRekeyIkeSaRequestPayloads(saProposals, mLocalAddress);
-
-            // Build IKE header
-            IkeHeader ikeHeader =
-                    new IkeHeader(
-                            mCurrentIkeSaRecord.getInitiatorSpi(),
-                            mCurrentIkeSaRecord.getResponderSpi(),
-                            IkePayload.PAYLOAD_TYPE_SK,
-                            IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                            false /*isResponseMsg*/,
-                            mCurrentIkeSaRecord.isLocalInit,
-                            mCurrentIkeSaRecord.getLocalRequestMessageId());
-
-            return new IkeMessage(ikeHeader, payloadList);
-        }
-
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    handleDeleteSessionRequest(ikeMessage);
-                    break;
-                default:
-                    // TODO: Implement simultaneous rekey
-                    buildAndSendErrorNotificationResponse(
-                            mCurrentIkeSaRecord,
-                            ikeMessage.ikeHeader.messageId,
-                            ERROR_TYPE_TEMPORARY_FAILURE);
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                // Validate syntax
-                validateIkeRekeyResp(mRetransmitter.getMessage(), ikeMessage);
-
-                // Handle error notifications if they exist
-                if (handleErrorNotifyIfExists(ikeMessage, false /*isSimulRekey*/) == NOT_HANDLED) {
-                    // No error notifications included. Negotiate new SA
-                    mLocalInitNewIkeSaRecord =
-                            validateAndBuildIkeSa(
-                                    mRetransmitter.getMessage(), ikeMessage, true /*isLocalInit*/);
-                    transitionTo(mRekeyIkeLocalDelete);
-                }
-
-                // Stop retransmissions
-                mRetransmitter.stopRetransmitting();
-            } catch (IkeProtocolException e) {
-                if (e instanceof InvalidSyntaxException) {
-                    handleProcessRespOrSaCreationFailureAndQuit(e);
-                } else {
-                    handleProcessRespOrSaCreationFailureAndQuit(
-                            new InvalidSyntaxException(
-                                    "Error in processing IKE Rekey-Create response", e));
-                }
-
-            } catch (GeneralSecurityException | IOException e) {
-                handleProcessRespOrSaCreationFailureAndQuit(
-                        new IkeInternalException("Error in creating a new IKE SA during rekey", e));
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException ikeException) {
-            handleProcessRespOrSaCreationFailureAndQuit(ikeException);
-        }
-
-        private void handleProcessRespOrSaCreationFailureAndQuit(IkeException exception) {
-            // We don't retry rekey if failure was caused by invalid response or SA creation error.
-            // Reason is there is no way to notify the remote side the old SA is still alive but the
-            // new one has failed.
-
-            mRetransmitter.stopRetransmitting();
-
-            sendEncryptedIkeMessage(buildIkeDeleteReq(mCurrentIkeSaRecord));
-            handleIkeFatalError(exception);
-        }
-    }
-
-    /**
-     * SimulRekeyIkeLocalCreate represents the state where IKE library has replied to rekey request
-     * sent from the remote and is waiting for a rekey response for a locally initiated rekey
-     * request.
-     *
-     * <p>SimulRekeyIkeLocalCreate extends RekeyIkeLocalCreate so that it can call super class to
-     * validate incoming rekey response against locally initiated rekey request.
-     */
-    class SimulRekeyIkeLocalCreate extends RekeyIkeLocalCreate {
-        @Override
-        public void enterState() {
-            mRetransmitter = new EncryptedRetransmitter(null);
-            // TODO: Populate super.mRetransmitter from state initialization data
-            // Do not send request.
-        }
-
-        public IkeMessage buildRequest() {
-            throw new UnsupportedOperationException(
-                    "Do not support sending request in " + getCurrentState().getName());
-        }
-
-        @Override
-        public void exitState() {
-            // Do nothing.
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_RECEIVE_IKE_PACKET:
-                    ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
-                    IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
-
-                    if (mRemoteInitNewIkeSaRecord == getIkeSaRecordForPacket(ikeHeader)) {
-                        deferMessage(message);
-                    } else {
-                        handleReceivedIkePacket(message);
-                    }
-                    return HANDLED;
-
-                default:
-                    return super.processStateMessage(message);
-            }
-        }
-
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    deferMessage(message);
-                    return;
-                default:
-                    // TODO: Add more cases for other types of request.
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                validateIkeRekeyResp(mRetransmitter.getMessage(), ikeMessage);
-
-                // TODO: Check and handle error notifications before SA negotiation
-
-                mLocalInitNewIkeSaRecord =
-                        validateAndBuildIkeSa(
-                                mRetransmitter.getMessage(), ikeMessage, true /*isLocalInit*/);
-                transitionTo(mSimulRekeyIkeLocalDeleteRemoteDelete);
-            } catch (IkeProtocolException e) {
-                // TODO: Handle processing errors.
-            } catch (GeneralSecurityException e) {
-                // TODO: Fatal - kill session.
-            } catch (IOException e) {
-                // TODO: SPI allocation collided - delete new IKE SA, retry rekey.
-            }
-        }
-    }
-
-    /** RekeyIkeDeleteBase represents common behaviours of deleting stage during rekeying IKE SA. */
-    private abstract class RekeyIkeDeleteBase extends DeleteBase {
-        @Override
-        public boolean processStateMessage(Message message) {
-            switch (message.what) {
-                case CMD_RECEIVE_IKE_PACKET:
-                    ReceivedIkePacket receivedIkePacket = (ReceivedIkePacket) message.obj;
-                    IkeHeader ikeHeader = receivedIkePacket.ikeHeader;
-
-                    // Verify that this message is correctly authenticated and encrypted:
-                    IkeSaRecord ikeSaRecord = getIkeSaRecordForPacket(ikeHeader);
-                    boolean isMessageOnNewSa = false;
-                    if (ikeSaRecord != null && mIkeSaRecordSurviving == ikeSaRecord) {
-                        DecodeResult decodeResult =
-                                IkeMessage.decode(
-                                        ikeHeader.isResponseMsg
-                                                ? ikeSaRecord.getLocalRequestMessageId()
-                                                : ikeSaRecord.getRemoteRequestMessageId(),
-                                        mIkeIntegrity,
-                                        mIkeCipher,
-                                        ikeSaRecord,
-                                        ikeHeader,
-                                        receivedIkePacket.ikePacketBytes,
-                                        ikeSaRecord.getCollectedFragments(ikeHeader.isResponseMsg));
-                        isMessageOnNewSa =
-                                (decodeResult.status == DECODE_STATUS_PROTECTED_ERROR)
-                                        || (decodeResult.status == DECODE_STATUS_OK)
-                                        || (decodeResult.status == DECODE_STATUS_PARTIAL);
-                    }
-
-                    // Authenticated request received on the new/surviving SA; treat it as
-                    // an acknowledgement that the remote has successfully rekeyed.
-                    if (isMessageOnNewSa) {
-                        State nextState = mIdle;
-
-                        // This is the first IkeMessage seen on the new SA. It cannot be a response.
-                        // Likewise, if it a request, it must not be a retransmission. Verify msgId.
-                        // If either condition happens, consider rekey a success, but immediately
-                        // kill the session.
-                        if (ikeHeader.isResponseMsg
-                                || ikeSaRecord.getRemoteRequestMessageId() - ikeHeader.messageId
-                                        != 0) {
-                            nextState = mDeleteIkeLocalDelete;
-                        } else {
-                            deferMessage(message);
-                        }
-
-                        // Locally close old (and losing) IKE SAs. As a result of not waiting for
-                        // delete responses, the old SA can be left in a state where the stored ID
-                        // is no longer correct. However, this finishRekey() call will remove that
-                        // SA, so it doesn't matter.
-                        finishRekey();
-                        transitionTo(nextState);
-                    } else {
-                        handleReceivedIkePacket(message);
-                    }
-
-                    return HANDLED;
-                default:
-                    return super.processStateMessage(message);
-                    // TODO: Add more cases for other packet types.
-            }
-        }
-
-        // Rekey timer for old (and losing) SAs will be cancelled as part of the closing of the SA.
-        protected void finishRekey() {
-            mCurrentIkeSaRecord = mIkeSaRecordSurviving;
-            mLocalInitNewIkeSaRecord = null;
-            mRemoteInitNewIkeSaRecord = null;
-
-            mIkeSaRecordSurviving = null;
-
-            if (mIkeSaRecordAwaitingLocalDel != null) {
-                removeIkeSaRecord(mIkeSaRecordAwaitingLocalDel);
-                mIkeSaRecordAwaitingLocalDel.close();
-                mIkeSaRecordAwaitingLocalDel = null;
-            }
-
-            if (mIkeSaRecordAwaitingRemoteDel != null) {
-                removeIkeSaRecord(mIkeSaRecordAwaitingRemoteDel);
-                mIkeSaRecordAwaitingRemoteDel.close();
-                mIkeSaRecordAwaitingRemoteDel = null;
-            }
-
-            synchronized (mChildCbToSessions) {
-                for (ChildSessionStateMachine child : mChildCbToSessions.values()) {
-                    child.setSkD(mCurrentIkeSaRecord.getSkD());
-                }
-            }
-
-            // TODO: Update prf of all child sessions
-        }
-    }
-
-    /**
-     * SimulRekeyIkeLocalDeleteRemoteDelete represents the deleting stage during simultaneous
-     * rekeying when IKE library is waiting for both a Delete request and a Delete response.
-     */
-    class SimulRekeyIkeLocalDeleteRemoteDelete extends RekeyIkeDeleteBase {
-        private Retransmitter mRetransmitter;
-
-        @Override
-        public void enterState() {
-            // Detemine surviving IKE SA. According to RFC 7296: "The new IKE SA containing the
-            // lowest nonce SHOULD be deleted by the node that created it, and the other surviving
-            // new IKE SA MUST inherit all the Child SAs."
-            if (mLocalInitNewIkeSaRecord.compareTo(mRemoteInitNewIkeSaRecord) > 0) {
-                mIkeSaRecordSurviving = mLocalInitNewIkeSaRecord;
-                mIkeSaRecordAwaitingLocalDel = mCurrentIkeSaRecord;
-                mIkeSaRecordAwaitingRemoteDel = mRemoteInitNewIkeSaRecord;
-            } else {
-                mIkeSaRecordSurviving = mRemoteInitNewIkeSaRecord;
-                mIkeSaRecordAwaitingLocalDel = mLocalInitNewIkeSaRecord;
-                mIkeSaRecordAwaitingRemoteDel = mCurrentIkeSaRecord;
-            }
-            mRetransmitter =
-                    new EncryptedRetransmitter(
-                            mIkeSaRecordAwaitingLocalDel,
-                            buildIkeDeleteReq(mIkeSaRecordAwaitingLocalDel));
-            // TODO: Set timer awaiting for delete request.
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            IkeSaRecord ikeSaRecordForPacket = getIkeSaRecordForPacket(ikeMessage.ikeHeader);
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    try {
-                        validateIkeDeleteReq(ikeMessage, mIkeSaRecordAwaitingRemoteDel);
-                        IkeMessage respMsg =
-                                buildIkeDeleteResp(ikeMessage, mIkeSaRecordAwaitingRemoteDel);
-                        removeIkeSaRecord(mIkeSaRecordAwaitingRemoteDel);
-                        // TODO: Encode and send response and close
-                        // mIkeSaRecordAwaitingRemoteDel.
-                        // TODO: Stop timer awating delete request.
-                        transitionTo(mSimulRekeyIkeLocalDelete);
-                    } catch (InvalidSyntaxException e) {
-                        logd("Validation failed for delete request", e);
-                        // TODO: Shutdown - fatal error
-                    }
-                    return;
-                default:
-                    // TODO: Reply with TEMPORARY_FAILURE
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                validateIkeDeleteResp(ikeMessage, mIkeSaRecordAwaitingLocalDel);
-                finishDeleteIkeSaAwaitingLocalDel();
-            } catch (InvalidSyntaxException e) {
-                loge("Invalid syntax on IKE Delete response. Shutting down anyways", e);
-                finishDeleteIkeSaAwaitingLocalDel();
-            } catch (IllegalStateException e) {
-                // Response received on incorrect SA
-                cleanUpAndQuit(e);
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException exception) {
-            if (mIkeSaRecordAwaitingLocalDel == ikeSaRecord) {
-                loge("Invalid syntax on IKE Delete response. Shutting down anyways", exception);
-                finishDeleteIkeSaAwaitingLocalDel();
-            } else {
-                cleanUpAndQuit(
-                        new IllegalStateException("Delete response received on incorrect SA"));
-            }
-        }
-
-        private void finishDeleteIkeSaAwaitingLocalDel() {
-            mRetransmitter.stopRetransmitting();
-
-            removeIkeSaRecord(mIkeSaRecordAwaitingLocalDel);
-            mIkeSaRecordAwaitingLocalDel.close();
-            mIkeSaRecordAwaitingLocalDel = null;
-
-            transitionTo(mSimulRekeyIkeRemoteDelete);
-        }
-
-        @Override
-        public void exitState() {
-            finishRekey();
-            mRetransmitter.stopRetransmitting();
-            // TODO: Stop awaiting delete request timer.
-        }
-    }
-
-    /**
-     * SimulRekeyIkeLocalDelete represents the state when IKE library is waiting for a Delete
-     * response during simultaneous rekeying.
-     */
-    class SimulRekeyIkeLocalDelete extends RekeyIkeDeleteBase {
-        private Retransmitter mRetransmitter;
-
-        @Override
-        public void enterState() {
-            mRetransmitter = new EncryptedRetransmitter(mIkeSaRecordAwaitingLocalDel, null);
-            // TODO: Populate mRetransmitter from state initialization data.
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            // Always return a TEMPORARY_FAILURE. In no case should we accept a message on an SA
-            // that is going away. All messages on the new SA is caught in RekeyIkeDeleteBase
-            buildAndSendErrorNotificationResponse(
-                    mIkeSaRecordAwaitingLocalDel,
-                    ikeMessage.ikeHeader.messageId,
-                    ERROR_TYPE_TEMPORARY_FAILURE);
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                validateIkeDeleteResp(ikeMessage, mIkeSaRecordAwaitingLocalDel);
-                finishRekey();
-                transitionTo(mIdle);
-            } catch (InvalidSyntaxException e) {
-                loge(
-                        "Invalid syntax on IKE Delete response. Shutting down old IKE SA and"
-                                + " finishing rekey",
-                        e);
-                finishRekey();
-                transitionTo(mIdle);
-            } catch (IllegalStateException e) {
-                // Response received on incorrect SA
-                cleanUpAndQuit(e);
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException exception) {
-            if (mIkeSaRecordAwaitingLocalDel == ikeSaRecord) {
-                loge(
-                        "Invalid syntax on IKE Delete response. Shutting down old IKE SA and"
-                                + " finishing rekey",
-                        exception);
-                finishRekey();
-                transitionTo(mIdle);
-            } else {
-                cleanUpAndQuit(
-                        new IllegalStateException("Delete response received on incorrect SA"));
-            }
-        }
-    }
-
-    /**
-     * SimulRekeyIkeRemoteDelete represents the state that waiting for a Delete request during
-     * simultaneous rekeying.
-     */
-    class SimulRekeyIkeRemoteDelete extends RekeyIkeDeleteBase {
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            // At this point, the incoming request can ONLY be on mIkeSaRecordAwaitingRemoteDel - if
-            // it was on the surviving SA, it is deferred and the rekey is finished. It is likewise
-            // impossible to have this on the local-deleted SA, since the delete has already been
-            // acknowledged in the SimulRekeyIkeLocalDeleteRemoteDelete state.
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    try {
-                        validateIkeDeleteReq(ikeMessage, mIkeSaRecordAwaitingRemoteDel);
-
-                        IkeMessage respMsg =
-                                buildIkeDeleteResp(ikeMessage, mIkeSaRecordAwaitingRemoteDel);
-                        sendEncryptedIkeMessage(mIkeSaRecordAwaitingRemoteDel, respMsg);
-
-                        finishRekey();
-                        transitionTo(mIdle);
-                    } catch (InvalidSyntaxException e) {
-                        // Program error.
-                        cleanUpAndQuit(new IllegalStateException(e));
-                    }
-                    return;
-                default:
-                    buildAndSendErrorNotificationResponse(
-                            mIkeSaRecordAwaitingRemoteDel,
-                            ikeMessage.ikeHeader.messageId,
-                            ERROR_TYPE_TEMPORARY_FAILURE);
-            }
-        }
-    }
-
-    /**
-     * RekeyIkeLocalDelete represents the deleting stage when IKE library is initiating a Rekey
-     * procedure.
-     *
-     * <p>RekeyIkeLocalDelete and SimulRekeyIkeLocalDelete have same behaviours in
-     * processStateMessage(). While RekeyIkeLocalDelete overrides enterState() and exitState()
-     * methods for initiating and finishing the deleting stage for IKE rekeying.
-     */
-    class RekeyIkeLocalDelete extends SimulRekeyIkeLocalDelete {
-        private Retransmitter mRetransmitter;
-
-        @Override
-        public void enterState() {
-            mIkeSaRecordSurviving = mLocalInitNewIkeSaRecord;
-            mIkeSaRecordAwaitingLocalDel = mCurrentIkeSaRecord;
-            mRetransmitter =
-                    new EncryptedRetransmitter(
-                            mIkeSaRecordAwaitingLocalDel,
-                            buildIkeDeleteReq(mIkeSaRecordAwaitingLocalDel));
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        public void exitState() {
-            mRetransmitter.stopRetransmitting();
-        }
-    }
-
-    /**
-     * RekeyIkeRemoteDelete represents the deleting stage when responding to a Rekey procedure.
-     *
-     * <p>RekeyIkeRemoteDelete and SimulRekeyIkeRemoteDelete have same behaviours in
-     * processStateMessage(). While RekeyIkeLocalDelete overrides enterState() and exitState()
-     * methods for waiting incoming delete request and for finishing the deleting stage for IKE
-     * rekeying.
-     */
-    class RekeyIkeRemoteDelete extends SimulRekeyIkeRemoteDelete {
-        @Override
-        public void enterState() {
-            mIkeSaRecordSurviving = mRemoteInitNewIkeSaRecord;
-            mIkeSaRecordAwaitingRemoteDel = mCurrentIkeSaRecord;
-
-            sendMessageDelayed(TIMEOUT_REKEY_REMOTE_DELETE, REKEY_DELETE_TIMEOUT_MS);
-        }
-
-        @Override
-        public boolean processStateMessage(Message message) {
-            // Intercept rekey delete timeout. Assume rekey succeeded since no retransmissions
-            // were received.
-            if (message.what == TIMEOUT_REKEY_REMOTE_DELETE) {
-                finishRekey();
-                transitionTo(mIdle);
-
-                return HANDLED;
-            } else {
-                return super.processStateMessage(message);
-            }
-        }
-
-        @Override
-        public void exitState() {
-            removeMessages(TIMEOUT_REKEY_REMOTE_DELETE);
-        }
-    }
-
-    /** DeleteIkeLocalDelete initiates a deletion request of the current IKE Session. */
-    class DeleteIkeLocalDelete extends DeleteBase {
-        private Retransmitter mRetransmitter;
-
-        @Override
-        public void enterState() {
-            mRetransmitter = new EncryptedRetransmitter(buildIkeDeleteReq(mCurrentIkeSaRecord));
-        }
-
-        @Override
-        protected void triggerRetransmit() {
-            mRetransmitter.retransmit();
-        }
-
-        @Override
-        protected void handleRequestIkeMessage(
-                IkeMessage ikeMessage, int ikeExchangeSubType, Message message) {
-            switch (ikeExchangeSubType) {
-                case IKE_EXCHANGE_SUBTYPE_DELETE_IKE:
-                    handleDeleteSessionRequest(ikeMessage);
-                    return;
-                default:
-                    buildAndSendErrorNotificationResponse(
-                            mCurrentIkeSaRecord,
-                            ikeMessage.ikeHeader.messageId,
-                            ERROR_TYPE_TEMPORARY_FAILURE);
-            }
-        }
-
-        @Override
-        protected void handleResponseIkeMessage(IkeMessage ikeMessage) {
-            try {
-                validateIkeDeleteResp(ikeMessage, mCurrentIkeSaRecord);
-                mUserCbExecutor.execute(
-                        () -> {
-                            mIkeSessionCallback.onClosed();
-                        });
-
-                removeIkeSaRecord(mCurrentIkeSaRecord);
-                mCurrentIkeSaRecord.close();
-                mCurrentIkeSaRecord = null;
-                quitNow();
-            } catch (InvalidSyntaxException e) {
-                handleResponseGenericProcessError(mCurrentIkeSaRecord, e);
-            }
-        }
-
-        @Override
-        protected void handleResponseGenericProcessError(
-                IkeSaRecord ikeSaRecord, InvalidSyntaxException exception) {
-            loge("Invalid syntax on IKE Delete response. Shutting down anyways", exception);
-            handleIkeFatalError(exception);
-            quitNow();
-        }
-
-        @Override
-        public void exitState() {
-            mRetransmitter.stopRetransmitting();
-        }
-    }
-
-    /**
-     * Helper class to generate IKE SA creation payloads, in both request and response directions.
-     */
-    private static class CreateIkeSaHelper {
-        public static List<IkePayload> getIkeInitSaRequestPayloads(
-                IkeSaProposal[] saProposals,
-                long initIkeSpi,
-                long respIkeSpi,
-                InetAddress localAddr,
-                InetAddress remoteAddr,
-                int localPort,
-                int remotePort)
-                throws IOException {
-            List<IkePayload> payloadList =
-                    getCreateIkeSaPayloads(IkeSaPayload.createInitialIkeSaPayload(saProposals));
-
-            // Though RFC says Notify-NAT payload is "just after the Ni and Nr payloads (before the
-            // optional CERTREQ payload)", it also says recipient MUST NOT reject " messages in
-            // which the payloads were not in the "right" order" due to the lack of clarity of the
-            // payload order.
-            payloadList.add(
-                    new IkeNotifyPayload(
-                            NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP,
-                            IkeNotifyPayload.generateNatDetectionData(
-                                    initIkeSpi, respIkeSpi, localAddr, localPort)));
-            payloadList.add(
-                    new IkeNotifyPayload(
-                            NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP,
-                            IkeNotifyPayload.generateNatDetectionData(
-                                    initIkeSpi, respIkeSpi, remoteAddr, remotePort)));
-            return payloadList;
-        }
-
-        public static List<IkePayload> getRekeyIkeSaRequestPayloads(
-                IkeSaProposal[] saProposals, InetAddress localAddr) throws IOException {
-            if (localAddr == null) {
-                throw new IllegalArgumentException("Local address was null for rekey");
-            }
-
-            return getCreateIkeSaPayloads(
-                    IkeSaPayload.createRekeyIkeSaRequestPayload(saProposals, localAddr));
-        }
-
-        public static List<IkePayload> getRekeyIkeSaResponsePayloads(
-                byte respProposalNumber, IkeSaProposal saProposal, InetAddress localAddr)
-                throws IOException {
-            if (localAddr == null) {
-                throw new IllegalArgumentException("Local address was null for rekey");
-            }
-
-            return getCreateIkeSaPayloads(
-                    IkeSaPayload.createRekeyIkeSaResponsePayload(
-                            respProposalNumber, saProposal, localAddr));
-        }
-
-        /**
-         * Builds the initial or rekey IKE creation payloads.
-         *
-         * <p>Will return a non-empty list of IkePayloads, the first of which WILL be the SA payload
-         */
-        private static List<IkePayload> getCreateIkeSaPayloads(IkeSaPayload saPayload)
-                throws IOException {
-            if (saPayload.proposalList.size() == 0) {
-                throw new IllegalArgumentException("Invalid SA proposal list - was empty");
-            }
-
-            List<IkePayload> payloadList = new ArrayList<>(3);
-
-            payloadList.add(saPayload);
-            payloadList.add(new IkeNoncePayload());
-
-            // SaPropoals.Builder guarantees that each SA proposal has at least one DH group.
-            DhGroupTransform dhGroupTransform =
-                    ((IkeProposal) saPayload.proposalList.get(0))
-                            .saProposal
-                            .getDhGroupTransforms()[0];
-            payloadList.add(new IkeKePayload(dhGroupTransform.id));
-
-            return payloadList;
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/SaRecord.java b/src/java/com/android/internal/net/ipsec/ike/SaRecord.java
deleted file mode 100644
index 035af17..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/SaRecord.java
+++ /dev/null
@@ -1,1098 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike;
-
-import static android.net.ipsec.ike.IkeManager.getIkeLog;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.ResourceUnavailableException;
-import android.net.IpSecManager.SecurityParameterIndex;
-import android.net.IpSecManager.SpiUnavailableException;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.IpSecTransform;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.message.IkeKePayload;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial;
-import com.android.internal.net.ipsec.ike.message.IkeNoncePayload;
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-
-import dalvik.system.CloseGuard;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * SaRecord represents common information of an IKE SA and a Child SA.
- *
- * <p>When doing rekey, there can be multiple SAs in the same IkeSessionStateMachine or
- * ChildSessionStateMachine, where they use same cryptographic algorithms but with different keys.
- * We store cryptographic algorithms and unchanged SA configurations in IkeSessionOptions or
- * ChildSessionOptions and store changed information including keys, SPIs, and nonces in SaRecord.
- *
- * <p>All keys are named by the key type plus the source of the traffic this key is protecting. For
- * example, "mSkAi" represents the integrity key that protects traffic from the SA initiator to the
- * SA responder.
- *
- * <p>Except for keys, all other paramters (SPIs, nonces and messages) are named by the creator. For
- * example, "initSPI" represents a SPI that is created by the SA initiator.
- */
-public abstract class SaRecord implements AutoCloseable {
-    private static ISaRecordHelper sSaRecordHelper = new SaRecordHelper();
-    private static IIpSecTransformHelper sIpSecTransformHelper = new IpSecTransformHelper();
-
-    /** Flag indicates if this SA is locally initiated */
-    public final boolean isLocalInit;
-
-    public final byte[] nonceInitiator;
-    public final byte[] nonceResponder;
-
-    private final byte[] mSkAi;
-    private final byte[] mSkAr;
-    private final byte[] mSkEi;
-    private final byte[] mSkEr;
-
-    private final LocalRequest mFutureRekeyEvent;
-
-    private final CloseGuard mCloseGuard = CloseGuard.get();
-
-    /** Package private */
-    SaRecord(
-            boolean localInit,
-            byte[] nonceInit,
-            byte[] nonceResp,
-            byte[] skAi,
-            byte[] skAr,
-            byte[] skEi,
-            byte[] skEr,
-            LocalRequest futureRekeyEvent) {
-        isLocalInit = localInit;
-        nonceInitiator = nonceInit;
-        nonceResponder = nonceResp;
-
-        mSkAi = skAi;
-        mSkAr = skAr;
-        mSkEi = skEi;
-        mSkEr = skEr;
-
-        logKey("SK_ai", skAi);
-        logKey("SK_ar", skAr);
-        logKey("SK_ei", skEi);
-        logKey("SK_er", skEr);
-
-        mFutureRekeyEvent = futureRekeyEvent;
-
-        mCloseGuard.open("close");
-    }
-
-    private void logKey(String type, byte[] key) {
-        getIkeLog().d(getTag(), type + ": " + getIkeLog().pii(key));
-    }
-
-    protected abstract String getTag();
-
-    /**
-     * Get the integrity key for calculate integrity checksum for an outbound packet.
-     *
-     * @return the integrity key in a byte array, which will be empty if integrity algorithm is not
-     *     used in this SA.
-     */
-    public byte[] getOutboundIntegrityKey() {
-        return isLocalInit ? mSkAi : mSkAr;
-    }
-
-    /**
-     * Get the integrity key to authenticate an inbound packet.
-     *
-     * @return the integrity key in a byte array, which will be empty if integrity algorithm is not
-     *     used in this SA.
-     */
-    public byte[] getInboundIntegrityKey() {
-        return isLocalInit ? mSkAr : mSkAi;
-    }
-
-    /**
-     * Get the encryption key for protecting an outbound packet.
-     *
-     * @return the encryption key in a byte array.
-     */
-    public byte[] getOutboundEncryptionKey() {
-        return isLocalInit ? mSkEi : mSkEr;
-    }
-
-    /**
-     * Get the decryption key for an inbound packet.
-     *
-     * @return the decryption key in a byte array.
-     */
-    public byte[] getInboundDecryptionKey() {
-        return isLocalInit ? mSkEr : mSkEi;
-    }
-
-    /** Check that the SaRecord was closed properly. */
-    @Override
-    protected void finalize() throws Throwable {
-        if (mCloseGuard != null) {
-            mCloseGuard.warnIfOpen();
-        }
-        close();
-    }
-
-    @Override
-    public void close() {
-        mFutureRekeyEvent.cancel();
-    }
-
-    /** Package private */
-    LocalRequest getFutureRekeyEvent() {
-        return mFutureRekeyEvent;
-    }
-
-    /** Package private */
-    @VisibleForTesting
-    static void setSaRecordHelper(ISaRecordHelper helper) {
-        sSaRecordHelper = helper;
-    }
-
-    /** Package private */
-    @VisibleForTesting
-    static void setIpSecTransformHelper(IIpSecTransformHelper helper) {
-        sIpSecTransformHelper = helper;
-    }
-
-    /**
-     * SaRecordHelper implements methods for constructing SaRecord.
-     *
-     * <p>Package private
-     */
-    static class SaRecordHelper implements ISaRecordHelper {
-        @Override
-        public IkeSaRecord makeFirstIkeSaRecord(
-                IkeMessage initRequest,
-                IkeMessage initResponse,
-                IkeSaRecordConfig ikeSaRecordConfig)
-                throws GeneralSecurityException {
-            // Extract nonces
-            byte[] nonceInit =
-                    initRequest.getPayloadForType(
-                                    IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)
-                            .nonceData;
-            byte[] nonceResp =
-                    initResponse.getPayloadForType(
-                                    IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)
-                            .nonceData;
-
-            // Get SKEYSEED
-            byte[] sharedDhKey = getSharedKey(initRequest, initResponse);
-            byte[] sKeySeed =
-                    ikeSaRecordConfig.prf.generateSKeySeed(nonceInit, nonceResp, sharedDhKey);
-
-            return makeIkeSaRecord(sKeySeed, nonceInit, nonceResp, ikeSaRecordConfig);
-        }
-
-        @Override
-        public IkeSaRecord makeRekeyedIkeSaRecord(
-                IkeSaRecord oldSaRecord,
-                IkeMacPrf oldPrf,
-                IkeMessage rekeyRequest,
-                IkeMessage rekeyResponse,
-                IkeSaRecordConfig ikeSaRecordConfig)
-                throws GeneralSecurityException {
-            // Extract nonces
-            byte[] nonceInit =
-                    rekeyRequest.getPayloadForType(
-                                    IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)
-                            .nonceData;
-            byte[] nonceResp =
-                    rekeyResponse.getPayloadForType(
-                                    IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class)
-                            .nonceData;
-
-            // Get SKEYSEED
-            IkeMessage localMsg = ikeSaRecordConfig.isLocalInit ? rekeyRequest : rekeyResponse;
-            IkeMessage remoteMsg = ikeSaRecordConfig.isLocalInit ? rekeyResponse : rekeyRequest;
-
-            byte[] sharedDhKey = getSharedKey(localMsg, remoteMsg);
-            byte[] sKeySeed =
-                    oldPrf.generateRekeyedSKeySeed(
-                            oldSaRecord.mSkD, nonceInit, nonceResp, sharedDhKey);
-
-            return makeIkeSaRecord(sKeySeed, nonceInit, nonceResp, ikeSaRecordConfig);
-        }
-
-        private byte[] getSharedKey(IkeMessage keLocalMessage, IkeMessage keRemoteMessage)
-                throws GeneralSecurityException {
-            IkeKePayload keLocalPayload =
-                    keLocalMessage.getPayloadForType(
-                            IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class);
-            IkeKePayload keRemotePayload =
-                    keRemoteMessage.getPayloadForType(
-                            IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class);
-
-            return IkeKePayload.getSharedKey(
-                    keLocalPayload.localPrivateKey, keRemotePayload.keyExchangeData);
-        }
-
-        /**
-         * Package private method for calculating keys and construct IkeSaRecord.
-         *
-         * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.13">RFC 7296, Internet Key
-         *     Exchange Protocol Version 2 (IKEv2), Generating Keying Material</a>
-         */
-        @VisibleForTesting
-        IkeSaRecord makeIkeSaRecord(
-                byte[] sKeySeed,
-                byte[] nonceInit,
-                byte[] nonceResp,
-                IkeSaRecordConfig ikeSaRecordConfig) {
-            // Build data to sign for generating the keying material.
-            ByteBuffer bufferToSign =
-                    ByteBuffer.allocate(
-                            nonceInit.length + nonceResp.length + 2 * IkePayload.SPI_LEN_IKE);
-
-            IkeSecurityParameterIndex initSpi = ikeSaRecordConfig.initSpi;
-            IkeSecurityParameterIndex respSpi = ikeSaRecordConfig.respSpi;
-            IkeMacPrf prf = ikeSaRecordConfig.prf;
-            int integrityKeyLength = ikeSaRecordConfig.integrityKeyLength;
-            int encryptionKeyLength = ikeSaRecordConfig.encryptionKeyLength;
-
-            bufferToSign
-                    .put(nonceInit)
-                    .put(nonceResp)
-                    .putLong(initSpi.getSpi())
-                    .putLong(respSpi.getSpi());
-
-            // Get length of the keying material according to RFC 7296, 2.13 and 2.14. The length of
-            // SK_D is always equal to the length of PRF key.
-            int skDLength = prf.getKeyLength();
-            int keyMaterialLen =
-                    skDLength
-                            + 2 * integrityKeyLength
-                            + 2 * encryptionKeyLength
-                            + 2 * prf.getKeyLength();
-            byte[] keyMat = prf.generateKeyMat(sKeySeed, bufferToSign.array(), keyMaterialLen);
-
-            // Extract keys.
-            byte[] skD = new byte[skDLength];
-            byte[] skAi = new byte[integrityKeyLength];
-            byte[] skAr = new byte[integrityKeyLength];
-            byte[] skEi = new byte[encryptionKeyLength];
-            byte[] skEr = new byte[encryptionKeyLength];
-            byte[] skPi = new byte[prf.getKeyLength()];
-            byte[] skPr = new byte[prf.getKeyLength()];
-
-            ByteBuffer keyMatBuffer = ByteBuffer.wrap(keyMat);
-            keyMatBuffer.get(skD).get(skAi).get(skAr).get(skEi).get(skEr).get(skPi).get(skPr);
-            return new IkeSaRecord(
-                    initSpi,
-                    respSpi,
-                    ikeSaRecordConfig.isLocalInit,
-                    nonceInit,
-                    nonceResp,
-                    skD,
-                    skAi,
-                    skAr,
-                    skEi,
-                    skEr,
-                    skPi,
-                    skPr,
-                    ikeSaRecordConfig.futureRekeyEvent);
-        }
-
-        @Override
-        public ChildSaRecord makeChildSaRecord(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                ChildSaRecordConfig childSaRecordConfig)
-                throws GeneralSecurityException, ResourceUnavailableException,
-                        SpiUnavailableException, IOException {
-            // Extract nonces. Encoding/Decoding of payload list guarantees that there is only one
-            // nonce payload in the reqPayloads and respPayloads lists
-            byte[] nonceInit =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                                    IkePayload.PAYLOAD_TYPE_NONCE,
-                                    IkeNoncePayload.class,
-                                    reqPayloads)
-                            .nonceData;
-            byte[] nonceResp =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                                    IkePayload.PAYLOAD_TYPE_NONCE,
-                                    IkeNoncePayload.class,
-                                    respPayloads)
-                            .nonceData;
-
-            // Check if KE Payload exists and get DH shared key. Encoding/Decoding of payload list
-            // guarantees that there is either no KE payload in the reqPayloads and respPayloads
-            // lists, or only one KE payload in each list.
-            byte[] sharedDhKey = new byte[0];
-            IkeKePayload keInitPayload =
-                    IkePayload.getPayloadForTypeInProvidedList(
-                            IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class, reqPayloads);
-            if (keInitPayload != null) {
-                IkeKePayload keRespPayload =
-                        IkePayload.getPayloadForTypeInProvidedList(
-                                IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class, respPayloads);
-                sharedDhKey =
-                        IkeKePayload.getSharedKey(
-                                keInitPayload.localPrivateKey, keRespPayload.keyExchangeData);
-            }
-
-            return makeChildSaRecord(sharedDhKey, nonceInit, nonceResp, childSaRecordConfig);
-        }
-        /**
-         * Package private method for calculating keys, build IpSecTransforms and construct
-         * ChildSaRecord.
-         *
-         * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.17">RFC 7296, Internet Key
-         *     Exchange Protocol Version 2 (IKEv2), Generating Keying Material for Child SAs</a>
-         */
-        @VisibleForTesting
-        ChildSaRecord makeChildSaRecord(
-                byte[] sharedKey,
-                byte[] nonceInit,
-                byte[] nonceResp,
-                ChildSaRecordConfig childSaRecordConfig)
-                throws ResourceUnavailableException, SpiUnavailableException, IOException {
-            // Build data to sign for generating the keying material.
-            ByteBuffer bufferToSign =
-                    ByteBuffer.allocate(sharedKey.length + nonceInit.length + nonceResp.length);
-            bufferToSign.put(sharedKey).put(nonceInit).put(nonceResp);
-
-            // Get length of the keying material according to RFC 7296, 2.17.
-            int encryptionKeyLength = childSaRecordConfig.encryptionAlgo.getKeyLength();
-            int integrityKeyLength =
-                    childSaRecordConfig.hasIntegrityAlgo
-                            ? childSaRecordConfig.integrityAlgo.getKeyLength()
-                            : 0;
-            int keyMaterialLen = 2 * encryptionKeyLength + 2 * integrityKeyLength;
-            byte[] keyMat =
-                    childSaRecordConfig.ikePrf.generateKeyMat(
-                            childSaRecordConfig.skD, bufferToSign.array(), keyMaterialLen);
-
-            // Extract keys according to the order that keys carrying data from initiator to
-            // responder are taken before keys for the other direction and encryption keys are taken
-            // before integrity keys.
-            byte[] skEi = new byte[encryptionKeyLength];
-            byte[] skAi = new byte[integrityKeyLength];
-            byte[] skEr = new byte[encryptionKeyLength];
-            byte[] skAr = new byte[integrityKeyLength];
-
-            ByteBuffer keyMatBuffer = ByteBuffer.wrap(keyMat);
-            keyMatBuffer.get(skEi).get(skAi).get(skEr).get(skAr);
-
-            // IpSecTransform for traffic from the initiator
-            IpSecTransform initTransform = null;
-            // IpSecTransform for traffic from the responder
-            IpSecTransform respTransform = null;
-            try {
-                // Build IpSecTransform
-                initTransform =
-                        sIpSecTransformHelper.makeIpSecTransform(
-                                childSaRecordConfig.context,
-                                childSaRecordConfig.initAddress /*source address*/,
-                                childSaRecordConfig.udpEncapSocket,
-                                childSaRecordConfig.respSpi /*destination SPI*/,
-                                childSaRecordConfig.integrityAlgo,
-                                childSaRecordConfig.encryptionAlgo,
-                                skAi,
-                                skEi,
-                                childSaRecordConfig.isTransport);
-                respTransform =
-                        sIpSecTransformHelper.makeIpSecTransform(
-                                childSaRecordConfig.context,
-                                childSaRecordConfig.respAddress /*source address*/,
-                                childSaRecordConfig.udpEncapSocket,
-                                childSaRecordConfig.initSpi /*destination SPI*/,
-                                childSaRecordConfig.integrityAlgo,
-                                childSaRecordConfig.encryptionAlgo,
-                                skAr,
-                                skEr,
-                                childSaRecordConfig.isTransport);
-
-                int initSpi = childSaRecordConfig.initSpi.getSpi();
-                int respSpi = childSaRecordConfig.respSpi.getSpi();
-
-                boolean isLocalInit = childSaRecordConfig.isLocalInit;
-                int inSpi = isLocalInit ? initSpi : respSpi;
-                int outSpi = isLocalInit ? respSpi : initSpi;
-                IpSecTransform inTransform = isLocalInit ? respTransform : initTransform;
-                IpSecTransform outTransform = isLocalInit ? initTransform : respTransform;
-
-                return new ChildSaRecord(
-                        inSpi,
-                        outSpi,
-                        isLocalInit,
-                        nonceInit,
-                        nonceResp,
-                        skAi,
-                        skAr,
-                        skEi,
-                        skEr,
-                        inTransform,
-                        outTransform,
-                        childSaRecordConfig.futureRekeyEvent);
-
-            } catch (Exception e) {
-                if (initTransform != null) initTransform.close();
-                if (respTransform != null) respTransform.close();
-                throw e;
-            }
-        }
-    }
-
-    /**
-     * IpSecTransformHelper implements the IIpSecTransformHelper interface for constructing {@link
-     * IpSecTransform}}.
-     *
-     * <p>Package private
-     */
-    static class IpSecTransformHelper implements IIpSecTransformHelper {
-        private static final String TAG = "IpSecTransformHelper";
-
-        @Override
-        public IpSecTransform makeIpSecTransform(
-                Context context,
-                InetAddress sourceAddress,
-                UdpEncapsulationSocket udpEncapSocket,
-                IpSecManager.SecurityParameterIndex spi,
-                @Nullable IkeMacIntegrity integrityAlgo,
-                IkeCipher encryptionAlgo,
-                byte[] integrityKey,
-                byte[] encryptionKey,
-                boolean isTransport)
-                throws ResourceUnavailableException, SpiUnavailableException, IOException {
-            IpSecTransform.Builder builder = new IpSecTransform.Builder(context);
-
-            if (encryptionAlgo.isAead()) {
-                builder.setAuthenticatedEncryption(
-                        encryptionAlgo.buildIpSecAlgorithmWithKey(encryptionKey));
-            } else {
-                builder.setEncryption(encryptionAlgo.buildIpSecAlgorithmWithKey(encryptionKey));
-                builder.setAuthentication(integrityAlgo.buildIpSecAlgorithmWithKey(integrityKey));
-            }
-
-            if (udpEncapSocket != null && sourceAddress instanceof Inet6Address) {
-                getIkeLog().wtf(TAG, "Kernel does not support UDP encapsulation for IPv6 SAs");
-            }
-            if (udpEncapSocket != null && sourceAddress instanceof Inet4Address) {
-                builder.setIpv4Encapsulation(udpEncapSocket, IkeSocket.IKE_SERVER_PORT);
-            }
-
-            if (isTransport) {
-                return builder.buildTransportModeTransform(sourceAddress, spi);
-            } else {
-                return builder.buildTunnelModeTransform(sourceAddress, spi);
-            }
-        }
-    }
-
-    /** Package private class to group parameters for building a ChildSaRecord. */
-    @VisibleForTesting
-    static final class ChildSaRecordConfig {
-        public final Context context;
-        public final SecurityParameterIndex initSpi;
-        public final SecurityParameterIndex respSpi;
-        public final InetAddress initAddress;
-        public final InetAddress respAddress;
-        @Nullable public final UdpEncapsulationSocket udpEncapSocket;
-        public final IkeMacPrf ikePrf;
-        @Nullable public final IkeMacIntegrity integrityAlgo;
-        public final IkeCipher encryptionAlgo;
-        public final byte[] skD;
-        public final boolean isTransport;
-        public final boolean isLocalInit;
-        public final boolean hasIntegrityAlgo;
-        public final ChildLocalRequest futureRekeyEvent;
-
-        ChildSaRecordConfig(
-                Context context,
-                SecurityParameterIndex initSpi,
-                SecurityParameterIndex respSpi,
-                InetAddress localAddress,
-                InetAddress remoteAddress,
-                @Nullable UdpEncapsulationSocket udpEncapSocket,
-                IkeMacPrf ikePrf,
-                @Nullable IkeMacIntegrity integrityAlgo,
-                IkeCipher encryptionAlgo,
-                byte[] skD,
-                boolean isTransport,
-                boolean isLocalInit,
-                ChildLocalRequest futureRekeyEvent) {
-            this.context = context;
-            this.initSpi = initSpi;
-            this.respSpi = respSpi;
-            this.initAddress = isLocalInit ? localAddress : remoteAddress;
-            this.respAddress = isLocalInit ? remoteAddress : localAddress;
-            this.udpEncapSocket = udpEncapSocket;
-            this.ikePrf = ikePrf;
-            this.integrityAlgo = integrityAlgo;
-            this.encryptionAlgo = encryptionAlgo;
-            this.skD = skD;
-            this.isTransport = isTransport;
-            this.isLocalInit = isLocalInit;
-            hasIntegrityAlgo = (integrityAlgo != null);
-            this.futureRekeyEvent = futureRekeyEvent;
-        }
-    }
-
-    /** IkeSaRecord represents an IKE SA. */
-    public static class IkeSaRecord extends SaRecord implements Comparable<IkeSaRecord> {
-        private static final String TAG = "IkeSaRecord";
-
-        /** SPI of IKE SA initiator */
-        private final IkeSecurityParameterIndex mInitiatorSpiResource;
-        /** SPI of IKE SA responder */
-        private final IkeSecurityParameterIndex mResponderSpiResource;
-
-        private final byte[] mSkD;
-        private final byte[] mSkPi;
-        private final byte[] mSkPr;
-
-        private int mLocalRequestMessageId;
-        private int mRemoteRequestMessageId;
-
-        private DecodeResultPartial mCollectedReqFragments;
-        private DecodeResultPartial mCollectedRespFragments;
-
-        private byte[] mLastRecivedReqFirstPacket;
-        private List<byte[]> mLastSentRespAllPackets;
-
-        /** Package private */
-        IkeSaRecord(
-                IkeSecurityParameterIndex initSpi,
-                IkeSecurityParameterIndex respSpi,
-                boolean localInit,
-                byte[] nonceInit,
-                byte[] nonceResp,
-                byte[] skD,
-                byte[] skAi,
-                byte[] skAr,
-                byte[] skEi,
-                byte[] skEr,
-                byte[] skPi,
-                byte[] skPr,
-                LocalRequest futureRekeyEvent) {
-            super(localInit, nonceInit, nonceResp, skAi, skAr, skEi, skEr, futureRekeyEvent);
-
-            mInitiatorSpiResource = initSpi;
-            mResponderSpiResource = respSpi;
-
-            mSkD = skD;
-            mSkPi = skPi;
-            mSkPr = skPr;
-
-            mLocalRequestMessageId = 0;
-            mRemoteRequestMessageId = 0;
-
-            mCollectedReqFragments = null;
-            mCollectedRespFragments = null;
-
-            logKey("SK_d", skD);
-            logKey("SK_pi", skPi);
-            logKey("SK_pr", skPr);
-        }
-
-        /**
-         * Package private interface for IkeSessionStateMachien to construct an IkeSaRecord
-         * instance.
-         */
-        static IkeSaRecord makeFirstIkeSaRecord(
-                IkeMessage initRequest,
-                IkeMessage initResponse,
-                IkeSecurityParameterIndex initSpi,
-                IkeSecurityParameterIndex respSpi,
-                IkeMacPrf prf,
-                int integrityKeyLength,
-                int encryptionKeyLength,
-                LocalRequest futureRekeyEvent)
-                throws GeneralSecurityException {
-            return sSaRecordHelper.makeFirstIkeSaRecord(
-                    initRequest,
-                    initResponse,
-                    new IkeSaRecordConfig(
-                            initSpi,
-                            respSpi,
-                            prf,
-                            integrityKeyLength,
-                            encryptionKeyLength,
-                            true /*isLocalInit*/,
-                            futureRekeyEvent));
-        }
-
-        /** Package private */
-        static IkeSaRecord makeRekeyedIkeSaRecord(
-                IkeSaRecord oldSaRecord,
-                IkeMacPrf oldPrf,
-                IkeMessage rekeyRequest,
-                IkeMessage rekeyResponse,
-                IkeSecurityParameterIndex initSpi,
-                IkeSecurityParameterIndex respSpi,
-                IkeMacPrf prf,
-                int integrityKeyLength,
-                int encryptionKeyLength,
-                boolean isLocalInit,
-                LocalRequest futureRekeyEvent)
-                throws GeneralSecurityException {
-            return sSaRecordHelper.makeRekeyedIkeSaRecord(
-                    oldSaRecord,
-                    oldPrf,
-                    rekeyRequest,
-                    rekeyResponse,
-                    new IkeSaRecordConfig(
-                            initSpi,
-                            respSpi,
-                            prf,
-                            integrityKeyLength,
-                            encryptionKeyLength,
-                            isLocalInit,
-                            futureRekeyEvent));
-        }
-
-        private void logKey(String type, byte[] key) {
-            getIkeLog().d(TAG, type + ": " + getIkeLog().pii(key));
-        }
-
-        @Override
-        protected String getTag() {
-            return TAG;
-        }
-
-        /** Package private */
-        long getInitiatorSpi() {
-            return mInitiatorSpiResource.getSpi();
-        }
-
-        /** Package private */
-        long getResponderSpi() {
-            return mResponderSpiResource.getSpi();
-        }
-
-        /** Package private */
-        long getLocalSpi() {
-            return isLocalInit ? mInitiatorSpiResource.getSpi() : mResponderSpiResource.getSpi();
-        }
-
-        /** Package private */
-        long getRemoteSpi() {
-            return isLocalInit ? mResponderSpiResource.getSpi() : mInitiatorSpiResource.getSpi();
-        }
-
-        /** Package private */
-        byte[] getSkD() {
-            return mSkD;
-        }
-
-        /**
-         * Get the PRF key of IKE initiator for building an outbound Auth Payload.
-         *
-         * @return the PRF key in a byte array.
-         */
-        public byte[] getSkPi() {
-            return mSkPi;
-        }
-
-        /**
-         * Get the PRF key of IKE responder for validating an inbound Auth Payload.
-         *
-         * @return the PRF key in a byte array.
-         */
-        public byte[] getSkPr() {
-            return mSkPr;
-        }
-
-        /**
-         * Compare with a specific IkeSaRecord
-         *
-         * @param record IkeSaRecord to be compared.
-         * @return a negative integer if input IkeSaRecord contains lowest nonce; a positive integer
-         *     if this IkeSaRecord has lowest nonce; return zero if lowest nonces of two
-         *     IkeSaRecords match.
-         */
-        public int compareTo(IkeSaRecord record) {
-            // TODO: Implement it b/122924815.
-            return 1;
-        }
-
-        /**
-         * Get current message ID for the local requesting window.
-         *
-         * <p>Called for building an outbound request or for validating the message ID of an inbound
-         * response.
-         *
-         * @return the local request message ID.
-         */
-        public int getLocalRequestMessageId() {
-            return mLocalRequestMessageId;
-        }
-
-        /**
-         * Get current message ID for the remote requesting window.
-         *
-         * <p>Called for validating the message ID of an inbound request. If the message ID of the
-         * inbound request is smaller than the current remote message ID by one, it means the
-         * message is a retransmitted request.
-         *
-         * @return the remote request message ID
-         */
-        public int getRemoteRequestMessageId() {
-            return mRemoteRequestMessageId;
-        }
-
-        /**
-         * Increment the local request message ID by one.
-         *
-         * <p>It should be called when IKE library has received an authenticated and protected
-         * response with the correct local request message ID.
-         */
-        public void incrementLocalRequestMessageId() {
-            mLocalRequestMessageId++;
-        }
-
-        /**
-         * Increment the remote request message ID by one.
-         *
-         * <p>It should be called when IKE library has received an authenticated and protected
-         * request with the correct remote request message ID.
-         */
-        public void incrementRemoteRequestMessageId() {
-            mRemoteRequestMessageId++;
-        }
-
-        /** Return all collected IKE fragments that have been collected. */
-        public DecodeResultPartial getCollectedFragments(boolean isResp) {
-            return isResp ? mCollectedRespFragments : mCollectedReqFragments;
-        }
-
-        /**
-         * Update collected IKE fragments when receiving new IKE fragment.
-         *
-         * <p>TODO: b/140264067 Investigate if we need to support reassembling timeout. It is safe
-         * to do not support it because as an initiator, we will re-transmit the request anyway. As
-         * a responder, caching these fragments until getting a complete message won't affect
-         * anything.
-         */
-        public void updateCollectedFragments(
-                DecodeResultPartial updatedFragments, boolean isResp) {
-            if (isResp) {
-                mCollectedRespFragments = updatedFragments;
-            } else {
-                mCollectedReqFragments = updatedFragments;
-            }
-        }
-
-        /** Reset collected IKE fragemnts */
-        public void resetCollectedFragments(boolean isResp) {
-            updateCollectedFragments(null, isResp);
-        }
-
-        /** Update first packet of last received request. */
-        public void updateLastReceivedReqFirstPacket(byte[] reqPacket) {
-            mLastRecivedReqFirstPacket = reqPacket;
-        }
-
-        /** Update all packets of last sent response. */
-        public void updateLastSentRespAllPackets(List<byte[]> respPacketList) {
-            mLastSentRespAllPackets = respPacketList;
-        }
-
-        /** Returns if received IKE packet is the first packet of a re-transmistted request. */
-        public boolean isRetransmittedRequest(byte[] request) {
-            return Arrays.equals(mLastRecivedReqFirstPacket, request);
-        }
-
-        /** Get all encoded packets of last sent response. */
-        public List<byte[]> getLastSentRespAllPackets() {
-            return mLastSentRespAllPackets;
-        }
-
-        /** Release IKE SPI resource. */
-        @Override
-        public void close() {
-            super.close();
-            mInitiatorSpiResource.close();
-            mResponderSpiResource.close();
-        }
-    }
-
-    /** Package private class that groups parameters to construct an IkeSaRecord instance. */
-    @VisibleForTesting
-    static class IkeSaRecordConfig {
-        public final IkeSecurityParameterIndex initSpi;
-        public final IkeSecurityParameterIndex respSpi;
-        public final IkeMacPrf prf;
-        public final int integrityKeyLength;
-        public final int encryptionKeyLength;
-        public final boolean isLocalInit;
-        public final LocalRequest futureRekeyEvent;
-
-        IkeSaRecordConfig(
-                IkeSecurityParameterIndex initSpi,
-                IkeSecurityParameterIndex respSpi,
-                IkeMacPrf prf,
-                int integrityKeyLength,
-                int encryptionKeyLength,
-                boolean isLocalInit,
-                LocalRequest futureRekeyEvent) {
-            this.initSpi = initSpi;
-            this.respSpi = respSpi;
-            this.prf = prf;
-            this.integrityKeyLength = integrityKeyLength;
-            this.encryptionKeyLength = encryptionKeyLength;
-            this.isLocalInit = isLocalInit;
-            this.futureRekeyEvent = futureRekeyEvent;
-        }
-    }
-
-    /** ChildSaRecord represents an Child SA. */
-    public static class ChildSaRecord extends SaRecord implements Comparable<ChildSaRecord> {
-        private static final String TAG = "ChildSaRecord";
-
-        /** Locally generated SPI for receiving IPsec Packet. */
-        private final int mInboundSpi;
-        /** Remotely generated SPI for sending IPsec Packet. */
-        private final int mOutboundSpi;
-
-        /** IPsec Transform applied to traffic towards the host. */
-        private final IpSecTransform mInboundTransform;
-        /** IPsec Transform applied to traffic from the host. */
-        private final IpSecTransform mOutboundTransform;
-
-        /** Package private */
-        ChildSaRecord(
-                int inSpi,
-                int outSpi,
-                boolean localInit,
-                byte[] nonceInit,
-                byte[] nonceResp,
-                byte[] skAi,
-                byte[] skAr,
-                byte[] skEi,
-                byte[] skEr,
-                IpSecTransform inTransform,
-                IpSecTransform outTransform,
-                ChildLocalRequest futureRekeyEvent) {
-            super(localInit, nonceInit, nonceResp, skAi, skAr, skEi, skEr, futureRekeyEvent);
-
-            mInboundSpi = inSpi;
-            mOutboundSpi = outSpi;
-            mInboundTransform = inTransform;
-            mOutboundTransform = outTransform;
-        }
-
-        /**
-         * Package private interface for ChildSessionStateMachine to construct a ChildSaRecord
-         * instance.
-         */
-        static ChildSaRecord makeChildSaRecord(
-                Context context,
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                SecurityParameterIndex initSpi,
-                SecurityParameterIndex respSpi,
-                InetAddress localAddress,
-                InetAddress remoteAddress,
-                @Nullable UdpEncapsulationSocket udpEncapSocket,
-                IkeMacPrf prf,
-                @Nullable IkeMacIntegrity integrityAlgo,
-                IkeCipher encryptionAlgo,
-                byte[] skD,
-                boolean isTransport,
-                boolean isLocalInit,
-                ChildLocalRequest futureRekeyEvent)
-                throws GeneralSecurityException, ResourceUnavailableException,
-                        SpiUnavailableException, IOException {
-            return sSaRecordHelper.makeChildSaRecord(
-                    reqPayloads,
-                    respPayloads,
-                    new ChildSaRecordConfig(
-                            context,
-                            initSpi,
-                            respSpi,
-                            localAddress,
-                            remoteAddress,
-                            udpEncapSocket,
-                            prf,
-                            integrityAlgo,
-                            encryptionAlgo,
-                            skD,
-                            isTransport,
-                            isLocalInit,
-                            futureRekeyEvent));
-        }
-
-        @Override
-        protected String getTag() {
-            return TAG;
-        }
-
-        /** Package private */
-        int getLocalSpi() {
-            return mInboundSpi;
-        }
-
-        /** Package private */
-        int getRemoteSpi() {
-            return mOutboundSpi;
-        }
-
-        /** Package private */
-        IpSecTransform getInboundIpSecTransform() {
-            return mInboundTransform;
-        }
-
-        /** Package private */
-        IpSecTransform getOutboundIpSecTransform() {
-            return mOutboundTransform;
-        }
-
-        /**
-         * Compare with a specific ChildSaRecord
-         *
-         * @param record ChildSaRecord to be compared.
-         * @return a negative integer if input ChildSaRecord contains lowest nonce; a positive
-         *     integer if this ChildSaRecord has lowest nonce; return zero if lowest nonces of two
-         *     ChildSaRecord match.
-         */
-        public int compareTo(ChildSaRecord record) {
-            // TODO: Implement it b/122924815
-            return 1;
-        }
-
-        /** Release IpSecTransform pair. */
-        @Override
-        public void close() {
-            super.close();
-            mInboundTransform.close();
-            mOutboundTransform.close();
-        }
-    }
-
-    /**
-     * ISaRecordHelper provides a package private interface for constructing SaRecord.
-     *
-     * <p>ISaRecordHelper exists so that the interface is injectable for testing.
-     */
-    interface ISaRecordHelper {
-        /**
-         * Construct IkeSaRecord as results of IKE initial exchange.
-         *
-         * @param initRequest IKE_INIT request.
-         * @param initResponse IKE_INIT request.
-         * @param ikeSaRecordConfig that contains IKE SPI resources and negotiated algorithm
-         *     information for constructing an IkeSaRecord instance.
-         * @return ikeSaRecord for initial IKE SA.
-         * @throws GeneralSecurityException if the DH public key in the response is invalid.
-         */
-        IkeSaRecord makeFirstIkeSaRecord(
-                IkeMessage initRequest,
-                IkeMessage initResponse,
-                IkeSaRecordConfig ikeSaRecordConfig)
-                throws GeneralSecurityException;
-
-        /**
-         * Construct new IkeSaRecord when doing rekey.
-         *
-         * @param oldSaRecord old IKE SA
-         * @param oldPrf the PRF function from the old SA
-         * @param rekeyRequest Rekey IKE request.
-         * @param rekeyResponse Rekey IKE response.
-         * @param ikeSaRecordConfig that contains IKE SPI resources and negotiated algorithm
-         *     information for constructing an IkeSaRecord instance.
-         * @return ikeSaRecord for new IKE SA.
-         */
-        IkeSaRecord makeRekeyedIkeSaRecord(
-                IkeSaRecord oldSaRecord,
-                IkeMacPrf oldPrf,
-                IkeMessage rekeyRequest,
-                IkeMessage rekeyResponse,
-                IkeSaRecordConfig ikeSaRecordConfig)
-                throws GeneralSecurityException;
-
-        /**
-         * Construct ChildSaRecord and generate IpSecTransform pairs.
-         *
-         * @param reqPayloads payload list in request.
-         * @param respPayloads payload list in response.
-         * @param childSaRecordConfig the grouped parameters for constructing ChildSaRecord.
-         * @return new Child SA.
-         */
-        ChildSaRecord makeChildSaRecord(
-                List<IkePayload> reqPayloads,
-                List<IkePayload> respPayloads,
-                ChildSaRecordConfig childSaRecordConfig)
-                throws GeneralSecurityException, ResourceUnavailableException,
-                        SpiUnavailableException, IOException;
-    }
-
-    /**
-     * IIpSecTransformHelper provides a package private interface to construct {@link
-     * IpSecTransform}
-     *
-     * <p>IIpSecTransformHelper exists so that the interface is injectable for testing.
-     */
-    @VisibleForTesting
-    interface IIpSecTransformHelper {
-        /**
-         * Construct an instance of {@link IpSecTransform}
-         *
-         * @param context current context
-         * @param sourceAddress the source {@code InetAddress} of traffic on sockets of interfaces
-         *     that will use this transform
-         * @param udpEncapSocket the UDP-Encap socket that allows IpSec traffic to pass through a
-         *     NAT. Null if no NAT exists.
-         * @param spi a unique {@link IpSecManager.SecurityParameterIndex} to identify transformed
-         *     traffic
-         * @param integrityAlgo specifying the authentication algorithm to be applied.
-         * @param encryptionAlgo specifying the encryption algorithm or authenticated encryption
-         *     algorithm to be applied.
-         * @param integrityKey the negotiated authentication key to be applied.
-         * @param encryptionKey the negotiated encryption key to be applied.
-         * @param isTransport the flag indicates if a transport or a tunnel mode transform will be
-         *     built.
-         * @return an instance of {@link IpSecTransform}
-         * @throws ResourceUnavailableException indicating that too many transforms are active
-         * @throws SpiUnavailableException indicating the rare case where an SPI collides with an
-         *     existing transform
-         * @throws IOException indicating other errors
-         */
-        IpSecTransform makeIpSecTransform(
-                Context context,
-                InetAddress sourceAddress,
-                UdpEncapsulationSocket udpEncapSocket,
-                IpSecManager.SecurityParameterIndex spi,
-                @Nullable IkeMacIntegrity integrityAlgo,
-                IkeCipher encryptionAlgo,
-                byte[] integrityKey,
-                byte[] encryptionKey,
-                boolean isTransport)
-                throws ResourceUnavailableException, SpiUnavailableException, IOException;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCipher.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCipher.java
deleted file mode 100644
index 33a8b37..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCipher.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-import java.security.SecureRandom;
-
-import javax.crypto.Cipher;
-import javax.crypto.NoSuchPaddingException;
-
-/**
- * IkeCipher contains common information of normal and combined mode encryption algorithms.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public abstract class IkeCipher extends IkeCrypto {
-    private static final int KEY_LEN_3DES = 24;
-
-    private static final int IV_LEN_3DES = 8;
-    private static final int IV_LEN_AES_CBC = 16;
-    private static final int IV_LEN_AES_GCM = 8;
-
-    private final boolean mIsAead;
-    private final int mIvLen;
-
-    protected final Cipher mCipher;
-
-    protected IkeCipher(
-            int algorithmId,
-            int keyLength,
-            int ivLength,
-            String algorithmName,
-            boolean isAead,
-            Provider provider) {
-        super(algorithmId, keyLength, algorithmName);
-        mIvLen = ivLength;
-        mIsAead = isAead;
-
-        try {
-            mCipher = Cipher.getInstance(getAlgorithmName(), provider);
-        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
-            throw new IllegalArgumentException("Failed to construct " + getTypeString(), e);
-        }
-    }
-
-    /**
-     * Contruct an instance of IkeCipher.
-     *
-     * @param encryptionTransform the valid negotiated EncryptionTransform.
-     * @param provider the security provider.
-     * @return an instance of IkeCipher.
-     */
-    public static IkeCipher create(EncryptionTransform encryptionTransform, Provider provider) {
-        int algorithmId = encryptionTransform.id;
-
-        // Use specifiedKeyLength for algorithms with variable key length. Since
-        // specifiedKeyLength are encoded in bits, it needs to be converted to bytes.
-        switch (algorithmId) {
-            case SaProposal.ENCRYPTION_ALGORITHM_3DES:
-                return new IkeNormalModeCipher(
-                        algorithmId, KEY_LEN_3DES, IV_LEN_3DES, "DESede/CBC/NoPadding", provider);
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_CBC:
-                return new IkeNormalModeCipher(
-                        algorithmId,
-                        encryptionTransform.getSpecifiedKeyLength() / 8,
-                        IV_LEN_AES_CBC,
-                        "AES/CBC/NoPadding",
-                        provider);
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8:
-                // Fall through
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12:
-                // Fall through
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16:
-                // Fall through
-                return new IkeCombinedModeCipher(
-                        algorithmId,
-                        encryptionTransform.getSpecifiedKeyLength() / 8,
-                        IV_LEN_AES_GCM,
-                        "AES/GCM/NoPadding",
-                        provider);
-            default:
-                throw new IllegalArgumentException(
-                        "Unrecognized Encryption Algorithm ID: " + algorithmId);
-        }
-    }
-
-    /**
-     * Check if this encryption algorithm is a combined-mode/AEAD algorithm.
-     *
-     * @return if this encryption algorithm is a combined-mode/AEAD algorithm.
-     */
-    public boolean isAead() {
-        return mIsAead;
-    }
-
-    /**
-     * Get the block size (in bytes).
-     *
-     * @return the block size (in bytes).
-     */
-    public int getBlockSize() {
-        // Currently all supported encryption algorithms are block ciphers. So the return value will
-        // not be zero.
-        return mCipher.getBlockSize();
-    }
-
-    /**
-     * Get initialization vector (IV) length.
-     *
-     * @return the IV length.
-     */
-    public int getIvLen() {
-        return mIvLen;
-    }
-
-    /**
-     * Generate initialization vector (IV).
-     *
-     * @return the initialization vector (IV).
-     */
-    public byte[] generateIv() {
-        byte[] iv = new byte[getIvLen()];
-        new SecureRandom().nextBytes(iv);
-        return iv;
-    }
-
-    protected void validateKeyLenOrThrow(byte[] key) {
-        if (key.length != getKeyLength()) {
-            throw new IllegalArgumentException(
-                    "Expected key with length of : "
-                            + getKeyLength()
-                            + " Received key with length of : "
-                            + key.length);
-        }
-    }
-
-    /**
-     * Build IpSecAlgorithm from this IkeCipher.
-     *
-     * <p>Build IpSecAlgorithm that represents the same encryption algorithm with this IkeCipher
-     * instance with provided encryption key.
-     *
-     * @param key the encryption key in byte array.
-     * @return the IpSecAlgorithm.
-     */
-    public abstract IpSecAlgorithm buildIpSecAlgorithmWithKey(byte[] key);
-
-    /**
-     * Returns algorithm type as a String.
-     *
-     * @return the algorithm type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "Encryption Algorithm";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipher.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipher.java
deleted file mode 100644
index 4bb1d34..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipher.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Provider;
-import java.security.spec.AlgorithmParameterSpec;
-import java.util.Arrays;
-
-import javax.crypto.AEADBadTagException;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.GCMParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * IkeCipher represents a negotiated combined-mode cipher(AEAD) encryption algorithm.
- *
- * <p>Checksum mentioned in this class is also known as authentication tag or Integrity Checksum
- * Vector(ICV)
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- * @see <a href="https://tools.ietf.org/html/rfc5282">RFC 5282,Using Authenticated Encryption
- *     Algorithms with the Encrypted Payload of the Internet Key Exchange version 2 (IKEv2)
- *     Protocol</a>
- */
-public final class IkeCombinedModeCipher extends IkeCipher {
-    private static final int SALT_LEN_GCM = 4;
-
-    private final int mChecksumLen;
-    private final int mSaltLen;
-
-    /** Package private */
-    IkeCombinedModeCipher(
-            int algorithmId, int keyLength, int ivLength, String algorithmName, Provider provider) {
-        super(algorithmId, keyLength, ivLength, algorithmName, true /*isAead*/, provider);
-        switch (algorithmId) {
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8:
-                mSaltLen = SALT_LEN_GCM;
-                mChecksumLen = 8;
-                break;
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12:
-                mSaltLen = SALT_LEN_GCM;
-                mChecksumLen = 12;
-                break;
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16:
-                mSaltLen = SALT_LEN_GCM;
-                mChecksumLen = 16;
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "Unrecognized Encryption Algorithm ID: " + algorithmId);
-        }
-    }
-
-    private byte[] doCipherAction(
-            byte[] data, byte[] additionalAuthData, byte[] keyBytes, byte[] ivBytes, int opmode)
-            throws AEADBadTagException {
-        try {
-            // Provided key consists of encryption/decryption key plus 4-byte salt. Salt is used
-            // with IV to build the nonce.
-            ByteBuffer secretKeyAndSaltBuffer = ByteBuffer.wrap(keyBytes);
-            byte[] secretKeyBytes = new byte[keyBytes.length - mSaltLen];
-            byte[] salt = new byte[mSaltLen];
-            secretKeyAndSaltBuffer.get(secretKeyBytes);
-            secretKeyAndSaltBuffer.get(salt);
-
-            SecretKeySpec key = new SecretKeySpec(secretKeyBytes, getAlgorithmName());
-
-            ByteBuffer nonceBuffer = ByteBuffer.allocate(mSaltLen + ivBytes.length);
-            nonceBuffer.put(salt);
-            nonceBuffer.put(ivBytes);
-
-            mCipher.init(opmode, key, getParamSpec(nonceBuffer.array()));
-            mCipher.updateAAD(additionalAuthData);
-
-            ByteBuffer inputBuffer = ByteBuffer.wrap(data);
-
-            int outputLen = data.length;
-            if (opmode == Cipher.ENCRYPT_MODE) outputLen += mChecksumLen;
-            ByteBuffer outputBuffer = ByteBuffer.allocate(outputLen);
-
-            mCipher.doFinal(inputBuffer, outputBuffer);
-            return outputBuffer.array();
-        } catch (AEADBadTagException e) {
-            // Checksum failed in decryption
-            throw (AEADBadTagException) e;
-        } catch (InvalidKeyException
-                | InvalidAlgorithmParameterException
-                | IllegalBlockSizeException
-                | BadPaddingException
-                | ShortBufferException e) {
-            String errorMessage =
-                    Cipher.ENCRYPT_MODE == opmode
-                            ? "Failed to encrypt data: "
-                            : "Failed to decrypt data: ";
-            throw new IllegalArgumentException(errorMessage, e);
-        }
-    }
-
-    private AlgorithmParameterSpec getParamSpec(byte[] nonce) {
-        switch (getAlgorithmId()) {
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8:
-                // Fall through
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12:
-                // Fall through
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16:
-                return new GCMParameterSpec(mChecksumLen * 8, nonce);
-            default:
-                throw new IllegalArgumentException(
-                        "Unrecognized Encryption Algorithm ID: " + getAlgorithmId());
-        }
-    }
-
-    /**
-     * Encrypt padded data and calculate checksum for it.
-     *
-     * @param paddedData the padded data to encrypt.
-     * @param additionalAuthData additional data to authenticate (also known as associated data).
-     * @param keyBytes the encryption key.
-     * @param ivBytes the initialization vector (IV).
-     * @return the encrypted and padded data with checksum.
-     */
-    public byte[] encrypt(
-            byte[] paddedData, byte[] additionalAuthData, byte[] keyBytes, byte[] ivBytes) {
-        try {
-            return doCipherAction(
-                    paddedData, additionalAuthData, keyBytes, ivBytes, Cipher.ENCRYPT_MODE);
-        } catch (AEADBadTagException e) {
-            throw new IllegalArgumentException("Failed to encrypt data: ", e);
-        }
-    }
-
-    /**
-     * Authenticate and decrypt the padded data with checksum.
-     *
-     * @param paddedDataWithChecksum the padded data with checksum.
-     * @param additionalAuthData additional data to authenticate (also known as associated data).
-     * @param keyBytes the decryption key.
-     * @param ivBytes the initialization vector (IV).
-     * @return the decrypted and padded data
-     * @throws AEADBadTagException if authentication or decryption fails
-     */
-    public byte[] decrypt(
-            byte[] paddedDataWithChecksum,
-            byte[] additionalAuthData,
-            byte[] keyBytes,
-            byte[] ivBytes)
-            throws AEADBadTagException {
-
-        byte[] decryptPaddedDataAndAuthTag =
-                doCipherAction(
-                        paddedDataWithChecksum,
-                        additionalAuthData,
-                        keyBytes,
-                        ivBytes,
-                        Cipher.DECRYPT_MODE);
-
-        int decryptPaddedDataLen = decryptPaddedDataAndAuthTag.length - mChecksumLen;
-        return Arrays.copyOf(decryptPaddedDataAndAuthTag, decryptPaddedDataLen);
-    }
-
-    /**
-     * Gets key length of this algorithm (in bytes).
-     *
-     * @return the key length (in bytes).
-     */
-    @Override
-    public int getKeyLength() {
-        return super.getKeyLength() + mSaltLen;
-    }
-
-    /**
-     * Returns length of checksum.
-     *
-     * @return the length of checksum in bytes.
-     */
-    public int getChecksumLen() {
-        return mChecksumLen;
-    }
-
-    @Override
-    public IpSecAlgorithm buildIpSecAlgorithmWithKey(byte[] key) {
-        validateKeyLenOrThrow(key);
-        return new IpSecAlgorithm(IpSecAlgorithm.AUTH_CRYPT_AES_GCM, key, mChecksumLen * 8);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCrypto.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCrypto.java
deleted file mode 100644
index 65a676b..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCrypto.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-/**
- * IkeCrypto is an abstract class that represents common information for all negotiated
- * cryptographic algorithms that are used to build IKE SA and protect IKE message.
- */
-abstract class IkeCrypto {
-    private final int mAlgorithmId;
-    private final int mKeyLength;
-    private final String mAlgorithmName;
-
-    protected IkeCrypto(int algorithmId, int keyLength, String algorithmName) {
-        mAlgorithmId = algorithmId;
-        mKeyLength = keyLength;
-        mAlgorithmName = algorithmName;
-    }
-
-    protected int getAlgorithmId() {
-        return mAlgorithmId;
-    }
-
-    protected String getAlgorithmName() {
-        return mAlgorithmName;
-    }
-
-    /**
-     * Gets key length of this algorithm (in bytes).
-     *
-     * @return the key length (in bytes).
-     */
-    public int getKeyLength() {
-        return mKeyLength;
-    }
-
-    /**
-     * Returns algorithm type as a String.
-     *
-     * @return the algorithm type as a String.
-     */
-    public abstract String getTypeString();
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMac.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMac.java
deleted file mode 100644
index ee45cc9..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMac.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import com.android.internal.net.crypto.KeyGenerationUtils.ByteSigner;
-
-import java.nio.ByteBuffer;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.Provider;
-
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * IkeMac is an abstract class that represents common information for all negotiated algorithms that
- * generates Message Authentication Code (MAC), e.g. PRF and integrity algorithm.
- */
-abstract class IkeMac extends IkeCrypto implements ByteSigner {
-    // STOPSHIP: b/130190639 Catch unchecked exceptions, notify users and close the IKE session.
-    private final boolean mIsEncryptAlgo;
-    private final Mac mMac;
-    private final Cipher mCipher;
-
-    protected IkeMac(
-            int algorithmId,
-            int keyLength,
-            String algorithmName,
-            boolean isEncryptAlgo,
-            Provider provider) {
-        super(algorithmId, keyLength, algorithmName);
-
-        mIsEncryptAlgo = isEncryptAlgo;
-
-        try {
-            if (mIsEncryptAlgo) {
-                mMac = null;
-                mCipher = Cipher.getInstance(getAlgorithmName(), provider);
-            } else {
-                mMac = Mac.getInstance(getAlgorithmName(), provider);
-                mCipher = null;
-            }
-        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
-            throw new IllegalArgumentException("Failed to construct " + getTypeString(), e);
-        }
-    }
-
-    /**
-     * Signs the bytes to generate a Message Authentication Code (MAC).
-     *
-     * <p>Caller is responsible for providing valid key according to their use cases (e.g. PSK,
-     * SK_p, SK_d ...).
-     *
-     * @param keyBytes the key to sign data.
-     * @param dataToSign the data to be signed.
-     * @return the calculated MAC.
-     */
-    @Override
-    public byte[] signBytes(byte[] keyBytes, byte[] dataToSign) {
-        try {
-            SecretKeySpec secretKey = new SecretKeySpec(keyBytes, getAlgorithmName());
-
-            if (mIsEncryptAlgo) {
-                throw new UnsupportedOperationException(
-                        "Do not support " + getTypeString() + " using encryption algorithm.");
-            } else {
-                ByteBuffer inputBuffer = ByteBuffer.wrap(dataToSign);
-                mMac.init(secretKey);
-                mMac.update(inputBuffer);
-
-                return mMac.doFinal();
-            }
-        } catch (InvalidKeyException | IllegalStateException e) {
-            throw new IllegalArgumentException("Failed to generate MAC: ", e);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrity.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrity.java
deleted file mode 100644
index 8f2173f..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrity.java
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-
-import java.security.Provider;
-import java.util.Arrays;
-
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-
-/**
- * IkeMacIntegrity represents a negotiated integrity algorithm.
- *
- * <p>For integrity algorithms based on encryption algorithm, all operations will be done by a
- * {@link Cipher}. Otherwise, all operations will be done by a {@link Mac}.
- *
- * <p>@see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
- * Exchange Protocol Version 2 (IKEv2)</a>
- */
-public class IkeMacIntegrity extends IkeMac {
-    // STOPSHIP: b/130190639 Catch unchecked exceptions, notify users and close the IKE session.
-    private final int mChecksumLength;
-
-    private IkeMacIntegrity(
-            @SaProposal.IntegrityAlgorithm int algorithmId,
-            int keyLength,
-            String algorithmName,
-            boolean isEncryptAlgo,
-            Provider provider,
-            int checksumLength) {
-        super(algorithmId, keyLength, algorithmName, isEncryptAlgo, provider);
-        mChecksumLength = checksumLength;
-    }
-
-    /**
-     * Construct an instance of IkeMacIntegrity.
-     *
-     * @param integrityTransform the valid negotiated IntegrityTransform.
-     * @param provider the security provider.
-     * @return an instance of IkeMacIntegrity.
-     */
-    public static IkeMacIntegrity create(IntegrityTransform integrityTransform, Provider provider) {
-        int algorithmId = integrityTransform.id;
-
-        int keyLength = 0;
-        String algorithmName = "";
-        boolean isEncryptAlgo = false;
-        int checksumLength = 0;
-
-        switch (algorithmId) {
-            case SaProposal.INTEGRITY_ALGORITHM_NONE:
-                throw new IllegalArgumentException("Integrity algorithm is not found.");
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96:
-                keyLength = 20;
-                algorithmName = "HmacSHA1";
-                checksumLength = 12;
-                break;
-            case SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96:
-                keyLength = 16;
-                isEncryptAlgo = true;
-                checksumLength = 12;
-
-                // TODO:Set mAlgorithmName
-                throw new UnsupportedOperationException(
-                        "Do not support INTEGRITY_ALGORITHM_AES_XCBC_96.");
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128:
-                keyLength = 32;
-                algorithmName = "HmacSHA256";
-                checksumLength = 16;
-                break;
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192:
-                keyLength = 48;
-                algorithmName = "HmacSHA384";
-                checksumLength = 24;
-                break;
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256:
-                keyLength = 64;
-                algorithmName = "HmacSHA512";
-                checksumLength = 32;
-                break;
-            default:
-                throw new IllegalArgumentException(
-                        "Unrecognized Integrity Algorithm ID: " + algorithmId);
-        }
-
-        return new IkeMacIntegrity(
-                algorithmId, keyLength, algorithmName, isEncryptAlgo, provider, checksumLength);
-    }
-
-    /**
-     * Gets integrity checksum length (in bytes).
-     *
-     * <p>IKE defines a fixed truncation length for each integirty algorithm as its checksum length.
-     *
-     * @return the integrity checksum length (in bytes).
-     */
-    public int getChecksumLen() {
-        return mChecksumLength;
-    }
-
-    /**
-     * Signs the bytes to generate an integrity checksum.
-     *
-     * @param keyBytes the negotiated integrity key.
-     * @param dataToAuthenticate the data to authenticate.
-     * @return the integrity checksum.
-     */
-    public byte[] generateChecksum(byte[] keyBytes, byte[] dataToAuthenticate) {
-        if (getKeyLength() != keyBytes.length) {
-            throw new IllegalArgumentException(
-                    "Expected key length: "
-                            + getKeyLength()
-                            + " Received key length: "
-                            + keyBytes.length);
-        }
-
-        byte[] signedBytes = signBytes(keyBytes, dataToAuthenticate);
-        return Arrays.copyOfRange(signedBytes, 0, mChecksumLength);
-    }
-
-    /**
-     * Build IpSecAlgorithm from this IkeMacIntegrity.
-     *
-     * <p>Build IpSecAlgorithm that represents the same integrity algorithm with this
-     * IkeMacIntegrity instance with provided integrity key.
-     *
-     * @param key the integrity key in byte array.
-     * @return the IpSecAlgorithm.
-     */
-    public IpSecAlgorithm buildIpSecAlgorithmWithKey(byte[] key) {
-        if (key.length != getKeyLength()) {
-            throw new IllegalArgumentException(
-                    "Expected key with length of : "
-                            + getKeyLength()
-                            + " Received key with length of : "
-                            + key.length);
-        }
-
-        switch (getAlgorithmId()) {
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96:
-                return new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, key, mChecksumLength * 8);
-            case SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96:
-                // TODO:Consider supporting AES128_XCBC in IpSecTransform.
-                throw new IllegalArgumentException(
-                        "Do not support IpSecAlgorithm with AES128_XCBC.");
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128:
-                return new IpSecAlgorithm(
-                        IpSecAlgorithm.AUTH_HMAC_SHA256, key, mChecksumLength * 8);
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192:
-                return new IpSecAlgorithm(
-                        IpSecAlgorithm.AUTH_HMAC_SHA384, key, mChecksumLength * 8);
-            case SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256:
-                return new IpSecAlgorithm(
-                        IpSecAlgorithm.AUTH_HMAC_SHA512, key, mChecksumLength * 8);
-            default:
-                throw new IllegalArgumentException(
-                        "Unrecognized Integrity Algorithm ID: " + getAlgorithmId());
-        }
-    }
-
-    /**
-     * Returns algorithm type as a String.
-     *
-     * @return the algorithm type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "Integrity Algorithm.";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrf.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrf.java
deleted file mode 100644
index 1d81aae..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrf.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.crypto.KeyGenerationUtils;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-
-import java.nio.ByteBuffer;
-import java.security.Provider;
-
-import javax.crypto.Cipher;
-import javax.crypto.Mac;
-
-/**
- * IkeMacPrf represents a negotiated pseudorandom function.
- *
- * <p>Pseudorandom function is usually used for IKE SA authentication and generating keying
- * materials.
- *
- * <p>For pseudorandom functions based on integrity algorithms, all operations will be done by a
- * {@link Mac}. For pseudorandom functions based on encryption algorithms, all operations will be
- * done by a {@link Cipher}.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public class IkeMacPrf extends IkeMac {
-    // STOPSHIP: b/130190639 Catch unchecked exceptions, notify users and close the IKE session.
-
-    private IkeMacPrf(
-            @SaProposal.PseudorandomFunction int algorithmId,
-            int keyLength,
-            String algorithmName,
-            boolean isEncryptAlgo,
-            Provider provider) {
-        super(algorithmId, keyLength, algorithmName, isEncryptAlgo, provider);
-    }
-
-    /**
-     * Construct an instance of IkeMacPrf.
-     *
-     * @param prfTransform the valid negotiated PrfTransform.
-     * @param provider the security provider.
-     * @return an instance of IkeMacPrf.
-     */
-    public static IkeMacPrf create(PrfTransform prfTransform, Provider provider) {
-        int algorithmId = prfTransform.id;
-
-        int keyLength = 0;
-        String algorithmName = "";
-        boolean isEncryptAlgo = false;
-
-        switch (algorithmId) {
-            case SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1:
-                keyLength = 20;
-                algorithmName = "HmacSHA1";
-                break;
-            case SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC:
-                keyLength = 16;
-                isEncryptAlgo = true;
-
-                // TODO:Set mAlgorithmName
-                throw new UnsupportedOperationException(
-                        "Do not support PSEUDORANDOM_FUNCTION_AES128_XCBC.");
-            default:
-                throw new IllegalArgumentException("Unrecognized PRF ID: " + algorithmId);
-        }
-
-        return new IkeMacPrf(algorithmId, keyLength, algorithmName, isEncryptAlgo, provider);
-    }
-
-    /**
-     * Generates SKEYSEED based on the nonces and shared DH secret.
-     *
-     * @param nonceInit the IKE initiator nonce.
-     * @param nonceResp the IKE responder nonce.
-     * @param sharedDhKey the DH shared key.
-     * @return the byte array of SKEYSEED.
-     */
-    public byte[] generateSKeySeed(byte[] nonceInit, byte[] nonceResp, byte[] sharedDhKey) {
-        // TODO: If it is PSEUDORANDOM_FUNCTION_AES128_XCBC, only use first 8 bytes of each nonce.
-
-        ByteBuffer keyBuffer = ByteBuffer.allocate(nonceInit.length + nonceResp.length);
-        keyBuffer.put(nonceInit).put(nonceResp);
-
-        return signBytes(keyBuffer.array(), sharedDhKey);
-    }
-
-    /**
-     * Generates a rekey SKEYSEED based on the nonces and shared DH secret.
-     *
-     * @param skD the secret for deriving new keys
-     * @param nonceInit the IKE initiator nonce.
-     * @param nonceResp the IKE responder nonce.
-     * @param sharedDhKey the DH shared key.
-     * @return the byte array of SKEYSEED.
-     */
-    public byte[] generateRekeyedSKeySeed(
-            byte[] skD, byte[] nonceInit, byte[] nonceResp, byte[] sharedDhKey) {
-        // TODO: If it is PSEUDORANDOM_FUNCTION_AES128_XCBC, only use first 8 bytes of each nonce.
-
-        ByteBuffer dataToSign =
-                ByteBuffer.allocate(sharedDhKey.length + nonceInit.length + nonceResp.length);
-        dataToSign.put(sharedDhKey).put(nonceInit).put(nonceResp);
-
-        return signBytes(skD, dataToSign.array());
-    }
-
-    /**
-     * Derives keying materials from IKE/Child SA negotiation.
-     *
-     * <p>prf+(K, S) outputs a pseudorandom stream by using negotiated PRF iteratively. In this way
-     * it can generate long enough keying material containing all the keys for this IKE/Child SA.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.13">RFC 7296 Internet Key
-     *     Exchange Protocol Version 2 (IKEv2) 2.13. Generating Keying Material </a>
-     * @param keyBytes the key to sign data. SKEYSEED is used for generating KEYMAT for IKE SA. SK_d
-     *     is used for generating KEYMAT for Child SA.
-     * @param dataToSign the data to be signed.
-     * @param keyMaterialLen the length of keying materials.
-     * @return the byte array of keying materials
-     */
-    public byte[] generateKeyMat(byte[] keyBytes, byte[] dataToSign, int keyMaterialLen) {
-        return KeyGenerationUtils.prfPlus(this, keyBytes, dataToSign, keyMaterialLen);
-    }
-
-    /**
-     * Returns algorithm type as a String.
-     *
-     * @return the algorithm type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "Pseudorandom Function";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipher.java b/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipher.java
deleted file mode 100644
index e4904d4..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipher.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import java.nio.ByteBuffer;
-import java.security.InvalidAlgorithmParameterException;
-import java.security.InvalidKeyException;
-import java.security.Provider;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-/**
- * IkeCipher represents a negotiated normal mode encryption algorithm.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeNormalModeCipher extends IkeCipher {
-    /** Package private */
-    IkeNormalModeCipher(
-            int algorithmId, int keyLength, int ivLength, String algorithmName, Provider provider) {
-        super(algorithmId, keyLength, ivLength, algorithmName, false /*isAead*/, provider);
-    }
-
-    private byte[] doCipherAction(byte[] data, byte[] keyBytes, byte[] ivBytes, int opmode)
-            throws IllegalBlockSizeException {
-        if (getKeyLength() != keyBytes.length) {
-            throw new IllegalArgumentException(
-                    "Expected key length: "
-                            + getKeyLength()
-                            + " Received key length: "
-                            + keyBytes.length);
-        }
-        try {
-            SecretKeySpec key = new SecretKeySpec(keyBytes, getAlgorithmName());
-            IvParameterSpec iv = new IvParameterSpec(ivBytes);
-            mCipher.init(opmode, key, iv);
-
-            ByteBuffer inputBuffer = ByteBuffer.wrap(data);
-            ByteBuffer outputBuffer = ByteBuffer.allocate(data.length);
-
-            mCipher.doFinal(inputBuffer, outputBuffer);
-            return outputBuffer.array();
-        } catch (InvalidKeyException
-                | InvalidAlgorithmParameterException
-                | BadPaddingException
-                | ShortBufferException e) {
-            String errorMessage =
-                    Cipher.ENCRYPT_MODE == opmode
-                            ? "Failed to encrypt data: "
-                            : "Failed to decrypt data: ";
-            throw new IllegalArgumentException(errorMessage, e);
-        }
-    }
-
-    /**
-     * Encrypt padded data.
-     *
-     * @param paddedData the padded data to encrypt.
-     * @param keyBytes the encryption key.
-     * @param ivBytes the initialization vector (IV).
-     * @return the encrypted and padded data.
-     */
-    public byte[] encrypt(byte[] paddedData, byte[] keyBytes, byte[] ivBytes) {
-        try {
-            return doCipherAction(paddedData, keyBytes, ivBytes, Cipher.ENCRYPT_MODE);
-        } catch (IllegalBlockSizeException e) {
-            throw new IllegalArgumentException("Failed to encrypt data: ", e);
-        }
-    }
-
-    /**
-     * Decrypt the encrypted and padded data.
-     *
-     * @param encryptedData the encrypted and padded data.
-     * @param keyBytes the decryption key.
-     * @param ivBytes the initialization vector (IV).
-     * @return the decrypted and padded data.
-     * @throws IllegalBlockSizeException if the total encryptedData length is not a multiple of
-     *     block size.
-     */
-    public byte[] decrypt(byte[] encryptedData, byte[] keyBytes, byte[] ivBytes)
-            throws IllegalBlockSizeException {
-        return doCipherAction(encryptedData, keyBytes, ivBytes, Cipher.DECRYPT_MODE);
-    }
-
-    @Override
-    public IpSecAlgorithm buildIpSecAlgorithmWithKey(byte[] key) {
-        validateKeyLenOrThrow(key);
-
-        switch (getAlgorithmId()) {
-            case SaProposal.ENCRYPTION_ALGORITHM_3DES:
-                // TODO: Consider supporting 3DES in IpSecTransform.
-                throw new UnsupportedOperationException("Do not support 3Des encryption.");
-            case SaProposal.ENCRYPTION_ALGORITHM_AES_CBC:
-                return new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, key);
-            default:
-                throw new IllegalArgumentException(
-                        "Unrecognized Encryption Algorithm ID: " + getAlgorithmId());
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/AuthenticationFailedException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/AuthenticationFailedException.java
deleted file mode 100644
index e587364..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/AuthenticationFailedException.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown when IKE authentication fails.
- *
- * <p>Contains an exception message detailing the failure cause.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.21.2">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class AuthenticationFailedException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 0;
-
-    /**
-     * Construct a instance of AuthenticationFailedException.
-     *
-     * @param message the detail message.
-     */
-    public AuthenticationFailedException(String message) {
-        super(ERROR_TYPE_AUTHENTICATION_FAILED, message);
-    }
-
-    /**
-     * Construct a instance of AuthenticationFailedExcepion.
-     *
-     * @param cause the cause.
-     */
-    public AuthenticationFailedException(Throwable cause) {
-        super(ERROR_TYPE_AUTHENTICATION_FAILED, cause);
-    }
-
-    /**
-     * Construct a instance of AuthenticationFailedExcepion from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public AuthenticationFailedException(byte[] notifyData) {
-        super(ERROR_TYPE_AUTHENTICATION_FAILED, notifyData);
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidKeException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidKeException.java
deleted file mode 100644
index ae2330c..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidKeException.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown when the received KE payload in the request is different from accepted
- * Diffie-Hellman group.
- *
- * <p>Responder should include an INVALID_KE_PAYLOAD Notify payload in a response message for both
- * IKE INI exchange and other SA negotiation exchanges after IKE is setup..
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-1.3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class InvalidKeException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 2;
-
-    /**
-     * Construct an instance of InvalidKeException
-     *
-     * @param dhGroup the expected DH group
-     */
-    public InvalidKeException(int dhGroup) {
-        super(ERROR_TYPE_INVALID_KE_PAYLOAD, integerToByteArray(dhGroup, EXPECTED_ERROR_DATA_LEN));
-    }
-
-    /**
-     * Construct a instance of InvalidKeException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public InvalidKeException(byte[] notifyData) {
-        super(ERROR_TYPE_INVALID_KE_PAYLOAD, notifyData);
-    }
-
-    /**
-     * Return the expected DH Group included in this exception.
-     *
-     * @return the expected DH Group.
-     */
-    public int getDhGroup() {
-        return byteArrayToInteger(getErrorData());
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidMajorVersionException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidMajorVersionException.java
deleted file mode 100644
index dc0357e..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidMajorVersionException.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_MAJOR_VERSION;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown when major version is higher than 2.
- *
- * <p>Include INVALID_MAJOR_VERSION Notify payload in an unencrypted response message containing
- * version number 2.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.5">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class InvalidMajorVersionException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 1;
-
-    /**
-     * Construct a instance of InvalidMajorVersionException
-     *
-     * @param version the major version in received packet
-     */
-    public InvalidMajorVersionException(byte version) {
-        super(ERROR_TYPE_INVALID_MAJOR_VERSION, new byte[] {version});
-    }
-
-    /**
-     * Construct a instance of InvalidMajorVersionException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public InvalidMajorVersionException(byte[] notifyData) {
-        super(ERROR_TYPE_INVALID_MAJOR_VERSION, notifyData);
-    }
-
-    /**
-     * Return the major verion included in this exception.
-     *
-     * @return the major verion
-     */
-    public int getMajorVerion() {
-        return byteArrayToInteger(getErrorData());
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidMessageIdException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidMessageIdException.java
deleted file mode 100644
index 9c5cffa..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidMessageIdException.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_MESSAGE_ID;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown when the message ID is out of window size.
- *
- * <p>Notifications based on this exception contains the four-octet invalid message ID. It MUST only
- * ever be sent in an INFORMATIONAL request. Sending this notification is OPTIONAL, and
- * notifications of this type MUST be rate limited.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class InvalidMessageIdException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 4;
-
-    /**
-     * Construct a instance of InvalidMessageIdException
-     *
-     * @param messageId the invalid Message ID.
-     */
-    public InvalidMessageIdException(int messageId) {
-        super(
-                ERROR_TYPE_INVALID_MESSAGE_ID,
-                integerToByteArray(messageId, EXPECTED_ERROR_DATA_LEN));
-    }
-
-    /**
-     * Construct a instance of InvalidMessageIdException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public InvalidMessageIdException(byte[] notifyData) {
-        super(ERROR_TYPE_INVALID_MESSAGE_ID, notifyData);
-    }
-
-    /**
-     * Return the invalid message ID included in this exception.
-     *
-     * @return the message ID.
-     */
-    public int getMessageId() {
-        return byteArrayToInteger(getErrorData());
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidSyntaxException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidSyntaxException.java
deleted file mode 100644
index fd73f2f..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/InvalidSyntaxException.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown if any IKE message field is invalid.
- *
- * <p>Include INVALID_SYNTAX Notify payload in an encrypted response message if current message is
- * an encrypted request and cryptographic checksum is valid. Fatal error.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.10.1">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class InvalidSyntaxException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 0;
-
-    /**
-     * Construct an instance of InvalidSyntaxException.
-     *
-     * @param message the descriptive message.
-     */
-    public InvalidSyntaxException(String message) {
-        super(ERROR_TYPE_INVALID_SYNTAX, message);
-    }
-
-    /**
-     * Construct a instance of InvalidSyntaxException.
-     *
-     * @param cause the reason of exception.
-     */
-    public InvalidSyntaxException(Throwable cause) {
-        super(ERROR_TYPE_INVALID_SYNTAX, cause);
-    }
-
-    /**
-     * Construct a instance of InvalidSyntaxException.
-     *
-     * @param message the descriptive message.
-     * @param cause the reason of exception.
-     */
-    public InvalidSyntaxException(String message, Throwable cause) {
-        super(ERROR_TYPE_INVALID_SYNTAX, message, cause);
-    }
-
-    /**
-     * Construct a instance of InvalidSyntaxException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public InvalidSyntaxException(byte[] notifyData) {
-        super(ERROR_TYPE_INVALID_SYNTAX, notifyData);
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/NoValidProposalChosenException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/NoValidProposalChosenException.java
deleted file mode 100644
index 4514c65..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/NoValidProposalChosenException.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown if either none of SA proposals from SA initiator is acceptable or the
- * negotiated SA proposal from SA responder is invalid.
- *
- * <p>Include the NO_PROPOSAL_CHOSEN Notify payload in an encrypted response message if received
- * message is an encrypted request from SA initiator.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.7">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class NoValidProposalChosenException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 0;
-
-    /**
-     * Construct an instance of NoValidProposalChosenException.
-     *
-     * @param message the descriptive message.
-     */
-    public NoValidProposalChosenException(String message) {
-        super(ERROR_TYPE_NO_PROPOSAL_CHOSEN, message);
-    }
-
-    /**
-     * Construct an instance of NoValidProposalChosenException.
-     *
-     * @param message the descriptive message.
-     * @param cause the reason of exception.
-     */
-    public NoValidProposalChosenException(String message, Throwable cause) {
-        super(ERROR_TYPE_NO_PROPOSAL_CHOSEN, cause);
-    }
-
-    /**
-     * Construct a instance of NoValidProposalChosenException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public NoValidProposalChosenException(byte[] notifyData) {
-        super(ERROR_TYPE_NO_PROPOSAL_CHOSEN, notifyData);
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/TemporaryFailureException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/TemporaryFailureException.java
deleted file mode 100644
index 57ef8cd..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/TemporaryFailureException.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown when local node or remote peer receives a request that cannot be
- * completed due to a temporary condition such as a rekeying operation.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.7">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class TemporaryFailureException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 0;
-
-    /**
-     * Construct an instance of TemporaryFailureException.
-     *
-     * @param message the descriptive message.
-     */
-    public TemporaryFailureException(String message) {
-        super(ERROR_TYPE_TEMPORARY_FAILURE, message);
-    }
-
-    /**
-     * Construct a instance of TemporaryFailureException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public TemporaryFailureException(byte[] notifyData) {
-        super(ERROR_TYPE_TEMPORARY_FAILURE, notifyData);
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/TsUnacceptableException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/TsUnacceptableException.java
deleted file mode 100644
index ef1152a..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/TsUnacceptableException.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception is thrown if the remote sever proposed unacceptable TS.
- *
- * <p>If remote server is the exchange initiator, IKE library should respond with a TS_UNACCEPTABLE
- * Notify message. If the remote server is the exchange responder, IKE library should initiate a
- * Delete IKE exchange and close the IKE Session.
- */
-public final class TsUnacceptableException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 0;
-
-    /** Construct an instance of TsUnacceptableException. */
-    public TsUnacceptableException() {
-        super(ERROR_TYPE_TS_UNACCEPTABLE);
-    }
-
-    /**
-     * Construct a instance of TsUnacceptableException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public TsUnacceptableException(byte[] notifyData) {
-        super(ERROR_TYPE_TS_UNACCEPTABLE, notifyData);
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/UnrecognizedIkeProtocolException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/UnrecognizedIkeProtocolException.java
deleted file mode 100644
index 3d1d508..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/UnrecognizedIkeProtocolException.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-/**
- * This exception represents an unrecognized error notification in a received response.
- *
- * <p>When receiving an unrecognized error notification in a response, IKE Session MUST assume that
- * the corresponding request has failed entirely. If it is in a request, IKE Session MUST ignore it.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.10.1">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class UnrecognizedIkeProtocolException extends IkeProtocolException {
-    /** Constructs an instance of UnrecognizedIkeProtocolException */
-    public UnrecognizedIkeProtocolException(int errorType, byte[] notifyData) {
-        super(errorType, notifyData);
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        // Unrecognized error does not have an expected error data length. Any non-negative length
-        // is valid
-        return dataLen >= 0;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/exceptions/UnsupportedCriticalPayloadException.java b/src/java/com/android/internal/net/ipsec/ike/exceptions/UnsupportedCriticalPayloadException.java
deleted file mode 100644
index ab1f75e..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/exceptions/UnsupportedCriticalPayloadException.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * This exception is thrown when payload type is not supported and critical bit is set
- *
- * <p>Include UNSUPPORTED_CRITICAL_PAYLOAD Notify payloads in a response message. Each payload
- * contains only one payload type.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-2.5">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class UnsupportedCriticalPayloadException extends IkeProtocolException {
-    private static final int EXPECTED_ERROR_DATA_LEN = 1;
-
-    public final List<Integer> payloadTypeList;
-
-    /**
-     * Construct an instance of UnsupportedCriticalPayloadException.
-     *
-     * <p>To keep IkeProtocolException simpler, we only pass the first payload type to the
-     * superclass which can be retrieved by users.
-     *
-     * @param payloadList the list of all unsupported critical payload types.
-     */
-    public UnsupportedCriticalPayloadException(List<Integer> payloadList) {
-        super(
-                ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD,
-                integerToByteArray(payloadList.get(0), EXPECTED_ERROR_DATA_LEN));
-        payloadTypeList = payloadList;
-    }
-
-    /**
-     * Construct a instance of UnsupportedCriticalPayloadException from a notify payload.
-     *
-     * @param notifyData the notify data included in the payload.
-     */
-    public UnsupportedCriticalPayloadException(byte[] notifyData) {
-        super(ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, notifyData);
-        payloadTypeList = new ArrayList<>(1);
-        payloadTypeList.add(byteArrayToInteger(notifyData));
-    }
-
-    /**
-     * Return the all the unsupported critical payloads included in this exception.
-     *
-     * @return the unsupported critical payload list.
-     */
-    public List<Integer> getUnsupportedCriticalPayloadList() {
-        return payloadTypeList;
-    }
-
-    @Override
-    protected boolean isValidDataLength(int dataLen) {
-        return EXPECTED_ERROR_DATA_LEN == dataLen;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayload.java
deleted file mode 100644
index a4803af..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayload.java
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.annotation.StringDef;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.message.IkeAuthPayload.AuthMethod;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.ProviderException;
-import java.security.Signature;
-import java.security.SignatureException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-
-/**
- * IkeAuthDigitalSignPayload represents Authentication Payload using a specific or generic digital
- * signature authentication method.
- *
- * <p>If AUTH_METHOD_RSA_DIGITAL_SIGN is used, then the hash algorithm is SHA1. If
- * AUTH_METHOD_GENERIC_DIGITAL_SIGN is used, the signature algorihtm and hash algorithm are
- * extracted from authentication data.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.8">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- * @see <a href="https://tools.ietf.org/html/rfc7427">RFC 7427, Signature Authentication in the
- *     Internet Key Exchange Version 2 (IKEv2)</a>
- */
-public class IkeAuthDigitalSignPayload extends IkeAuthPayload {
-    private static final String KEY_ALGO_NAME = "RSA";
-
-    // Byte arrays of DER encoded identifier ASN.1 objects that indicates the algorithm used to
-    // generate the signature, extracted from
-    // <a href="https://tools.ietf.org/html/rfc7427#appendix-A"> RFC 7427. There is no need to
-    // understand the encoding process. They are just constants to indicate the algorithm type.
-    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA1 = {
-        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-        (byte) 0x05, (byte) 0x05, (byte) 0x00
-    };
-    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA2_256 = {
-        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-        (byte) 0x0b, (byte) 0x05, (byte) 0x00
-    };
-    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA2_384 = {
-        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-        (byte) 0x0c, (byte) 0x05, (byte) 0x00
-    };
-    private static final byte[] PKI_ALGO_ID_DER_BYTES_RSA_SHA2_512 = {
-        (byte) 0x30, (byte) 0x0d, (byte) 0x06, (byte) 0x09,
-        (byte) 0x2a, (byte) 0x86, (byte) 0x48, (byte) 0x86,
-        (byte) 0xf7, (byte) 0x0d, (byte) 0x01, (byte) 0x01,
-        (byte) 0x0d, (byte) 0x05, (byte) 0x00
-    };
-
-    // Length of ASN.1 object length field.
-    private static final int SIGNATURE_ALGO_ASN1_LEN_LEN = 1;
-
-    // Currently we only support RSA for signature algorithm.
-    @Retention(RetentionPolicy.SOURCE)
-    @StringDef({
-        SIGNATURE_ALGO_RSA_SHA1,
-        SIGNATURE_ALGO_RSA_SHA2_256,
-        SIGNATURE_ALGO_RSA_SHA2_384,
-        SIGNATURE_ALGO_RSA_SHA2_512
-    })
-    @VisibleForTesting
-    @interface SignatureAlgo {}
-
-    @VisibleForTesting static final String SIGNATURE_ALGO_RSA_SHA1 = "SHA1withRSA";
-    @VisibleForTesting static final String SIGNATURE_ALGO_RSA_SHA2_256 = "SHA256withRSA";
-    @VisibleForTesting static final String SIGNATURE_ALGO_RSA_SHA2_384 = "SHA384withRSA";
-    @VisibleForTesting static final String SIGNATURE_ALGO_RSA_SHA2_512 = "SHA512withRSA";
-
-    public final String signatureAlgoAndHash;
-    public final byte[] signature;
-
-    protected IkeAuthDigitalSignPayload(
-            boolean critical, @AuthMethod int authMethod, byte[] authData)
-            throws IkeProtocolException {
-        super(critical, authMethod);
-        switch (authMethod) {
-            case AUTH_METHOD_RSA_DIGITAL_SIGN:
-                signatureAlgoAndHash = SIGNATURE_ALGO_RSA_SHA1;
-                signature = authData;
-                break;
-            case AUTH_METHOD_GENERIC_DIGITAL_SIGN:
-                ByteBuffer inputBuffer = ByteBuffer.wrap(authData);
-
-                // Get signature algorithm.
-                int signAlgoLen = Byte.toUnsignedInt(inputBuffer.get());
-                byte[] signAlgoBytes = new byte[signAlgoLen];
-                inputBuffer.get(signAlgoBytes);
-                signatureAlgoAndHash = bytesToJavaStandardSignAlgoName(signAlgoBytes);
-
-                // Get signature.
-                signature = new byte[authData.length - SIGNATURE_ALGO_ASN1_LEN_LEN - signAlgoLen];
-                inputBuffer.get(signature);
-                break;
-            default:
-                throw new IllegalArgumentException("Unrecognized authentication method.");
-        }
-    }
-
-    /**
-     * Construct IkeAuthDigitalSignPayload for an outbound IKE packet.
-     *
-     * <p>Since IKE library is always a client, outbound IkeAuthDigitalSignPayload always signs IKE
-     * initiator's SignedOctets, which is concatenation of the IKE_INIT request message, the Nonce
-     * of IKE responder and the signed ID-Initiator payload body.
-     *
-     * <p>Caller MUST validate that the signatureAlgoName is supported by IKE library.
-     *
-     * @param signatureAlgoName the name of the algorithm requested. See the Signature section in
-     *     the <a href= "{@docRoot}/../technotes/guides/security/StandardNames.html#Signature"> Java
-     *     Cryptography Architecture Standard Algorithm Name Documentation</a> for information about
-     *     standard algorithm names.
-     * @param privateKey the private key of the identity whose signature is going to be generated.
-     * @param ikeInitBytes IKE_INIT request for calculating IKE initiator's SignedOctets.
-     * @param nonce nonce of IKE responder for calculating IKE initiator's SignedOctets.
-     * @param idPayloadBodyBytes ID-Initiator payload body for calculating IKE initiator's
-     *     SignedOctets.
-     * @param ikePrf the negotiated PRF.
-     * @param prfKeyBytes the negotiated PRF initiator key.
-     */
-    public IkeAuthDigitalSignPayload(
-            String signatureAlgoName,
-            PrivateKey privateKey,
-            byte[] ikeInitBytes,
-            byte[] nonce,
-            byte[] idPayloadBodyBytes,
-            IkeMacPrf ikePrf,
-            byte[] prfKeyBytes) {
-        super(false, IkeAuthPayload.AUTH_METHOD_GENERIC_DIGITAL_SIGN);
-        byte[] dataToSignBytes =
-                getSignedOctets(ikeInitBytes, nonce, idPayloadBodyBytes, ikePrf, prfKeyBytes);
-
-        try {
-            Signature signGen =
-                    Signature.getInstance(signatureAlgoName, IkeMessage.getSecurityProvider());
-            signGen.initSign(privateKey);
-            signGen.update(dataToSignBytes);
-
-            signature = signGen.sign();
-            signatureAlgoAndHash = signatureAlgoName;
-        } catch (SignatureException | InvalidKeyException e) {
-            throw new IllegalArgumentException("Signature generation failed", e);
-        } catch (NoSuchAlgorithmException e) {
-            throw new ProviderException(
-                    "Security Provider does not support "
-                            + KEY_ALGO_NAME
-                            + " or "
-                            + signatureAlgoName);
-        }
-    }
-
-    private String bytesToJavaStandardSignAlgoName(byte[] signAlgoBytes)
-            throws AuthenticationFailedException {
-        if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA1, signAlgoBytes)) {
-            return SIGNATURE_ALGO_RSA_SHA1;
-        } else if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA2_256, signAlgoBytes)) {
-            return SIGNATURE_ALGO_RSA_SHA2_256;
-        } else if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA2_384, signAlgoBytes)) {
-            return SIGNATURE_ALGO_RSA_SHA2_384;
-        } else if (Arrays.equals(PKI_ALGO_ID_DER_BYTES_RSA_SHA2_512, signAlgoBytes)) {
-            return SIGNATURE_ALGO_RSA_SHA2_512;
-        } else {
-            throw new AuthenticationFailedException(
-                    "Unrecognized ASN.1 objects for Signature algorithm and Hash");
-        }
-    }
-
-    /**
-     * Verify received signature in an inbound IKE packet.
-     *
-     * <p>Since IKE library is always a client, inbound IkeAuthDigitalSignPayload always signs IKE
-     * responder's SignedOctets, which is concatenation of the IKE_INIT response message, the Nonce
-     * of IKE initiator and the signed ID-Responder payload body.
-     *
-     * @param certificate received end certificate to verify the signature.
-     * @param ikeInitBytes IKE_INIT response for calculating IKE responder's SignedOctets.
-     * @param nonce nonce of IKE initiator for calculating IKE responder's SignedOctets.
-     * @param idPayloadBodyBytes ID-Responder payload body for calculating IKE responder's
-     *     SignedOctets.
-     * @param ikePrf the negotiated PRF.
-     * @param prfKeyBytes the negotiated PRF responder key.
-     * @throws AuthenticationFailedException if received signature verification failed.
-     */
-    public void verifyInboundSignature(
-            X509Certificate certificate,
-            byte[] ikeInitBytes,
-            byte[] nonce,
-            byte[] idPayloadBodyBytes,
-            IkeMacPrf ikePrf,
-            byte[] prfKeyBytes)
-            throws AuthenticationFailedException {
-        byte[] dataToSignBytes =
-                getSignedOctets(ikeInitBytes, nonce, idPayloadBodyBytes, ikePrf, prfKeyBytes);
-
-        try {
-            Signature signValidator =
-                    Signature.getInstance(signatureAlgoAndHash, IkeMessage.getSecurityProvider());
-            signValidator.initVerify(certificate);
-            signValidator.update(dataToSignBytes);
-
-            if (!signValidator.verify(signature)) {
-                throw new AuthenticationFailedException("Signature verification failed.");
-            }
-        } catch (SignatureException | InvalidKeyException e) {
-            throw new AuthenticationFailedException(e);
-        } catch (NoSuchAlgorithmException e) {
-            throw new ProviderException(
-                    "Security Provider does not support " + signatureAlgoAndHash);
-        }
-    }
-
-    // TODO: Add methods for generating signature.
-
-    @Override
-    protected void encodeAuthDataToByteBuffer(ByteBuffer byteBuffer) {
-        // TODO: Implement it.
-        throw new UnsupportedOperationException(
-                "It is not supported to encode a " + getTypeString());
-    }
-
-    @Override
-    protected int getAuthDataLength() {
-        // TODO: Implement it.
-        throw new UnsupportedOperationException(
-                "It is not supported to get payload length of " + getTypeString());
-    }
-
-    @Override
-    public String getTypeString() {
-        return "Auth(Digital Sign)";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayload.java
deleted file mode 100644
index 9227dda..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayload.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
-import java.security.KeyStore;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
-import java.security.cert.CertificateException;
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509CRL;
-import java.security.cert.X509Certificate;
-import java.util.List;
-import java.util.Set;
-
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.TrustManagerFactory;
-import javax.net.ssl.X509TrustManager;
-
-/**
- * IkeCertPayload is an abstract class that represents the common information for all Certificate
- * Payload carrying different types of certifciate-related data and static methods related to
- * certificate validation.
- *
- * <p>Certificate Payload is only sent in IKE_AUTH exchange.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.6">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public abstract class IkeCertPayload extends IkePayload {
-    // Length of certificate encoding type field in octets.
-    private static final int CERT_ENCODING_LEN = 1;
-
-    private static final String KEY_STORE_TYPE_PKCS12 = "PKCS12";
-    private static final String CERT_PATH_ALGO_PKIX = "PKIX";
-    private static final String CERT_AUTH_TYPE_RSA = "RSA";
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        CERTIFICATE_ENCODING_X509_CERT_SIGNATURE,
-        CERTIFICATE_ENCODING_CRL,
-        CERTIFICATE_ENCODING_X509_CERT_HASH_URL,
-    })
-    public @interface CertificateEncoding {}
-
-    public static final int CERTIFICATE_ENCODING_X509_CERT_SIGNATURE = 4;
-    public static final int CERTIFICATE_ENCODING_CRL = 7;
-    public static final int CERTIFICATE_ENCODING_X509_CERT_HASH_URL = 12;
-
-    @CertificateEncoding public final int certEncodingType;
-
-    protected IkeCertPayload(@CertificateEncoding int encodingType) {
-        this(false /*critical*/, encodingType);
-    }
-
-    protected IkeCertPayload(boolean critical, @CertificateEncoding int encodingType) {
-        super(PAYLOAD_TYPE_CERT, critical);
-        certEncodingType = encodingType;
-    }
-
-    protected static IkeCertPayload getIkeCertPayload(boolean critical, byte[] payloadBody)
-            throws IkeProtocolException {
-        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
-
-        int certEncodingType = Byte.toUnsignedInt(inputBuffer.get());
-        byte[] certData = new byte[payloadBody.length - CERT_ENCODING_LEN];
-        inputBuffer.get(certData);
-        switch (certEncodingType) {
-            case CERTIFICATE_ENCODING_X509_CERT_SIGNATURE:
-                return new IkeCertX509CertPayload(critical, certData);
-                // TODO: Support decoding CRL and "Hash and URL".
-            case CERTIFICATE_ENCODING_CRL:
-                throw new AuthenticationFailedException(
-                        "CERTIFICATE_ENCODING_CRL decoding is unsupported.");
-            case CERTIFICATE_ENCODING_X509_CERT_HASH_URL:
-                throw new AuthenticationFailedException(
-                        "CERTIFICATE_ENCODING_X509_CERT_HASH_URL decoding is unsupported");
-            default:
-                throw new AuthenticationFailedException("Unrecognized certificate encoding type.");
-        }
-    }
-
-    /**
-     * Validate an end certificate against the received chain and trust anchors.
-     *
-     * <p>Validation is done by checking if there is a valid certificate path from end certificate
-     * to provided trust anchors.
-     *
-     * <p>TrustManager implementation used in this method MUST conforms RFC 4158 and RFC 5280. As
-     * indicated in RFC 4158, Key Identifiers(KIDs) are not required to match during certification
-     * path validation and cannot be used to eliminate certificates.
-     *
-     * <p>Validation will fail if any certficate in the certificate chain is using RSA public key
-     * whose RSA modulus is smaller than 1024 bits.
-     *
-     * @param endCert the end certificate that will be used to verify AUTH payload
-     * @param certList all the received certificates (include the end certificate)
-     * @param crlList the certificate revocation lists
-     * @param trustAnchorSet the certificate authority set to validate the end certificate
-     * @throws AuthenticationFailedException if there is no valid certificate path
-     */
-    public static void validateCertificates(
-            X509Certificate endCert,
-            List<X509Certificate> certList,
-            @Nullable List<X509CRL> crlList,
-            Set<TrustAnchor> trustAnchorSet)
-            throws AuthenticationFailedException {
-        try {
-            // TODO: b/122676944 Support CRL checking
-
-            // Create a new keyStore with all trusted anchors
-            KeyStore keyStore =
-                    KeyStore.getInstance(KEY_STORE_TYPE_PKCS12, IkeMessage.getSecurityProvider());
-            keyStore.load(null);
-            for (TrustAnchor t : trustAnchorSet) {
-                X509Certificate trustedCert = t.getTrustedCert();
-                String alias =
-                        trustedCert.getSubjectX500Principal().getName() + trustedCert.hashCode();
-                keyStore.setCertificateEntry(alias, trustedCert);
-            }
-
-            // Build X509TrustManager with all keystore
-            TrustManagerFactory tmFactory =
-                    TrustManagerFactory.getInstance(
-                            CERT_PATH_ALGO_PKIX, IkeMessage.getTrustManagerProvider());
-            tmFactory.init(keyStore);
-
-            X509TrustManager trustManager = null;
-            for (TrustManager tm : tmFactory.getTrustManagers()) {
-                if (tm instanceof X509TrustManager) {
-                    trustManager = (X509TrustManager) tm;
-                }
-            }
-            if (trustManager == null) {
-                throw new ProviderException(
-                        "X509TrustManager is not supported by "
-                                + IkeMessage.getTrustManagerProvider().getName());
-            }
-
-            // Build and validate certificate path
-            trustManager.checkServerTrusted(
-                    certList.toArray(new X509Certificate[certList.size()]), CERT_AUTH_TYPE_RSA);
-        } catch (NoSuchAlgorithmException e) {
-            throw new ProviderException("Algorithm is not supported by the provider", e);
-        } catch (IOException | KeyStoreException e) {
-            throw new IllegalStateException(e);
-        } catch (CertificateException e) {
-            throw new AuthenticationFailedException(e);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java
deleted file mode 100644
index ddd1b3e..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayload.java
+++ /dev/null
@@ -1,767 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.annotation.IntDef;
-import android.net.LinkAddress;
-import android.net.ipsec.ike.IkeManager;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-/**
- * This class represents Configuration payload.
- *
- * <p>Configuration payload is used to exchange configuration information between IKE peers.
- *
- * <p>Configuration type should be consistent with the IKE message direction (e.g. a request Config
- * Payload should be in a request IKE message). IKE library will ignore Config Payload with
- * inconsistent type or with unrecognized type.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.6">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeConfigPayload extends IkePayload {
-    private static final int CONFIG_HEADER_RESERVED_LEN = 3;
-    private static final int CONFIG_HEADER_LEN = 4;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        CONFIG_ATTR_INTERNAL_IP4_ADDRESS,
-        CONFIG_ATTR_INTERNAL_IP4_NETMASK,
-        CONFIG_ATTR_INTERNAL_IP4_DNS,
-        CONFIG_ATTR_INTERNAL_IP4_DHCP,
-        CONFIG_ATTR_APPLICATION_VERSION,
-        CONFIG_ATTR_INTERNAL_IP6_ADDRESS,
-        CONFIG_ATTR_INTERNAL_IP6_DNS,
-        CONFIG_ATTR_INTERNAL_IP4_SUBNET,
-        CONFIG_ATTR_SUPPORTED_ATTRIBUTES,
-        CONFIG_ATTR_INTERNAL_IP6_SUBNET
-    })
-    public @interface ConfigAttr {}
-
-    public static final int CONFIG_ATTR_INTERNAL_IP4_ADDRESS = 1;
-    public static final int CONFIG_ATTR_INTERNAL_IP4_NETMASK = 2;
-    public static final int CONFIG_ATTR_INTERNAL_IP4_DNS = 3;
-    public static final int CONFIG_ATTR_INTERNAL_IP4_DHCP = 6;
-    public static final int CONFIG_ATTR_APPLICATION_VERSION = 7;
-    public static final int CONFIG_ATTR_INTERNAL_IP6_ADDRESS = 8;
-    public static final int CONFIG_ATTR_INTERNAL_IP6_DNS = 10;
-    public static final int CONFIG_ATTR_INTERNAL_IP4_SUBNET = 13;
-    public static final int CONFIG_ATTR_SUPPORTED_ATTRIBUTES = 14;
-    public static final int CONFIG_ATTR_INTERNAL_IP6_SUBNET = 15;
-
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({CONFIG_TYPE_REQUEST, CONFIG_TYPE_REPLY})
-    public @interface ConfigType {}
-
-    // We don't support CONFIG_TYPE_SET and CONFIG_TYPE_ACK
-    public static final int CONFIG_TYPE_REQUEST = 1;
-    public static final int CONFIG_TYPE_REPLY = 2;
-
-    @ConfigType public final int configType;
-    public final List<ConfigAttribute> recognizedAttributeList;
-
-    /** Build an IkeConfigPayload from a decoded inbound IKE packet. */
-    IkeConfigPayload(boolean critical, byte[] payloadBody) throws InvalidSyntaxException {
-        super(PAYLOAD_TYPE_CP, critical);
-
-        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
-        configType = Byte.toUnsignedInt(inputBuffer.get());
-        inputBuffer.get(new byte[CONFIG_HEADER_RESERVED_LEN]);
-
-        recognizedAttributeList = ConfigAttribute.decodeAttributeFrom(inputBuffer);
-
-        // For an inbound Config Payload, IKE library is only able to handle a Config Reply or IKE
-        // Session attribute requests in a Config Request. For interoperability, netmask validation
-        // will be skipped for Config(Request) and config payloads with unsupported config types.
-        if (configType == CONFIG_TYPE_REPLY) {
-            validateNetmaskInReply();
-        }
-    }
-
-    /** Build an IkeConfigPayload instance for an outbound IKE packet. */
-    public IkeConfigPayload(boolean isReply, List<ConfigAttribute> attributeList) {
-        super(PAYLOAD_TYPE_CP, false);
-        this.configType = isReply ? CONFIG_TYPE_REPLY : CONFIG_TYPE_REQUEST;
-        this.recognizedAttributeList = attributeList;
-    }
-
-    private void validateNetmaskInReply() throws InvalidSyntaxException {
-        boolean hasIpv4Address = false;
-        int numNetmask = 0;
-
-        for (ConfigAttribute attr : recognizedAttributeList) {
-            if (attr.isEmptyValue()) {
-                IkeManager.getIkeLog()
-                        .d(
-                                "IkeConfigPayload",
-                                "Found empty attribute in a Config Payload reply "
-                                        + attr.attributeType);
-            }
-            switch (attr.attributeType) {
-                case CONFIG_ATTR_INTERNAL_IP4_ADDRESS:
-                    if (!attr.isEmptyValue()) hasIpv4Address = true;
-                    break;
-                case CONFIG_ATTR_INTERNAL_IP4_NETMASK:
-                    if (!attr.isEmptyValue()) numNetmask++;
-                    break;
-                default:
-                    continue;
-            }
-        }
-
-        if (!hasIpv4Address && numNetmask > 0) {
-            throw new InvalidSyntaxException(
-                    "Found INTERNAL_IP4_NETMASK attribute but no INTERNAL_IP4_ADDRESS attribute");
-        }
-
-        if (numNetmask > 1) {
-            throw new InvalidSyntaxException("Found more than one INTERNAL_IP4_NETMASK");
-        }
-    }
-
-    // TODO: Create ConfigAttribute subclasses for each attribute.
-
-    /** This class represents common information of all Configuration Attributes. */
-    public abstract static class ConfigAttribute {
-        private static final int ATTRIBUTE_TYPE_MASK = 0x7fff;
-
-        private static final int ATTRIBUTE_HEADER_LEN = 4;
-        private static final int IPV4_PREFIX_LEN_MAX = 32;
-
-        protected static final int VALUE_LEN_NOT_INCLUDED = 0;
-
-        protected static final int IPV4_ADDRESS_LEN = 4;
-        protected static final int IPV6_ADDRESS_LEN = 16;
-        protected static final int PREFIX_LEN_LEN = 1;
-
-        public final int attributeType;
-
-        protected ConfigAttribute(int attributeType) {
-            this.attributeType = attributeType;
-        }
-
-        protected ConfigAttribute(int attributeType, int len) throws InvalidSyntaxException {
-            this(attributeType);
-
-            if (!isLengthValid(len)) {
-                throw new InvalidSyntaxException("Invalid configuration length");
-            }
-        }
-
-        /**
-         * Package private method to decode ConfigAttribute list from an inbound packet
-         *
-         * <p>NegativeArraySizeException and BufferUnderflowException will be caught in {@link
-         * IkeMessage}
-         */
-        static List<ConfigAttribute> decodeAttributeFrom(ByteBuffer inputBuffer)
-                throws InvalidSyntaxException {
-            List<ConfigAttribute> configList = new LinkedList();
-
-            while (inputBuffer.hasRemaining()) {
-                int attributeType = Short.toUnsignedInt(inputBuffer.getShort());
-                int length = Short.toUnsignedInt(inputBuffer.getShort());
-                byte[] value = new byte[length];
-                inputBuffer.get(value);
-
-                switch (attributeType) {
-                    case CONFIG_ATTR_INTERNAL_IP4_ADDRESS:
-                        configList.add(new ConfigAttributeIpv4Address(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP4_NETMASK:
-                        configList.add(new ConfigAttributeIpv4Netmask(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP4_DNS:
-                        configList.add(new ConfigAttributeIpv4Dns(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP4_DHCP:
-                        configList.add(new ConfigAttributeIpv4Dhcp(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP6_ADDRESS:
-                        configList.add(new ConfigAttributeIpv6Address(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP6_DNS:
-                        configList.add(new ConfigAttributeIpv6Dns(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP4_SUBNET:
-                        configList.add(new ConfigAttributeIpv4Subnet(value));
-                        break;
-                    case CONFIG_ATTR_INTERNAL_IP6_SUBNET:
-                        configList.add(new ConfigAttributeIpv6Subnet(value));
-                        break;
-                    default:
-                        IkeManager.getIkeLog()
-                                .i(
-                                        "IkeConfigPayload",
-                                        "Unrecognized attribute type: " + attributeType);
-                }
-
-                // TODO: Support App version and supported attribute list
-            }
-
-            return configList;
-        }
-
-        /** Encode attribute to ByteBuffer. */
-        public void encodeAttributeToByteBuffer(ByteBuffer buffer) {
-            buffer.putShort((short) (attributeType & ATTRIBUTE_TYPE_MASK))
-                    .putShort((short) getValueLength());
-            encodeValueToByteBuffer(buffer);
-        }
-
-        /** Get attribute length. */
-        public int getAttributeLen() {
-            return ATTRIBUTE_HEADER_LEN + getValueLength();
-        }
-
-        /** Returns if this attribute value is empty. */
-        public boolean isEmptyValue() {
-            return getValueLength() == VALUE_LEN_NOT_INCLUDED;
-        }
-
-        protected static int netmaskToPrefixLen(Inet4Address address) {
-            byte[] bytes = address.getAddress();
-
-            int netmaskInt = ByteBuffer.wrap(bytes).getInt();
-            int leftmostBitMask = 0x80000000;
-
-            int prefixLen = 0;
-            while ((netmaskInt & leftmostBitMask) == leftmostBitMask) {
-                prefixLen++;
-                netmaskInt <<= 1;
-            }
-
-            if (netmaskInt != 0) {
-                throw new IllegalArgumentException("Invalid netmask address");
-            }
-
-            return prefixLen;
-        }
-
-        protected static byte[] prefixToNetmaskBytes(int prefixLen) {
-            if (prefixLen > IPV4_PREFIX_LEN_MAX || prefixLen < 0) {
-                throw new IllegalArgumentException("Invalid IPv4 prefix length.");
-            }
-
-            int netmaskInt = (int) (((long) 0xffffffff) << (IPV4_PREFIX_LEN_MAX - prefixLen));
-            byte[] netmask = new byte[IPV4_ADDRESS_LEN];
-
-            ByteBuffer buffer = ByteBuffer.allocate(IPV4_ADDRESS_LEN);
-            buffer.putInt(netmaskInt);
-            return buffer.array();
-        }
-
-        protected abstract void encodeValueToByteBuffer(ByteBuffer buffer);
-
-        protected abstract int getValueLength();
-
-        protected abstract boolean isLengthValid(int length);
-    }
-
-    /**
-     * This class represents common information of all Configuration Attributes whoses value is one
-     * IPv4 address or empty.
-     */
-    abstract static class ConfigAttrIpv4AddressBase extends ConfigAttribute {
-        public final Inet4Address address;
-
-        protected ConfigAttrIpv4AddressBase(int attributeType, Inet4Address address) {
-            super(attributeType);
-            this.address = address;
-        }
-
-        protected ConfigAttrIpv4AddressBase(int attributeType) {
-            super(attributeType);
-            this.address = null;
-        }
-
-        protected ConfigAttrIpv4AddressBase(int attributeType, byte[] value)
-                throws InvalidSyntaxException {
-            super(attributeType, value.length);
-
-            if (value.length == VALUE_LEN_NOT_INCLUDED) {
-                address = null;
-                return;
-            }
-
-            try {
-                address = (Inet4Address) Inet4Address.getByAddress(value);
-            } catch (UnknownHostException e) {
-                throw new InvalidSyntaxException("Invalid attribute value", e);
-            }
-        }
-
-        @Override
-        protected void encodeValueToByteBuffer(ByteBuffer buffer) {
-            if (address == null) {
-                buffer.put(new byte[0]);
-                return;
-            }
-
-            buffer.put(address.getAddress());
-        }
-
-        @Override
-        protected int getValueLength() {
-            return address == null ? 0 : IPV4_ADDRESS_LEN;
-        }
-
-        @Override
-        protected boolean isLengthValid(int length) {
-            return length == IPV4_ADDRESS_LEN || length == VALUE_LEN_NOT_INCLUDED;
-        }
-    }
-
-    /** This class represents Configuration Attribute for IPv4 internal address. */
-    public static class ConfigAttributeIpv4Address extends ConfigAttrIpv4AddressBase {
-        /** Construct an instance with specified address for an outbound packet. */
-        public ConfigAttributeIpv4Address(Inet4Address ipv4Address) {
-            super(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, ipv4Address);
-        }
-
-        /**
-         * Construct an instance without a specified address for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv4Address() {
-            super(CONFIG_ATTR_INTERNAL_IP4_ADDRESS);
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        ConfigAttributeIpv4Address(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, value);
-        }
-    }
-
-    /**
-     * This class represents Configuration Attribute for IPv4 netmask.
-     *
-     * <p>Non-empty values for this attribute in a CFG_REQUEST do not make sense and thus MUST NOT
-     * be included
-     */
-    public static class ConfigAttributeIpv4Netmask extends ConfigAttrIpv4AddressBase {
-        /**
-         * Construct an instance without a specified netmask for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv4Netmask() {
-            super(CONFIG_ATTR_INTERNAL_IP4_NETMASK);
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        public ConfigAttributeIpv4Netmask(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP4_NETMASK, value);
-
-            if (address == null) return;
-            try {
-                netmaskToPrefixLen(address);
-            } catch (IllegalArgumentException e) {
-                throw new InvalidSyntaxException("Invalid attribute value", e);
-            }
-        }
-
-        /** Convert netmask to prefix length. */
-        public int getPrefixLen() {
-            return netmaskToPrefixLen(address);
-        }
-    }
-
-    /** This class represents Configuration Attribute for IPv4 DHCP server. */
-    public static class ConfigAttributeIpv4Dhcp extends ConfigAttrIpv4AddressBase {
-        /** Construct an instance with specified DHCP server address for an outbound packet. */
-        public ConfigAttributeIpv4Dhcp(Inet4Address ipv4Address) {
-            super(CONFIG_ATTR_INTERNAL_IP4_DHCP, ipv4Address);
-        }
-
-        /**
-         * Construct an instance without a specified DHCP server address for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv4Dhcp() {
-            super(CONFIG_ATTR_INTERNAL_IP4_DHCP);
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        ConfigAttributeIpv4Dhcp(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP4_DHCP, value);
-        }
-    }
-
-    /**
-     * This class represents Configuration Attribute for IPv4 DNS.
-     *
-     * <p>There is no use case to create a DNS request for a specfic DNS server address. As an IKE
-     * client, we will only support building an empty DNS attribute for an outbound IKE packet.
-     */
-    public static class ConfigAttributeIpv4Dns extends ConfigAttrIpv4AddressBase {
-        /** Construct an instance with specified DNS server address for an outbound packet. */
-        public ConfigAttributeIpv4Dns(Inet4Address ipv4Address) {
-            super(CONFIG_ATTR_INTERNAL_IP4_DNS, ipv4Address);
-        }
-
-        /**
-         * Construct an instance without a specified DNS server address for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv4Dns() {
-            super(CONFIG_ATTR_INTERNAL_IP4_DNS);
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        ConfigAttributeIpv4Dns(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP4_DNS, value);
-        }
-    }
-
-    /** This class represents Configuration Attribute for IPv4 subnets. */
-    public static class ConfigAttributeIpv4Subnet extends ConfigAttribute {
-        private static final int VALUE_LEN = 2 * IPV4_ADDRESS_LEN;
-
-        public final LinkAddress linkAddress;
-
-        /** Construct an instance with specified subnet for an outbound packet. */
-        public ConfigAttributeIpv4Subnet(LinkAddress ipv4LinkAddress) {
-            super(CONFIG_ATTR_INTERNAL_IP4_SUBNET);
-
-            if (!ipv4LinkAddress.isIpv4()) {
-                throw new IllegalArgumentException("Input LinkAddress is not IPv4");
-            }
-
-            this.linkAddress = ipv4LinkAddress;
-        }
-
-        /**
-         * Construct an instance without a specified subnet for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv4Subnet() {
-            super(CONFIG_ATTR_INTERNAL_IP4_SUBNET);
-            this.linkAddress = null;
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        ConfigAttributeIpv4Subnet(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP4_SUBNET, value.length);
-
-            if (value.length == VALUE_LEN_NOT_INCLUDED) {
-                linkAddress = null;
-                return;
-            }
-
-            try {
-                ByteBuffer inputBuffer = ByteBuffer.wrap(value);
-                byte[] ipBytes = new byte[IPV4_ADDRESS_LEN];
-                inputBuffer.get(ipBytes);
-                byte[] netmaskBytes = new byte[IPV4_ADDRESS_LEN];
-                inputBuffer.get(netmaskBytes);
-
-                InetAddress address = InetAddress.getByAddress(ipBytes);
-                InetAddress netmask = InetAddress.getByAddress(netmaskBytes);
-                validateInet4AddressTypeOrThrow(address);
-                validateInet4AddressTypeOrThrow(netmask);
-
-                linkAddress = new LinkAddress(address, netmaskToPrefixLen((Inet4Address) netmask));
-            } catch (UnknownHostException | IllegalArgumentException e) {
-                throw new InvalidSyntaxException("Invalid attribute value", e);
-            }
-        }
-
-        private void validateInet4AddressTypeOrThrow(InetAddress address) {
-            if (!(address instanceof Inet4Address)) {
-                throw new IllegalArgumentException("Input InetAddress is not IPv4");
-            }
-        }
-
-        @Override
-        protected void encodeValueToByteBuffer(ByteBuffer buffer) {
-            if (linkAddress == null) {
-                buffer.put(new byte[VALUE_LEN_NOT_INCLUDED]);
-                return;
-            }
-            byte[] netmaskBytes = prefixToNetmaskBytes(linkAddress.getPrefixLength());
-            buffer.put(linkAddress.getAddress().getAddress()).put(netmaskBytes);
-        }
-
-        @Override
-        protected int getValueLength() {
-            return linkAddress == null ? 0 : VALUE_LEN;
-        }
-
-        @Override
-        protected boolean isLengthValid(int length) {
-            return length == VALUE_LEN || length == VALUE_LEN_NOT_INCLUDED;
-        }
-    }
-
-    /**
-     * This class represents common information of all Configuration Attributes whoses value is an
-     * IPv6 address range.
-     *
-     * <p>These attributes contains an IPv6 address and a prefix length.
-     */
-    abstract static class ConfigAttrIpv6AddrRangeBase extends ConfigAttribute {
-        private static final int VALUE_LEN = IPV6_ADDRESS_LEN + PREFIX_LEN_LEN;
-
-        public final LinkAddress linkAddress;
-
-        protected ConfigAttrIpv6AddrRangeBase(int attributeType, LinkAddress ipv6LinkAddress) {
-            super(attributeType);
-
-            validateIpv6LinkAddressTypeOrThrow(ipv6LinkAddress);
-            linkAddress = ipv6LinkAddress;
-        }
-
-        protected ConfigAttrIpv6AddrRangeBase(int attributeType) {
-            super(attributeType);
-            linkAddress = null;
-        }
-
-        protected ConfigAttrIpv6AddrRangeBase(int attributeType, byte[] value)
-                throws InvalidSyntaxException {
-            super(attributeType, value.length);
-
-            if (value.length == VALUE_LEN_NOT_INCLUDED) {
-                linkAddress = null;
-                return;
-            }
-
-            try {
-                ByteBuffer inputBuffer = ByteBuffer.wrap(value);
-                byte[] ip6AddrBytes = new byte[IPV6_ADDRESS_LEN];
-                inputBuffer.get(ip6AddrBytes);
-                InetAddress address = InetAddress.getByAddress(ip6AddrBytes);
-
-                int prefixLen = Byte.toUnsignedInt(inputBuffer.get());
-
-                linkAddress = new LinkAddress(address, prefixLen);
-                validateIpv6LinkAddressTypeOrThrow(linkAddress);
-            } catch (UnknownHostException | IllegalArgumentException e) {
-                throw new InvalidSyntaxException("Invalid attribute value", e);
-            }
-        }
-
-        private void validateIpv6LinkAddressTypeOrThrow(LinkAddress address) {
-            if (!address.isIpv6()) {
-                throw new IllegalArgumentException("Input LinkAddress is not IPv6");
-            }
-        }
-
-        @Override
-        protected void encodeValueToByteBuffer(ByteBuffer buffer) {
-            if (linkAddress == null) {
-                buffer.put(new byte[VALUE_LEN_NOT_INCLUDED]);
-                return;
-            }
-
-            buffer.put(linkAddress.getAddress().getAddress())
-                    .put((byte) linkAddress.getPrefixLength());
-        }
-
-        @Override
-        protected int getValueLength() {
-            return linkAddress == null ? VALUE_LEN_NOT_INCLUDED : VALUE_LEN;
-        }
-
-        @Override
-        protected boolean isLengthValid(int length) {
-            return length == VALUE_LEN || length == VALUE_LEN_NOT_INCLUDED;
-        }
-    }
-
-    /** This class represents Configuration Attribute for IPv6 internal addresses. */
-    public static class ConfigAttributeIpv6Address extends ConfigAttrIpv6AddrRangeBase {
-        /** Construct an instance with specified address for an outbound packet. */
-        public ConfigAttributeIpv6Address(LinkAddress ipv6LinkAddress) {
-            super(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, ipv6LinkAddress);
-        }
-
-        /**
-         * Construct an instance without a specified address for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv6Address() {
-            super(CONFIG_ATTR_INTERNAL_IP6_ADDRESS);
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        ConfigAttributeIpv6Address(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, value);
-        }
-    }
-
-    /** This class represents Configuration Attribute for IPv6 subnets. */
-    public static class ConfigAttributeIpv6Subnet extends ConfigAttrIpv6AddrRangeBase {
-        /** Construct an instance with specified subnet for an outbound packet. */
-        public ConfigAttributeIpv6Subnet(LinkAddress ipv6LinkAddress) {
-            super(CONFIG_ATTR_INTERNAL_IP6_SUBNET, ipv6LinkAddress);
-        }
-
-        /**
-         * Construct an instance without a specified subnet for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv6Subnet() {
-            super(CONFIG_ATTR_INTERNAL_IP6_SUBNET);
-        }
-
-        /** Construct an instance with a decoded inbound packet. */
-        @VisibleForTesting
-        ConfigAttributeIpv6Subnet(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP6_SUBNET, value);
-        }
-    }
-
-    /**
-     * This class represents Configuration Attribute for IPv6 DNS.
-     *
-     * <p>There is no use case to create a DNS request for a specfic DNS server address. As an IKE
-     * client, we will only support building an empty DNS attribute for an outbound IKE packet.
-     */
-    public static class ConfigAttributeIpv6Dns extends ConfigAttribute {
-        public final Inet6Address address;
-
-        /** Construct an instance with specified DNS server address for an outbound packet. */
-        public ConfigAttributeIpv6Dns(Inet6Address ipv6Address) {
-            super(CONFIG_ATTR_INTERNAL_IP6_DNS);
-            address = ipv6Address;
-        }
-
-        /**
-         * Construct an instance without a specified DNS server address for an outbound packet.
-         *
-         * <p>It must be only used in a configuration request.
-         */
-        public ConfigAttributeIpv6Dns() {
-            super(CONFIG_ATTR_INTERNAL_IP6_DNS);
-            this.address = null;
-        }
-
-        protected ConfigAttributeIpv6Dns(byte[] value) throws InvalidSyntaxException {
-            super(CONFIG_ATTR_INTERNAL_IP6_DNS, value.length);
-
-            if (value.length == VALUE_LEN_NOT_INCLUDED) {
-                address = null;
-                return;
-            }
-
-            try {
-                InetAddress netAddress = InetAddress.getByAddress(value);
-
-                if (!(netAddress instanceof Inet6Address)) {
-                    throw new InvalidSyntaxException("Invalid IPv6 address.");
-                }
-                address = (Inet6Address) netAddress;
-            } catch (UnknownHostException e) {
-                throw new InvalidSyntaxException("Invalid attribute value", e);
-            }
-        }
-
-        @Override
-        protected void encodeValueToByteBuffer(ByteBuffer buffer) {
-            if (address == null) {
-                buffer.put(new byte[0]);
-                return;
-            }
-
-            buffer.put(address.getAddress());
-        }
-
-        @Override
-        protected int getValueLength() {
-            return address == null ? 0 : IPV6_ADDRESS_LEN;
-        }
-
-        @Override
-        protected boolean isLengthValid(int length) {
-            return length == IPV6_ADDRESS_LEN || length == VALUE_LEN_NOT_INCLUDED;
-        }
-    }
-
-    /**
-     * Encode Configuration payload to ByteBUffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer.put((byte) configType).put(new byte[CONFIG_HEADER_RESERVED_LEN]);
-
-        for (ConfigAttribute attr : recognizedAttributeList) {
-            attr.encodeAttributeToByteBuffer(byteBuffer);
-        }
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        int len = GENERIC_HEADER_LENGTH + CONFIG_HEADER_LEN;
-
-        for (ConfigAttribute attr : recognizedAttributeList) {
-            len += attr.getAttributeLen();
-        }
-
-        return len;
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        switch (configType) {
-            case CONFIG_TYPE_REQUEST:
-                return "CP(Req)";
-            case CONFIG_TYPE_REPLY:
-                return "CP(Reply)";
-            default:
-                return "CP(" + configType + ")";
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayload.java
deleted file mode 100644
index f629f50..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayload.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import java.nio.ByteBuffer;
-
-/**
- * IkeDeletePayload represents a Delete Payload.
- *
- * <p>As instructed in RFC 7296, deletion of the IKE SA is indicated by a protocol ID of 1 (IKE) but
- * no SPIs. Deletion of a Child SA will contain the IPsec protocol ID and SPIs of inbound IPsec
- * packets. Since IKE library only supports negotiating Child SA using ESP, only the protocol ID of
- * 3 (ESP) is used for deleting Child SA.
- *
- * The possible request/response pairs for deletion are as follows:
- * - IKE SA deletion:
- *     Incoming: INFORMATIONAL(DELETE(PROTO_IKE))
- *     Outgoing: INFORMATIONAL()
- *
- * - ESP SA deletion:
- *     Incoming: INFORMATIONAL(DELETE(PROTO_ESP, SPI_A_OUT))
- *     Outgoing: INFORMATIONAL(DELETE(PROTO_ESP, SPI_A_IN))
- *
- * - ESP SA simultaneous deletion:
- *     Outgoing: INFORMATIONAL(DELETE(PROTO_ESP, SPI_A_IN))
- *     Incoming: INFORMATIONAL(DELETE(PROTO_ESP, SPI_A_OUT))
- *     Outgoing: INFORMATIONAL() // Notice DELETE payload omitted
- *
- * - ESP SA simultaneous multi-deletion:
- *     Outgoing: INFORMATIONAL(DELETE(PROTO_ESP, SPI_A_IN))
- *     Incoming: INFORMATIONAL(DELETE(PROTO_ESP, SPI_A_OUT, SPI_B_OUT))
- *     Outgoing: INFORMATIONAL(DELETE(PROTO_ESP, SPI_B_IN)) // Notice SPI_A_OUT omitted
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.11">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeDeletePayload extends IkeInformationalPayload {
-    private static final int DELETE_HEADER_LEN = 4;
-
-    @ProtocolId public final int protocolId;
-    public final byte spiSize;
-    public final int numSpi;
-    public final int[] spisToDelete;
-
-    /**
-     * Construct an instance of IkeDeletePayload from decoding inbound IKE packet.
-     *
-     * <p>NegativeArraySizeException and BufferUnderflowException will be caught in {@link
-     * IkeMessage}
-     *
-     * @param critical indicates if this payload is critical. Ignored in supported payload as
-     *     instructed by the RFC 7296.
-     * @param payloadBody payload body in byte array
-     * @throws IkeProtocolException if there is any error
-     */
-    IkeDeletePayload(boolean critical, byte[] payloadBody) throws IkeProtocolException {
-        super(PAYLOAD_TYPE_DELETE, critical);
-
-        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
-
-        protocolId = Byte.toUnsignedInt(inputBuffer.get());
-        spiSize = inputBuffer.get();
-        numSpi = Short.toUnsignedInt(inputBuffer.getShort());
-        spisToDelete = new int[numSpi];
-
-        switch (protocolId) {
-            case PROTOCOL_ID_IKE:
-                // Delete payload for IKE SA must not include SPI.
-                if (spiSize != SPI_LEN_NOT_INCLUDED
-                        || numSpi != 0
-                        || inputBuffer.remaining() != 0) {
-                    throw new InvalidSyntaxException("Invalid Delete IKE Payload.");
-                }
-                break;
-            case PROTOCOL_ID_ESP:
-                // Delete payload for Child SA must include SPI
-                if (spiSize != SPI_LEN_IPSEC
-                        || numSpi == 0
-                        || inputBuffer.remaining() != SPI_LEN_IPSEC * numSpi) {
-                    throw new InvalidSyntaxException("Invalid Delete Child Payload.");
-                }
-
-                for (int i = 0; i < numSpi; i++) {
-                    spisToDelete[i] = inputBuffer.getInt();
-                }
-                break;
-            default:
-                throw new InvalidSyntaxException("Unrecognized protocol in Delete Payload.");
-        }
-    }
-
-    /**
-     * Constructor for an outbound IKE SA deletion payload.
-     *
-     * <p>This constructor takes no SPI, as IKE SAs are deleted by sending a delete payload within
-     * the negotiated session. As such, the SPIs are shared state that does not need to be sent.
-     */
-    public IkeDeletePayload() {
-        super(PAYLOAD_TYPE_DELETE, false);
-        protocolId = PROTOCOL_ID_IKE;
-        spiSize = SPI_LEN_NOT_INCLUDED;
-        numSpi = 0;
-        spisToDelete = new int[0];
-    }
-
-    /**
-     * Constructor for an outbound Child SA deletion payload.
-     *
-     * @param spis array of SPIs of Child SAs to delete. Must contain at least one SPI.
-     */
-    public IkeDeletePayload(int[] spis) {
-        super(PAYLOAD_TYPE_DELETE, false);
-
-        if (spis == null || spis.length < 1) {
-            throw new IllegalArgumentException("No SPIs provided");
-        }
-
-        protocolId = PROTOCOL_ID_ESP;
-        spiSize = SPI_LEN_IPSEC;
-        numSpi = spis.length;
-        spisToDelete = spis;
-    }
-
-    /**
-     * Encode Delete Payload to ByteBuffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer.put((byte) protocolId).put(spiSize).putShort((short) numSpi);
-
-        for (int toDelete : spisToDelete) {
-            byteBuffer.putInt(toDelete);
-        }
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        return GENERIC_HEADER_LENGTH + DELETE_HEADER_LEN + spisToDelete.length * spiSize;
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "Del";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayload.java
deleted file mode 100644
index 5dc1497..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayload.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import com.android.internal.net.eap.message.EapMessage;
-
-import java.nio.ByteBuffer;
-
-/**
- * IkeEapPayload represents an EAP payload.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.8">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- *     Protocol (EAP)</a>
- */
-public final class IkeEapPayload extends IkePayload {
-    public final byte[] eapMessage;
-
-    /**
-     * Construct an instance of IkeEapPayload from a decoded inbound IKE packet.
-     *
-     * <p>Any syntax errors contained in the eapMessage will be handled in {@link EapMessage}.
-     *
-     * @param isCritical indicates if this payload is critical. Ignored in supported payload as
-     *     instructed by the RFC 7296.
-     * @param eapMessage byte-array encoded EapMessage
-     */
-    IkeEapPayload(boolean isCritical, byte[] eapMessage) {
-        super(PAYLOAD_TYPE_EAP, isCritical);
-
-        this.eapMessage = eapMessage;
-    }
-
-    /**
-     * Construct an instance of IkeEapPayload for an outbound IKE EAP message.
-     *
-     * <p>This eapMessage is constructed in the IKE session and is guaranteed to have valid syntax.
-     *
-     * @param eapMessage byte-array encoded EapMessage
-     */
-    public IkeEapPayload(byte[] eapMessage) {
-        super(PAYLOAD_TYPE_EAP, false);
-
-        this.eapMessage = eapMessage;
-    }
-
-    /**
-     * Encode EAP Payload to ByteBuffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer.put(eapMessage);
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        return GENERIC_HEADER_LENGTH + eapMessage.length;
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "EAP";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBody.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBody.java
deleted file mode 100644
index 77cc9f4..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBody.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeCombinedModeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher;
-
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-import javax.crypto.AEADBadTagException;
-import javax.crypto.IllegalBlockSizeException;
-
-/**
- * IkeEncryptedPayloadBody is a package private class that represents an IKE payload substructure
- * that contains initialization vector, encrypted content, padding, pad length and integrity
- * checksum.
- *
- * <p>Both an Encrypted Payload (IkeSkPayload) and an EncryptedFragmentPayload (IkeSkfPayload)
- * consists of an IkeEncryptedPayloadBody instance.
- *
- * <p>When using normal cipher with separate integrity algorithm, data to authenticate includes
- * bytes from beginning of IKE header to the pad length, which are concatenation of IKE header,
- * current payload header, iv and encrypted and padded data.
- *
- * <p>When using AEAD, additional authentication data(also known as) associated data is required. It
- * MUST include bytes from beginning of IKE header to the last octet of the Payload Header of the
- * Encrypted Payload. Note fragment number and total fragments are also included if Encrypted
- * Payload is SKF.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#page-105">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- * @see <a href="https://tools.ietf.org/html/rfc7383#page-6">RFC 7383, Internet Key Exchange
- *     Protocol Version 2 (IKEv2) Message Fragmentation</a>
- */
-final class IkeEncryptedPayloadBody {
-    // Length of pad length field.
-    private static final int PAD_LEN_LEN = 1;
-
-    private final byte[] mUnencryptedData;
-    private final byte[] mEncryptedAndPaddedData;
-    private final byte[] mIv;
-    private final byte[] mIntegrityChecksum;
-
-    /**
-     * Package private constructor for constructing an instance of IkeEncryptedPayloadBody from
-     * decrypting an incoming packet.
-     */
-    IkeEncryptedPayloadBody(
-            byte[] message,
-            int encryptedBodyOffset,
-            IkeMacIntegrity integrityMac,
-            IkeCipher decryptCipher,
-            byte[] integrityKey,
-            byte[] decryptionKey)
-            throws IkeProtocolException, GeneralSecurityException {
-        ByteBuffer inputBuffer = ByteBuffer.wrap(message);
-
-        // Skip IKE header and generic payload header (and SKF header)
-        inputBuffer.get(new byte[encryptedBodyOffset]);
-
-        // Extract bytes for authentication and decryption.
-        int expectedIvLen = decryptCipher.getIvLen();
-        mIv = new byte[expectedIvLen];
-
-        int checksumLen = getChecksum(integrityMac, decryptCipher);
-        int encryptedDataLen = message.length - (encryptedBodyOffset + expectedIvLen + checksumLen);
-        // IkeMessage will catch exception if encryptedDataLen is negative.
-        mEncryptedAndPaddedData = new byte[encryptedDataLen];
-
-        mIntegrityChecksum = new byte[checksumLen];
-        inputBuffer.get(mIv).get(mEncryptedAndPaddedData).get(mIntegrityChecksum);
-
-        if (decryptCipher.isAead()) {
-            byte[] dataToAuthenticate = Arrays.copyOfRange(message, 0, encryptedBodyOffset);
-            mUnencryptedData =
-                    combinedModeDecrypt(
-                            (IkeCombinedModeCipher) decryptCipher,
-                            mEncryptedAndPaddedData,
-                            mIntegrityChecksum,
-                            dataToAuthenticate,
-                            decryptionKey,
-                            mIv);
-        } else {
-            byte[] dataToAuthenticate =
-                    Arrays.copyOfRange(message, 0, message.length - checksumLen);
-
-            validateInboundChecksumOrThrow(
-                    dataToAuthenticate, integrityMac, integrityKey, mIntegrityChecksum);
-            mUnencryptedData =
-                    normalModeDecrypt(
-                            mEncryptedAndPaddedData,
-                            (IkeNormalModeCipher) decryptCipher,
-                            decryptionKey,
-                            mIv);
-        }
-    }
-
-    /**
-     * Package private constructor for constructing an instance of IkeEncryptedPayloadBody for
-     * building an outbound packet.
-     */
-    IkeEncryptedPayloadBody(
-            IkeHeader ikeHeader,
-            @IkePayload.PayloadType int firstPayloadType,
-            byte[] skfHeaderBytes,
-            byte[] unencryptedPayloads,
-            IkeMacIntegrity integrityMac,
-            IkeCipher encryptCipher,
-            byte[] integrityKey,
-            byte[] encryptionKey) {
-        this(
-                ikeHeader,
-                firstPayloadType,
-                skfHeaderBytes,
-                unencryptedPayloads,
-                integrityMac,
-                encryptCipher,
-                integrityKey,
-                encryptionKey,
-                encryptCipher.generateIv(),
-                calculatePadding(unencryptedPayloads.length, encryptCipher.getBlockSize()));
-    }
-
-    /** Package private constructor only for testing. */
-    @VisibleForTesting
-    IkeEncryptedPayloadBody(
-            IkeHeader ikeHeader,
-            @IkePayload.PayloadType int firstPayloadType,
-            byte[] skfHeaderBytes,
-            byte[] unencryptedPayloads,
-            IkeMacIntegrity integrityMac,
-            IkeCipher encryptCipher,
-            byte[] integrityKey,
-            byte[] encryptionKey,
-            byte[] iv,
-            byte[] padding) {
-        mUnencryptedData = unencryptedPayloads;
-
-        mIv = iv;
-        if (encryptCipher.isAead()) {
-            byte[] paddedDataWithChecksum =
-                    combinedModeEncrypt(
-                            (IkeCombinedModeCipher) encryptCipher,
-                            ikeHeader,
-                            firstPayloadType,
-                            skfHeaderBytes,
-                            unencryptedPayloads,
-                            encryptionKey,
-                            iv,
-                            padding);
-
-            int checkSumLen = ((IkeCombinedModeCipher) encryptCipher).getChecksumLen();
-            mIntegrityChecksum = new byte[checkSumLen];
-            mEncryptedAndPaddedData = new byte[paddedDataWithChecksum.length - checkSumLen];
-
-            ByteBuffer buffer = ByteBuffer.wrap(paddedDataWithChecksum);
-            buffer.get(mEncryptedAndPaddedData);
-            buffer.get(mIntegrityChecksum);
-        } else {
-            // Encrypt data
-            mEncryptedAndPaddedData =
-                    normalModeEncrypt(
-                            unencryptedPayloads,
-                            (IkeNormalModeCipher) encryptCipher,
-                            encryptionKey,
-                            iv,
-                            padding);
-            // Calculate checksum
-            mIntegrityChecksum =
-                    generateOutboundChecksum(
-                            ikeHeader,
-                            firstPayloadType,
-                            skfHeaderBytes,
-                            integrityMac,
-                            iv,
-                            mEncryptedAndPaddedData,
-                            integrityKey);
-        }
-    }
-
-    private int getChecksum(IkeMacIntegrity integrityMac, IkeCipher decryptCipher) {
-        if (decryptCipher.isAead()) {
-            return ((IkeCombinedModeCipher) decryptCipher).getChecksumLen();
-        } else {
-            return integrityMac.getChecksumLen();
-        }
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static byte[] generateOutboundChecksum(
-            IkeHeader ikeHeader,
-            @IkePayload.PayloadType int firstPayloadType,
-            byte[] skfHeaderBytes,
-            IkeMacIntegrity integrityMac,
-            byte[] iv,
-            byte[] encryptedAndPaddedData,
-            byte[] integrityKey) {
-        // Length from encrypted payload header to the Pad Length field
-        int encryptedPayloadHeaderToPadLen =
-                IkePayload.GENERIC_HEADER_LENGTH
-                        + skfHeaderBytes.length
-                        + iv.length
-                        + encryptedAndPaddedData.length;
-
-        // Calculate length of authentication data and allocate ByteBuffer.
-        int dataToAuthenticateLength = IkeHeader.IKE_HEADER_LENGTH + encryptedPayloadHeaderToPadLen;
-        ByteBuffer authenticatedSectionBuffer = ByteBuffer.allocate(dataToAuthenticateLength);
-
-        // Build data to authenticate.
-        int encryptedPayloadLength = encryptedPayloadHeaderToPadLen + integrityMac.getChecksumLen();
-        ikeHeader.encodeToByteBuffer(authenticatedSectionBuffer, encryptedPayloadLength);
-        IkePayload.encodePayloadHeaderToByteBuffer(
-                firstPayloadType, encryptedPayloadLength, authenticatedSectionBuffer);
-        authenticatedSectionBuffer.put(skfHeaderBytes).put(iv).put(encryptedAndPaddedData);
-
-        // Calculate checksum
-        return integrityMac.generateChecksum(integrityKey, authenticatedSectionBuffer.array());
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static void validateInboundChecksumOrThrow(
-            byte[] dataToAuthenticate,
-            IkeMacIntegrity integrityMac,
-            byte[] integrityKey,
-            byte[] integrityChecksum)
-            throws GeneralSecurityException {
-        // TODO: Make it package private and add test.
-        int checkSumLen = integrityChecksum.length;
-        byte[] calculatedChecksum = integrityMac.generateChecksum(integrityKey, dataToAuthenticate);
-
-        if (!Arrays.equals(integrityChecksum, calculatedChecksum)) {
-            throw new GeneralSecurityException("Message authentication failed.");
-        }
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static byte[] normalModeEncrypt(
-            byte[] dataToEncrypt,
-            IkeNormalModeCipher encryptCipher,
-            byte[] encryptionKey,
-            byte[] iv,
-            byte[] padding) {
-        byte[] paddedData = getPaddedData(dataToEncrypt, padding);
-
-        // Encrypt data.
-        return encryptCipher.encrypt(paddedData, encryptionKey, iv);
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static byte[] normalModeDecrypt(
-            byte[] encryptedData,
-            IkeNormalModeCipher decryptCipher,
-            byte[] decryptionKey,
-            byte[] iv)
-            throws IllegalBlockSizeException {
-        byte[] paddedPlaintext = decryptCipher.decrypt(encryptedData, decryptionKey, iv);
-
-        return stripPadding(paddedPlaintext);
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static byte[] combinedModeEncrypt(
-            IkeCombinedModeCipher encryptCipher,
-            IkeHeader ikeHeader,
-            @IkePayload.PayloadType int firstPayloadType,
-            byte[] skfHeaderBytes,
-            byte[] dataToEncrypt,
-            byte[] encryptionKey,
-            byte[] iv,
-            byte[] padding) {
-        int dataToAuthenticateLength =
-                IkeHeader.IKE_HEADER_LENGTH
-                        + IkePayload.GENERIC_HEADER_LENGTH
-                        + skfHeaderBytes.length;
-        ByteBuffer authenticatedSectionBuffer = ByteBuffer.allocate(dataToAuthenticateLength);
-
-        byte[] paddedData = getPaddedData(dataToEncrypt, padding);
-        int encryptedPayloadLength =
-                IkePayload.GENERIC_HEADER_LENGTH
-                        + skfHeaderBytes.length
-                        + iv.length
-                        + paddedData.length
-                        + encryptCipher.getChecksumLen();
-        ikeHeader.encodeToByteBuffer(authenticatedSectionBuffer, encryptedPayloadLength);
-        IkePayload.encodePayloadHeaderToByteBuffer(
-                firstPayloadType, encryptedPayloadLength, authenticatedSectionBuffer);
-        authenticatedSectionBuffer.put(skfHeaderBytes);
-
-        return encryptCipher.encrypt(
-                paddedData, authenticatedSectionBuffer.array(), encryptionKey, iv);
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static byte[] combinedModeDecrypt(
-            IkeCombinedModeCipher decryptCipher,
-            byte[] encryptedData,
-            byte[] checksum,
-            byte[] dataToAuthenticate,
-            byte[] decryptionKey,
-            byte[] iv)
-            throws AEADBadTagException {
-        ByteBuffer dataWithChecksumBuffer =
-                ByteBuffer.allocate(encryptedData.length + checksum.length);
-        dataWithChecksumBuffer.put(encryptedData);
-        dataWithChecksumBuffer.put(checksum);
-        dataWithChecksumBuffer.rewind();
-
-        byte[] paddedPlaintext =
-                decryptCipher.decrypt(
-                        dataWithChecksumBuffer.array(), dataToAuthenticate, decryptionKey, iv);
-
-        return stripPadding(paddedPlaintext);
-    }
-
-    /** Package private for testing */
-    @VisibleForTesting
-    static byte[] calculatePadding(int dataToEncryptLength, int blockSize) {
-        // Sum of dataToEncryptLength, PAD_LEN_LEN and padLength should be aligned with block size.
-        int unpaddedLen = dataToEncryptLength + PAD_LEN_LEN;
-        int padLength = (unpaddedLen + blockSize - 1) / blockSize * blockSize - unpaddedLen;
-        byte[] padding = new byte[padLength];
-
-        // According to RFC 7296, "Padding MAY contain any value".
-        new SecureRandom().nextBytes(padding);
-
-        return padding;
-    }
-
-    private static byte[] getPaddedData(byte[] data, byte[] padding) {
-        int padLength = padding.length;
-        int paddedDataLength = data.length + padLength + PAD_LEN_LEN;
-        ByteBuffer padBuffer = ByteBuffer.allocate(paddedDataLength);
-        padBuffer.put(data).put(padding).put((byte) padLength);
-
-        return padBuffer.array();
-    }
-
-    private static byte[] stripPadding(byte[] paddedPlaintext) {
-        // Remove padding. Pad length value is the last byte of the padded unencrypted data.
-        int padLength = Byte.toUnsignedInt(paddedPlaintext[paddedPlaintext.length - 1]);
-        int decryptedDataLen = paddedPlaintext.length - padLength - PAD_LEN_LEN;
-
-        return Arrays.copyOfRange(paddedPlaintext, 0, decryptedDataLen);
-    }
-
-    /** Package private */
-    byte[] getUnencryptedData() {
-        return mUnencryptedData;
-    }
-
-    /** Package private */
-    int getLength() {
-        return (mIv.length + mEncryptedAndPaddedData.length + mIntegrityChecksum.length);
-    }
-
-    /** Package private */
-    byte[] encode() {
-        ByteBuffer buffer = ByteBuffer.allocate(getLength());
-        buffer.put(mIv).put(mEncryptedAndPaddedData).put(mIntegrityChecksum);
-        return buffer.array();
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeInformationalPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeInformationalPayload.java
deleted file mode 100644
index 606c38f..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeInformationalPayload.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-/**
- * IkeInformationalPayload abstracts all Payloads sent in INFORMATIONAL exchanges.
- *
- * <p>This class is a non-RFC payload for implementation simplicity.
- */
-public abstract class IkeInformationalPayload extends IkePayload {
-    IkeInformationalPayload(int payloadType, boolean isCritical) {
-        super(payloadType, isCritical);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeMessage.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeMessage.java
deleted file mode 100644
index 27fb965..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeMessage.java
+++ /dev/null
@@ -1,981 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static android.net.ipsec.ike.IkeManager.getIkeLog;
-
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PayloadType;
-
-import android.annotation.IntDef;
-import android.annotation.Nullable;
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeInternalException;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidMessageIdException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException;
-import com.android.org.bouncycastle.jce.provider.BouncyCastleProvider;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.security.Provider;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-/**
- * IkeMessage represents an IKE message.
- *
- * <p>It contains all attributes and provides methods for encoding, decoding, encrypting and
- * decrypting.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeMessage {
-    private static final String TAG = "IkeMessage";
-
-    private static IIkeMessageHelper sIkeMessageHelper = new IkeMessageHelper();
-
-    // Currently use Bouncy Castle as crypto security provider
-    static final Provider SECURITY_PROVIDER = new BouncyCastleProvider();
-
-    // TODO: b/142070035 Use Conscrypt as default security provider instead of BC
-
-    // Currently use HarmonyJSSE as TrustManager provider
-    static final Provider TRUST_MANAGER_PROVIDER = Security.getProvider("HarmonyJSSE");
-
-    // Payload types in this set may be included multiple times within an IKE message. All other
-    // payload types can be included at most once.
-    private static final Set<Integer> REPEATABLE_PAYLOAD_TYPES = new HashSet<>();
-
-    static {
-        REPEATABLE_PAYLOAD_TYPES.add(IkePayload.PAYLOAD_TYPE_CERT);
-        REPEATABLE_PAYLOAD_TYPES.add(IkePayload.PAYLOAD_TYPE_CERT_REQUEST);
-        REPEATABLE_PAYLOAD_TYPES.add(IkePayload.PAYLOAD_TYPE_NOTIFY);
-        REPEATABLE_PAYLOAD_TYPES.add(IkePayload.PAYLOAD_TYPE_DELETE);
-        REPEATABLE_PAYLOAD_TYPES.add(IkePayload.PAYLOAD_TYPE_VENDOR);
-    }
-
-    public final IkeHeader ikeHeader;
-    public final List<IkePayload> ikePayloadList;
-    /**
-     * Conctruct an instance of IkeMessage. It is called by decode or for building outbound message.
-     *
-     * @param header the header of this IKE message
-     * @param payloadList the list of decoded IKE payloads in this IKE message
-     */
-    public IkeMessage(IkeHeader header, List<IkePayload> payloadList) {
-        ikeHeader = header;
-        ikePayloadList = payloadList;
-    }
-
-    /**
-     * Get security provider for IKE library
-     *
-     * <p>Use BouncyCastleProvider as the default security provider.
-     *
-     * @return the security provider of IKE library.
-     */
-    public static Provider getSecurityProvider() {
-        // TODO: Move this getter out of IKE message package since not only this package uses it.
-        return SECURITY_PROVIDER;
-    }
-
-    /**
-     * Get security provider for X509TrustManager to do certificate validation.
-     *
-     * <p>Use JSSEProvdier as the default security provider.
-     *
-     * @return the provider for X509TrustManager
-     */
-    public static Provider getTrustManagerProvider() {
-        return TRUST_MANAGER_PROVIDER;
-    }
-
-    /**
-     * Decode unencrypted IKE message body and create an instance of IkeMessage.
-     *
-     * <p>This method catches all RuntimeException during decoding incoming IKE packet.
-     *
-     * @param expectedMsgId the expected message ID to validate against.
-     * @param header the IKE header that is decoded but not validated.
-     * @param inputPacket the byte array contains the whole IKE message.
-     * @return the decoding result.
-     */
-    public static DecodeResult decode(int expectedMsgId, IkeHeader header, byte[] inputPacket) {
-        return sIkeMessageHelper.decode(expectedMsgId, header, inputPacket);
-    }
-
-    /**
-     * Decrypt and decode encrypted IKE message body and create an instance of IkeMessage.
-     *
-     * @param expectedMsgId the expected message ID to validate against.
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param decryptCipher the negotiated encryption algorithm.
-     * @param ikeSaRecord ikeSaRecord where this packet is sent on.
-     * @param ikeHeader header of IKE packet.
-     * @param packet IKE packet as a byte array.
-     * @param collectedFragments previously received IKE fragments.
-     * @return the decoding result.
-     */
-    public static DecodeResult decode(
-            int expectedMsgId,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher decryptCipher,
-            IkeSaRecord ikeSaRecord,
-            IkeHeader ikeHeader,
-            byte[] packet,
-            DecodeResultPartial collectedFragments) {
-        return sIkeMessageHelper.decode(
-                expectedMsgId,
-                integrityMac,
-                decryptCipher,
-                ikeSaRecord,
-                ikeHeader,
-                packet,
-                collectedFragments);
-    }
-
-    private static List<IkePayload> decodePayloadList(
-            @PayloadType int firstPayloadType, boolean isResp, byte[] unencryptedPayloads)
-            throws IkeProtocolException {
-        ByteBuffer inputBuffer = ByteBuffer.wrap(unencryptedPayloads);
-        int currentPayloadType = firstPayloadType;
-        // For supported payload
-        List<IkePayload> supportedPayloadList = new LinkedList<>();
-        // For unsupported critical payload
-        List<Integer> unsupportedCriticalPayloadList = new LinkedList<>();
-
-        // For marking the existence of supported payloads in this message.
-        HashSet<Integer> supportedTypesFoundSet = new HashSet<>();
-
-        StringBuilder logPayloadsSb = new StringBuilder();
-        logPayloadsSb.append("Decoded payloads [ ");
-
-        while (currentPayloadType != IkePayload.PAYLOAD_TYPE_NO_NEXT) {
-            Pair<IkePayload, Integer> pair =
-                    IkePayloadFactory.getIkePayload(currentPayloadType, isResp, inputBuffer);
-            IkePayload payload = pair.first;
-            logPayloadsSb.append(payload.getTypeString()).append(" ");
-
-            if (!(payload instanceof IkeUnsupportedPayload)) {
-                int type = payload.payloadType;
-                if (!supportedTypesFoundSet.add(type) && !REPEATABLE_PAYLOAD_TYPES.contains(type)) {
-                    throw new InvalidSyntaxException(
-                            "It is not allowed to have multiple payloads with payload type: "
-                                    + type);
-                }
-
-                supportedPayloadList.add(payload);
-            } else if (payload.isCritical) {
-                unsupportedCriticalPayloadList.add(payload.payloadType);
-            }
-            // Simply ignore unsupported uncritical payload.
-
-            currentPayloadType = pair.second;
-        }
-
-        logPayloadsSb.append("]");
-        getIkeLog().d("IkeMessage", logPayloadsSb.toString());
-
-        if (inputBuffer.remaining() > 0) {
-            throw new InvalidSyntaxException(
-                    "Malformed IKE Payload: Unexpected bytes at the end of packet.");
-        }
-
-        if (unsupportedCriticalPayloadList.size() > 0) {
-            throw new UnsupportedCriticalPayloadException(unsupportedCriticalPayloadList);
-        }
-
-        // TODO: Verify that for all status notification payloads, only
-        // NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP and NOTIFY_TYPE_IPCOMP_SUPPORTED can be included
-        // multiple times in a request message. There is not a clear number restriction for
-        // error notification payloads.
-
-        return supportedPayloadList;
-    }
-
-    /**
-     * Encode unencrypted IKE message.
-     *
-     * @return encoded IKE message in byte array.
-     */
-    public byte[] encode() {
-        return sIkeMessageHelper.encode(this);
-    }
-
-    /**
-     * Encrypt and encode packet.
-     *
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param encryptCipher the negotiated encryption algortihm.
-     * @param ikeSaRecord the ikeSaRecord where this packet is sent on.
-     * @param supportFragment if IKE fragmentation is supported
-     * @param fragSize the maximum size of IKE fragment
-     * @return encoded IKE message in byte array.
-     */
-    public byte[][] encryptAndEncode(
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher encryptCipher,
-            IkeSaRecord ikeSaRecord,
-            boolean supportFragment,
-            int fragSize) {
-        return sIkeMessageHelper.encryptAndEncode(
-                integrityMac, encryptCipher, ikeSaRecord, this, supportFragment, fragSize);
-    }
-
-    /**
-     * Encode all payloads to a byte array.
-     *
-     * @return byte array contains all encoded payloads
-     */
-    private byte[] encodePayloads() {
-        StringBuilder logPayloadsSb = new StringBuilder();
-        logPayloadsSb.append("Generating payloads [ ");
-
-        int payloadLengthSum = 0;
-        for (IkePayload payload : ikePayloadList) {
-            payloadLengthSum += payload.getPayloadLength();
-            logPayloadsSb.append(payload.getTypeString()).append(" ");
-        }
-        logPayloadsSb.append("]");
-        getIkeLog().d("IkeMessage", logPayloadsSb.toString());
-
-        if (ikePayloadList.isEmpty()) return new byte[0];
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(payloadLengthSum);
-        for (int i = 0; i < ikePayloadList.size() - 1; i++) {
-            ikePayloadList
-                    .get(i)
-                    .encodeToByteBuffer(ikePayloadList.get(i + 1).payloadType, byteBuffer);
-        }
-        ikePayloadList
-                .get(ikePayloadList.size() - 1)
-                .encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, byteBuffer);
-
-        return byteBuffer.array();
-    }
-
-    /** Package */
-    @VisibleForTesting
-    byte[] attachEncodedHeader(byte[] encodedIkeBody) {
-        ByteBuffer outputBuffer =
-                ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH + encodedIkeBody.length);
-        ikeHeader.encodeToByteBuffer(outputBuffer, encodedIkeBody.length);
-        outputBuffer.put(encodedIkeBody);
-        return outputBuffer.array();
-    }
-
-    /**
-     * Obtain all payloads with input payload type.
-     *
-     * <p>This method can be only applied to the payload types that can be included multiple times
-     * within an IKE message.
-     *
-     * @param payloadType the payloadType to look for.
-     * @param payloadClass the class of the desired payloads.
-     * @return a list of IkePayloads with the payloadType.
-     */
-    public <T extends IkePayload> List<T> getPayloadListForType(
-            @IkePayload.PayloadType int payloadType, Class<T> payloadClass) {
-        // STOPSHIP: b/130190639 Notify user the error and close IKE session.
-        if (!REPEATABLE_PAYLOAD_TYPES.contains(payloadType)) {
-            throw new IllegalArgumentException(
-                    "Received unexpected payloadType: "
-                            + payloadType
-                            + " that can be included at most once within an IKE message.");
-        }
-
-        return IkePayload.getPayloadListForTypeInProvidedList(
-                payloadType, payloadClass, ikePayloadList);
-    }
-
-    /**
-     * Obtain the payload with the input payload type.
-     *
-     * <p>This method can be only applied to the payload type that can be included at most once
-     * within an IKE message.
-     *
-     * @param payloadType the payloadType to look for.
-     * @param payloadClass the class of the desired payload.
-     * @return the IkePayload with the payloadType.
-     */
-    public <T extends IkePayload> T getPayloadForType(
-            @IkePayload.PayloadType int payloadType, Class<T> payloadClass) {
-        // STOPSHIP: b/130190639 Notify user the error and close IKE session.
-        if (REPEATABLE_PAYLOAD_TYPES.contains(payloadType)) {
-            throw new IllegalArgumentException(
-                    "Received unexpected payloadType: "
-                            + payloadType
-                            + " that may be included multiple times within an IKE message.");
-        }
-
-        return IkePayload.getPayloadForTypeInProvidedList(
-                payloadType, payloadClass, ikePayloadList);
-    }
-
-    /**
-     * Checks if this Request IkeMessage was a DPD message
-     *
-     * <p>An IKE message is a DPD request iff the message was encrypted (has a SK payload) and there
-     * were no payloads within the SK payload (or outside the SK payload).
-     */
-    public boolean isDpdRequest() {
-        return !ikeHeader.isResponseMsg
-                && ikeHeader.exchangeType == IkeHeader.EXCHANGE_TYPE_INFORMATIONAL
-                && ikePayloadList.isEmpty()
-                && ikeHeader.nextPayloadType == IkePayload.PAYLOAD_TYPE_SK;
-    }
-
-    /**
-     * IIkeMessageHelper provides interface for decoding, encoding and processing IKE packet.
-     *
-     * <p>IkeMessageHelper exists so that the interface is injectable for testing.
-     */
-    @VisibleForTesting
-    public interface IIkeMessageHelper {
-        /**
-         * Encode IKE message.
-         *
-         * @param ikeMessage message need to be encoded.
-         * @return encoded IKE message in byte array.
-         */
-        byte[] encode(IkeMessage ikeMessage);
-
-        /**
-         * Encrypt and encode IKE message.
-         *
-         * @param integrityMac the negotiated integrity algorithm.
-         * @param encryptCipher the negotiated encryption algortihm.
-         * @param ikeSaRecord the ikeSaRecord where this packet is sent on.
-         * @param ikeMessage message need to be encoded. * @param supportFragment if IKE
-         *     fragmentation is supported.
-         * @param fragSize the maximum size of IKE fragment.
-         * @return encoded IKE message in byte array.
-         */
-        byte[][] encryptAndEncode(
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher encryptCipher,
-                IkeSaRecord ikeSaRecord,
-                IkeMessage ikeMessage,
-                boolean supportFragment,
-                int fragSize);
-
-        // TODO: Return DecodeResult when decoding unencrypted message
-        /**
-         * Decode unencrypted packet.
-         *
-         * @param expectedMsgId the expected message ID to validate against.
-         * @param ikeHeader header of IKE packet.
-         * @param packet IKE packet as a byte array.
-         * @return the decoding result.
-         */
-        DecodeResult decode(int expectedMsgId, IkeHeader ikeHeader, byte[] packet);
-
-        /**
-         * Decrypt and decode packet.
-         *
-         * @param expectedMsgId the expected message ID to validate against.
-         * @param integrityMac the negotiated integrity algorithm.
-         * @param decryptCipher the negotiated encryption algorithm.
-         * @param ikeSaRecord ikeSaRecord where this packet is sent on.
-         * @param ikeHeader header of IKE packet.
-         * @param packet IKE packet as a byte array.
-         * @param collectedFragments previously received IKE fragments.
-         * @return the decoding result.
-         */
-        DecodeResult decode(
-                int expectedMsgId,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher decryptCipher,
-                IkeSaRecord ikeSaRecord,
-                IkeHeader ikeHeader,
-                byte[] packet,
-                DecodeResultPartial collectedFragments);
-    }
-
-    /** IkeMessageHelper provides methods for decoding, encoding and processing IKE packet. */
-    public static final class IkeMessageHelper implements IIkeMessageHelper {
-        @Override
-        public byte[] encode(IkeMessage ikeMessage) {
-            getIkeLog().d("IkeMessage", "Generating " + ikeMessage.ikeHeader.getBasicInfoString());
-
-            byte[] encodedIkeBody = ikeMessage.encodePayloads();
-            byte[] packet = ikeMessage.attachEncodedHeader(encodedIkeBody);
-            getIkeLog().d("IkeMessage", "Build a complete IKE message: " + getIkeLog().pii(packet));
-            return packet;
-        }
-
-        @Override
-        public byte[][] encryptAndEncode(
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher encryptCipher,
-                IkeSaRecord ikeSaRecord,
-                IkeMessage ikeMessage,
-                boolean supportFragment,
-                int fragSize) {
-            getIkeLog().d("IkeMessage", "Generating " + ikeMessage.ikeHeader.getBasicInfoString());
-
-            return encryptAndEncode(
-                    ikeMessage.ikeHeader,
-                    ikeMessage.ikePayloadList.isEmpty()
-                            ? IkePayload.PAYLOAD_TYPE_NO_NEXT
-                            : ikeMessage.ikePayloadList.get(0).payloadType,
-                    ikeMessage.encodePayloads(),
-                    integrityMac,
-                    encryptCipher,
-                    ikeSaRecord.getOutboundIntegrityKey(),
-                    ikeSaRecord.getOutboundEncryptionKey(),
-                    supportFragment,
-                    fragSize);
-        }
-
-        @VisibleForTesting
-        byte[][] encryptAndEncode(
-                IkeHeader ikeHeader,
-                @PayloadType int firstInnerPayload,
-                byte[] unencryptedPayloads,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher encryptCipher,
-                byte[] integrityKey,
-                byte[] encryptionKey,
-                boolean supportFragment,
-                int fragSize) {
-
-            IkeSkPayload skPayload =
-                    new IkeSkPayload(
-                            ikeHeader,
-                            firstInnerPayload,
-                            unencryptedPayloads,
-                            integrityMac,
-                            encryptCipher,
-                            integrityKey,
-                            encryptionKey);
-            int msgLen = IkeHeader.IKE_HEADER_LENGTH + skPayload.getPayloadLength();
-
-            // Build complete IKE message
-            if (!supportFragment || msgLen <= fragSize) {
-                byte[][] packetList = new byte[1][];
-                packetList[0] = encodeHeaderAndBody(ikeHeader, skPayload, firstInnerPayload);
-
-                getIkeLog()
-                        .d(
-                                "IkeMessage",
-                                "Build a complete IKE message: " + getIkeLog().pii(packetList[0]));
-                return packetList;
-            }
-
-            // Build IKE fragments
-            int dataLenPerPacket =
-                    fragSize
-                            - IkeHeader.IKE_HEADER_LENGTH
-                            - IkePayload.GENERIC_HEADER_LENGTH
-                            - IkeSkfPayload.SKF_HEADER_LEN
-                            - encryptCipher.getIvLen()
-                            - integrityMac.getChecksumLen()
-                            - encryptCipher.getBlockSize();
-
-            // Caller of this method MUST validate fragSize is valid.
-            if (dataLenPerPacket <= 0) {
-                throw new IllegalArgumentException(
-                        "Max fragment size is too small for an IKE fragment.");
-            }
-
-            int totalFragments =
-                    (unencryptedPayloads.length + dataLenPerPacket - 1) / dataLenPerPacket;
-            IkeHeader skfHeader = ikeHeader.makeSkfHeaderFromSkHeader();
-            byte[][] packetList = new byte[totalFragments][];
-
-            ByteBuffer unencryptedDataBuffer = ByteBuffer.wrap(unencryptedPayloads);
-            for (int i = 0; i < totalFragments; i++) {
-                byte[] unencryptedData =
-                        new byte[Math.min(dataLenPerPacket, unencryptedDataBuffer.remaining())];
-                unencryptedDataBuffer.get(unencryptedData);
-
-                int fragNum = i + 1; // 1-based
-
-                IkeSkfPayload skfPayload =
-                        new IkeSkfPayload(
-                                ikeHeader,
-                                firstInnerPayload,
-                                unencryptedData,
-                                integrityMac,
-                                encryptCipher,
-                                integrityKey,
-                                encryptionKey,
-                                fragNum,
-                                totalFragments);
-
-                packetList[i] =
-                        encodeHeaderAndBody(
-                                skfHeader,
-                                skfPayload,
-                                i == 0 ? firstInnerPayload : IkePayload.PAYLOAD_TYPE_NO_NEXT);
-                getIkeLog()
-                        .d(
-                                "IkeMessage",
-                                "Build an IKE fragment ("
-                                        + (i + 1)
-                                        + "/"
-                                        + totalFragments
-                                        + "): "
-                                        + getIkeLog().pii(packetList[0]));
-            }
-
-            return packetList;
-        }
-
-        private byte[] encodeHeaderAndBody(
-                IkeHeader ikeHeader, IkeSkPayload skPayload, @PayloadType int firstInnerPayload) {
-            ByteBuffer outputBuffer =
-                    ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH + skPayload.getPayloadLength());
-            ikeHeader.encodeToByteBuffer(outputBuffer, skPayload.getPayloadLength());
-            skPayload.encodeToByteBuffer(firstInnerPayload, outputBuffer);
-            return outputBuffer.array();
-        }
-
-        @Override
-        public DecodeResult decode(int expectedMsgId, IkeHeader header, byte[] inputPacket) {
-            try {
-                if (header.messageId != expectedMsgId) {
-                    throw new InvalidMessageIdException(header.messageId);
-                }
-
-                header.validateMajorVersion();
-                header.validateInboundHeader(inputPacket.length);
-
-                byte[] unencryptedPayloads =
-                        Arrays.copyOfRange(
-                                inputPacket, IkeHeader.IKE_HEADER_LENGTH, inputPacket.length);
-                List<IkePayload> supportedPayloadList =
-                        decodePayloadList(
-                                header.nextPayloadType, header.isResponseMsg, unencryptedPayloads);
-                return new DecodeResultOk(
-                        new IkeMessage(header, supportedPayloadList), inputPacket);
-            } catch (NegativeArraySizeException | BufferUnderflowException e) {
-                // Invalid length error when parsing payload bodies.
-                return new DecodeResultUnprotectedError(
-                        new InvalidSyntaxException("Malformed IKE Payload"));
-            } catch (IkeProtocolException e) {
-                return new DecodeResultUnprotectedError(e);
-            }
-        }
-
-        @Override
-        public DecodeResult decode(
-                int expectedMsgId,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher decryptCipher,
-                IkeSaRecord ikeSaRecord,
-                IkeHeader ikeHeader,
-                byte[] packet,
-                DecodeResultPartial collectedFragments) {
-            return decode(
-                    expectedMsgId,
-                    ikeHeader,
-                    packet,
-                    integrityMac,
-                    decryptCipher,
-                    ikeSaRecord.getInboundIntegrityKey(),
-                    ikeSaRecord.getInboundDecryptionKey(),
-                    collectedFragments);
-        }
-
-        private DecodeResult decode(
-                int expectedMsgId,
-                IkeHeader header,
-                byte[] inputPacket,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher decryptCipher,
-                byte[] integrityKey,
-                byte[] decryptionKey,
-                DecodeResultPartial collectedFragments) {
-            if (header.nextPayloadType != IkePayload.PAYLOAD_TYPE_SK
-                    && header.nextPayloadType != IkePayload.PAYLOAD_TYPE_SKF) {
-                // TODO: b/123372339 Handle message containing unprotected payloads.
-                throw new UnsupportedOperationException("Message contains unprotected payloads");
-            }
-
-            // Decrypt message and do authentication
-            Pair<IkeSkPayload, Integer> pair;
-            try {
-                pair =
-                        decryptAndAuthenticate(
-                                expectedMsgId,
-                                header,
-                                inputPacket,
-                                integrityMac,
-                                decryptCipher,
-                                integrityKey,
-                                decryptionKey);
-            } catch (IkeException e) {
-                if (collectedFragments == null) {
-                    return new DecodeResultUnprotectedError(e);
-                } else {
-                    getIkeLog()
-                            .i(
-                                    TAG,
-                                    "Message authentication or decryption failed on received"
-                                            + " message. Discard it ",
-                                    e);
-                    return collectedFragments;
-                }
-            }
-
-            // Handle IKE fragment
-            boolean isFragment = (header.nextPayloadType == IkePayload.PAYLOAD_TYPE_SKF);
-            boolean fragReassemblyStarted = (collectedFragments != null);
-
-            if (isFragment) {
-                getIkeLog()
-                        .d(
-                                TAG,
-                                "Received an IKE fragment ("
-                                        + ((IkeSkfPayload) pair.first).fragmentNum
-                                        + "/"
-                                        + ((IkeSkfPayload) pair.first).totalFragments
-                                        + ")");
-            }
-
-            // IKE fragment reassembly has started but a complete message was received.
-            if (!isFragment && fragReassemblyStarted) {
-                getIkeLog()
-                        .w(
-                                TAG,
-                                "Received a complete IKE message while doing IKE fragment"
-                                        + " reassembly. Discard the newly received message.");
-                return collectedFragments;
-            }
-
-            byte[] firstPacket = inputPacket;
-            byte[] decryptedBytes = pair.first.getUnencryptedData();
-            int firstPayloadType = pair.second;
-
-            // Received an IKE fragment
-            if (isFragment) {
-                validateFragmentHeader(header, inputPacket.length, collectedFragments);
-
-                // Add the recently received fragment to the reassembly queue.
-                DecodeResultPartial DecodeResultPartial =
-                        processIkeFragment(
-                                header,
-                                inputPacket,
-                                (IkeSkfPayload) (pair.first),
-                                pair.second,
-                                collectedFragments);
-
-                if (!DecodeResultPartial.isAllFragmentsReceived()) return DecodeResultPartial;
-
-                firstPayloadType = DecodeResultPartial.firstPayloadType;
-                decryptedBytes = DecodeResultPartial.reassembleAllFrags();
-                firstPacket = DecodeResultPartial.firstFragBytes;
-            }
-
-            // Received or has reassembled a complete IKE message. Check if there is protocol error.
-            try {
-                // TODO: Log IKE header information and payload types
-
-                List<IkePayload> supportedPayloadList =
-                        decodePayloadList(firstPayloadType, header.isResponseMsg, decryptedBytes);
-
-                header.validateInboundHeader(inputPacket.length);
-                return new DecodeResultOk(
-                        new IkeMessage(header, supportedPayloadList), firstPacket);
-            } catch (NegativeArraySizeException | BufferUnderflowException e) {
-                // Invalid length error when parsing payload bodies.
-                return new DecodeResultProtectedError(
-                        new InvalidSyntaxException("Malformed IKE Payload", e), firstPacket);
-            } catch (IkeProtocolException e) {
-                return new DecodeResultProtectedError(e, firstPacket);
-            }
-        }
-
-        private Pair<IkeSkPayload, Integer> decryptAndAuthenticate(
-                int expectedMsgId,
-                IkeHeader header,
-                byte[] inputPacket,
-                @Nullable IkeMacIntegrity integrityMac,
-                IkeCipher decryptCipher,
-                byte[] integrityKey,
-                byte[] decryptionKey)
-                throws IkeException {
-
-            try {
-                if (header.messageId != expectedMsgId) {
-                    throw new InvalidMessageIdException(header.messageId);
-                }
-
-                header.validateMajorVersion();
-
-                boolean isSkf = header.nextPayloadType == IkePayload.PAYLOAD_TYPE_SKF;
-                return IkePayloadFactory.getIkeSkPayload(
-                        isSkf,
-                        inputPacket,
-                        integrityMac,
-                        decryptCipher,
-                        integrityKey,
-                        decryptionKey);
-            } catch (NegativeArraySizeException | BufferUnderflowException e) {
-                throw new InvalidSyntaxException("Malformed IKE Payload", e);
-            } catch (GeneralSecurityException e) {
-                throw new IkeInternalException(e);
-            }
-        }
-
-        private void validateFragmentHeader(
-                IkeHeader fragIkeHeader, int packetLen, DecodeResultPartial collectedFragments) {
-            try {
-                fragIkeHeader.validateInboundHeader(packetLen);
-            } catch (IkeProtocolException e) {
-                getIkeLog()
-                        .e(
-                                TAG,
-                                "Received an IKE fragment with invalid header. Will be handled when"
-                                        + " reassembly is done.",
-                                e);
-            }
-
-            if (collectedFragments == null) return;
-            if (fragIkeHeader.exchangeType != collectedFragments.ikeHeader.exchangeType) {
-                getIkeLog()
-                        .e(
-                                TAG,
-                                "Received an IKE fragment with different exchange type from"
-                                        + " previously collected fragments. Ignore it.");
-            }
-        }
-
-        private DecodeResultPartial processIkeFragment(
-                IkeHeader header,
-                byte[] inputPacket,
-                IkeSkfPayload skf,
-                int nextPayloadType,
-                @Nullable DecodeResultPartial collectedFragments) {
-            if (collectedFragments == null) {
-                return new DecodeResultPartial(
-                        header, inputPacket, skf, nextPayloadType, collectedFragments);
-            }
-
-            if (skf.totalFragments > collectedFragments.collectedFragsList.length) {
-                getIkeLog()
-                        .i(
-                                TAG,
-                                "Received IKE fragment has larger total fragments number. Discard"
-                                        + " all previously collected fragments");
-                return new DecodeResultPartial(
-                        header, inputPacket, skf, nextPayloadType, null /*collectedFragments*/);
-            }
-
-            if (skf.totalFragments < collectedFragments.collectedFragsList.length) {
-                getIkeLog()
-                        .i(
-                                TAG,
-                                "Received IKE fragment has smaller total fragments number. Discard"
-                                        + " it.");
-                return collectedFragments;
-            }
-
-            if (collectedFragments.collectedFragsList[skf.fragmentNum - 1] != null) {
-                getIkeLog().i(TAG, "Received IKE fragment is a replay.");
-                return collectedFragments;
-            }
-
-            return new DecodeResultPartial(
-                    header, inputPacket, skf, nextPayloadType, collectedFragments);
-        }
-    }
-
-    /** Status to describe the result of decoding an inbound IKE message. */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        DECODE_STATUS_OK,
-        DECODE_STATUS_PARTIAL,
-        DECODE_STATUS_PROTECTED_ERROR,
-        DECODE_STATUS_UNPROTECTED_ERROR,
-    })
-    public @interface DecodeStatus {}
-
-    /**
-     * Represents a message that has been successfully (decrypted and) decoded or reassembled from
-     * IKE fragments
-     */
-    public static final int DECODE_STATUS_OK = 0;
-    /** Represents that reassembly process of IKE fragments has started but has not finished */
-    public static final int DECODE_STATUS_PARTIAL = 1;
-    /** Represents a crypto protected message with correct message ID but has parsing error. */
-    public static final int DECODE_STATUS_PROTECTED_ERROR = 2;
-    /**
-     * Represents an unencrypted message with parsing error, an encrypted message with
-     * authentication or decryption error, or any message with wrong message ID.
-     */
-    public static final int DECODE_STATUS_UNPROTECTED_ERROR = 3;
-
-    /** This class represents common decoding result of an IKE message. */
-    public abstract static class DecodeResult {
-        public final int status;
-
-        /** Construct an instance of DecodeResult. */
-        protected DecodeResult(int status) {
-            this.status = status;
-        }
-    }
-
-    /** This class represents an IKE message has been successfully (decrypted and) decoded. */
-    public static class DecodeResultOk extends DecodeResult {
-        public final IkeMessage ikeMessage;
-        public final byte[] firstPacket;
-
-        public DecodeResultOk(IkeMessage ikeMessage, byte[] firstPacket) {
-            super(DECODE_STATUS_OK);
-            this.ikeMessage = ikeMessage;
-            this.firstPacket = firstPacket;
-        }
-    }
-
-    /**
-     * This class represents IKE fragments are being reassembled to build a complete IKE message.
-     *
-     * <p>All IKE fragments should have the same IKE headers, except for the message length. This
-     * class only stores the IKE header of the first arrived IKE fragment to represent the IKE
-     * header of the complete IKE message. In this way we can verify all subsequent fragments'
-     * headers against it.
-     *
-     * <p>The first payload type is only stored in the first fragment, as indicated in RFC 7383. So
-     * this class only stores the next payload type field taken from the first fragment.
-     */
-    public static class DecodeResultPartial extends DecodeResult {
-        public final int firstPayloadType;
-        public final byte[] firstFragBytes;
-        public final IkeHeader ikeHeader;
-        public final byte[][] collectedFragsList;
-
-        /**
-         * Construct an instance of DecodeResultPartial with collected fragments and the newly
-         * received fragment.
-         *
-         * <p>The newly received fragment has been validated against collected fragments during
-         * decoding that all fragments have the same total fragments number and the newly received
-         * fragment is not a replay.
-         */
-        public DecodeResultPartial(
-                IkeHeader ikeHeader,
-                byte[] inputPacket,
-                IkeSkfPayload skfPayload,
-                int nextPayloadType,
-                @Nullable DecodeResultPartial collectedFragments) {
-            super(DECODE_STATUS_PARTIAL);
-
-            boolean isFirstFragment = 1 == skfPayload.fragmentNum;
-            if (collectedFragments == null) {
-                // First arrived IKE fragment
-                this.ikeHeader = ikeHeader;
-                this.firstPayloadType =
-                        isFirstFragment ? nextPayloadType : IkePayload.PAYLOAD_TYPE_NO_NEXT;
-                this.firstFragBytes = isFirstFragment ? inputPacket : null;
-                this.collectedFragsList = new byte[skfPayload.totalFragments][];
-            } else {
-                this.ikeHeader = collectedFragments.ikeHeader;
-                this.firstPayloadType =
-                        isFirstFragment ? nextPayloadType : collectedFragments.firstPayloadType;
-                this.firstFragBytes =
-                        isFirstFragment ? inputPacket : collectedFragments.firstFragBytes;
-                this.collectedFragsList = collectedFragments.collectedFragsList;
-            }
-
-            this.collectedFragsList[skfPayload.fragmentNum - 1] = skfPayload.getUnencryptedData();
-        }
-
-        /** Return if all IKE fragments have been collected */
-        public boolean isAllFragmentsReceived() {
-            for (byte[] frag : collectedFragsList) {
-                if (frag == null) return false;
-            }
-            return true;
-        }
-
-        /** Reassemble all IKE fragments and return the unencrypted message body in byte array. */
-        public byte[] reassembleAllFrags() {
-            if (!isAllFragmentsReceived()) {
-                throw new IllegalStateException("Not all fragments have been received");
-            }
-
-            int len = 0;
-            for (byte[] frag : collectedFragsList) {
-                len += frag.length;
-            }
-
-            ByteBuffer buffer = ByteBuffer.allocate(len);
-            for (byte[] frag : collectedFragsList) {
-                buffer.put(frag);
-            }
-
-            return buffer.array();
-        }
-    }
-
-    /**
-     * This class represents common information of error cases in decrypting and decoding message.
-     */
-    public abstract static class DecodeResultError extends DecodeResult {
-        public final IkeException ikeException;
-
-        protected DecodeResultError(int status, IkeException ikeException) {
-            super(status);
-            this.ikeException = ikeException;
-        }
-    }
-    /**
-     * This class represents that decoding errors have been found after the IKE message is
-     * authenticated and decrypted.
-     */
-    public static class DecodeResultProtectedError extends DecodeResultError {
-        public final byte[] firstPacket;
-
-        public DecodeResultProtectedError(IkeException ikeException, byte[] firstPacket) {
-            super(DECODE_STATUS_PROTECTED_ERROR, ikeException);
-            this.firstPacket = firstPacket;
-        }
-    }
-    /** This class represents errors have been found during message authentication or decryption. */
-    public static class DecodeResultUnprotectedError extends DecodeResultError {
-        public DecodeResultUnprotectedError(IkeException ikeException) {
-            super(DECODE_STATUS_UNPROTECTED_ERROR, ikeException);
-        }
-    }
-
-    /**
-     * For setting mocked IIkeMessageHelper for testing
-     *
-     * @param helper the mocked IIkeMessageHelper
-     */
-    public static void setIkeMessageHelper(IIkeMessageHelper helper) {
-        sIkeMessageHelper = helper;
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayload.java
deleted file mode 100644
index ce9529e..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayload.java
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_IKE_SPI;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_MAJOR_VERSION;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_MESSAGE_ID;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SELECTORS;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
-
-import android.annotation.IntDef;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.util.ArraySet;
-import android.util.SparseArray;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidKeException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidMajorVersionException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidMessageIdException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.exceptions.TemporaryFailureException;
-import com.android.internal.net.ipsec.ike.exceptions.TsUnacceptableException;
-import com.android.internal.net.ipsec.ike.exceptions.UnrecognizedIkeProtocolException;
-import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.security.ProviderException;
-import java.util.Set;
-
-/**
- * IkeNotifyPayload represents a Notify Payload.
- *
- * <p>As instructed by RFC 7296, for IKE SA concerned Notify Payload, Protocol ID and SPI Size must
- * be zero. Unrecognized notify message type must be ignored but should be logged.
- *
- * <p>Notification types that smaller or equal than ERROR_NOTIFY_TYPE_MAX are error types. The rest
- * of them are status types.
- *
- * <p>Critical bit for this payload must be ignored in received packet and must not be set in
- * outbound packet.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296">RFC 7296, Internet Key Exchange Protocol
- *     Version 2 (IKEv2)</a>
- */
-public final class IkeNotifyPayload extends IkeInformationalPayload {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef({
-        NOTIFY_TYPE_ADDITIONAL_TS_POSSIBLE,
-        NOTIFY_TYPE_IPCOMP_SUPPORTED,
-        NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP,
-        NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP,
-        NOTIFY_TYPE_USE_TRANSPORT_MODE,
-        NOTIFY_TYPE_REKEY_SA,
-        NOTIFY_TYPE_ESP_TFC_PADDING_NOT_SUPPORTED
-    })
-    public @interface NotifyType {}
-
-    /**
-     * Indicates that the responder has narrowed the proposed Traffic Selectors but other Traffic
-     * Selectors would also have been acceptable. Only allowed in the response for negotiating a
-     * Child SA.
-     */
-    public static final int NOTIFY_TYPE_ADDITIONAL_TS_POSSIBLE = 16386;
-    /**
-     * Indicates a willingness by its sender to use IPComp on this Child SA. Only allowed in the
-     * request/response for negotiating a Child SA.
-     */
-    public static final int NOTIFY_TYPE_IPCOMP_SUPPORTED = 16387;
-    /**
-     * Used for detecting if the IKE initiator is behind a NAT. Only allowed in the request/response
-     * of IKE_SA_INIT exchange.
-     */
-    public static final int NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP = 16388;
-    /**
-     * Used for detecting if the IKE responder is behind a NAT. Only allowed in the request/response
-     * of IKE_SA_INIT exchange.
-     */
-    public static final int NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP = 16389;
-    /**
-     * Indicates a willingness by its sender to use transport mode rather than tunnel mode on this
-     * Child SA. Only allowed in the request/response for negotiating a Child SA.
-     */
-    public static final int NOTIFY_TYPE_USE_TRANSPORT_MODE = 16391;
-    /**
-     * Used for rekeying a Child SA or an IKE SA. Only allowed in the request/response of
-     * CREATE_CHILD_SA exchange.
-     */
-    public static final int NOTIFY_TYPE_REKEY_SA = 16393;
-    /**
-     * Indicates that the sender will not accept packets that contain TFC padding over the Child SA
-     * being negotiated. Only allowed in the request/response for negotiating a Child SA.
-     */
-    public static final int NOTIFY_TYPE_ESP_TFC_PADDING_NOT_SUPPORTED = 16394;
-    /** Indicates that the sender supports IKE fragmentation. */
-    public static final int NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED = 16430;
-
-    private static final int NOTIFY_HEADER_LEN = 4;
-    private static final int ERROR_NOTIFY_TYPE_MAX = 16383;
-
-    private static final String NAT_DETECTION_DIGEST_ALGORITHM = "SHA-1";
-
-    private static final Set<Integer> VALID_NOTIFY_TYPES_FOR_EXISTING_CHILD_SA;
-    private static final Set<Integer> VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA;
-
-    private static final SparseArray<String> NOTIFY_TYPE_TO_STRING;
-
-    static {
-        VALID_NOTIFY_TYPES_FOR_EXISTING_CHILD_SA = new ArraySet<>();
-        VALID_NOTIFY_TYPES_FOR_EXISTING_CHILD_SA.add(ERROR_TYPE_INVALID_SELECTORS);
-        VALID_NOTIFY_TYPES_FOR_EXISTING_CHILD_SA.add(ERROR_TYPE_CHILD_SA_NOT_FOUND);
-        VALID_NOTIFY_TYPES_FOR_EXISTING_CHILD_SA.add(NOTIFY_TYPE_REKEY_SA);
-    }
-
-    static {
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA = new ArraySet<>();
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(
-                IkeProtocolException.ERROR_TYPE_SINGLE_PAIR_REQUIRED);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(
-                IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(IkeProtocolException.ERROR_TYPE_FAILED_CP_REQUIRED);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(IkeProtocolException.ERROR_TYPE_TS_UNACCEPTABLE);
-
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(NOTIFY_TYPE_ADDITIONAL_TS_POSSIBLE);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(NOTIFY_TYPE_IPCOMP_SUPPORTED);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(NOTIFY_TYPE_USE_TRANSPORT_MODE);
-        VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.add(NOTIFY_TYPE_ESP_TFC_PADDING_NOT_SUPPORTED);
-    }
-
-    static {
-        NOTIFY_TYPE_TO_STRING = new SparseArray<>();
-        NOTIFY_TYPE_TO_STRING.put(
-                ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, "Unsupported critical payload");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INVALID_IKE_SPI, "Invalid IKE SPI");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INVALID_MAJOR_VERSION, "Invalid major version");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INVALID_SYNTAX, "Invalid syntax");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INVALID_MESSAGE_ID, "Invalid message ID");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_NO_PROPOSAL_CHOSEN, "No proposal chosen");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INVALID_KE_PAYLOAD, "Invalid KE payload");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_AUTHENTICATION_FAILED, "Authentication failed");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_SINGLE_PAIR_REQUIRED, "Single pair required");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_NO_ADDITIONAL_SAS, "No additional SAs");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, "Internal address failure");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_FAILED_CP_REQUIRED, "Failed CP required");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_TS_UNACCEPTABLE, "TS unacceptable");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_INVALID_SELECTORS, "Invalid selectors");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_TEMPORARY_FAILURE, "Temporary failure");
-        NOTIFY_TYPE_TO_STRING.put(ERROR_TYPE_CHILD_SA_NOT_FOUND, "Child SA not found");
-
-        NOTIFY_TYPE_TO_STRING.put(NOTIFY_TYPE_ADDITIONAL_TS_POSSIBLE, "Additional TS possible");
-        NOTIFY_TYPE_TO_STRING.put(NOTIFY_TYPE_IPCOMP_SUPPORTED, "IPCOMP supported");
-        NOTIFY_TYPE_TO_STRING.put(NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP, "NAT detection source IP");
-        NOTIFY_TYPE_TO_STRING.put(
-                NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP, "NAT detection destination IP");
-        NOTIFY_TYPE_TO_STRING.put(NOTIFY_TYPE_USE_TRANSPORT_MODE, "Use transport mode");
-        NOTIFY_TYPE_TO_STRING.put(NOTIFY_TYPE_REKEY_SA, "Rekey SA");
-        NOTIFY_TYPE_TO_STRING.put(
-                NOTIFY_TYPE_ESP_TFC_PADDING_NOT_SUPPORTED, "ESP TCP Padding not supported");
-        NOTIFY_TYPE_TO_STRING.put(
-                NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED, "Fragmentation supported");
-    }
-
-    public final int protocolId;
-    public final byte spiSize;
-    public final int notifyType;
-    public final int spi;
-    public final byte[] notifyData;
-
-    /**
-     * Construct an instance of IkeNotifyPayload in the context of IkePayloadFactory
-     *
-     * @param critical indicates if this payload is critical. Ignored in supported payload as
-     *     instructed by the RFC 7296.
-     * @param payloadBody payload body in byte array
-     * @throws IkeProtocolException if there is any error
-     */
-    IkeNotifyPayload(boolean isCritical, byte[] payloadBody) throws IkeProtocolException {
-        super(PAYLOAD_TYPE_NOTIFY, isCritical);
-
-        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
-
-        protocolId = Byte.toUnsignedInt(inputBuffer.get());
-        spiSize = inputBuffer.get();
-        notifyType = Short.toUnsignedInt(inputBuffer.getShort());
-
-        // Validate syntax of spiSize, protocolId and notifyType.
-        // Reference: <https://tools.ietf.org/html/rfc7296#page-100>
-        if (spiSize == SPI_LEN_IPSEC) {
-            // For message concerning existing Child SA
-            validateNotifyPayloadForExistingChildSa();
-            spi = inputBuffer.getInt();
-
-        } else if (spiSize == SPI_LEN_NOT_INCLUDED) {
-            // For message concerning IKE SA or for new Child SA that to be negotiated.
-            validateNotifyPayloadForIkeAndNewChild();
-            spi = SPI_NOT_INCLUDED;
-
-        } else {
-            throw new InvalidSyntaxException("Invalid SPI Size: " + spiSize);
-        }
-
-        notifyData = new byte[payloadBody.length - NOTIFY_HEADER_LEN - spiSize];
-        inputBuffer.get(notifyData);
-    }
-
-    private void validateNotifyPayloadForExistingChildSa() throws InvalidSyntaxException {
-        if (protocolId != PROTOCOL_ID_AH && protocolId != PROTOCOL_ID_ESP) {
-            throw new InvalidSyntaxException(
-                    "Expected Procotol ID AH(2) or ESP(3): Protocol ID is " + protocolId);
-        }
-
-        if (!VALID_NOTIFY_TYPES_FOR_EXISTING_CHILD_SA.contains(notifyType)) {
-            throw new InvalidSyntaxException(
-                    "Expected Notify Type for existing Child SA: Notify Type is " + notifyType);
-        }
-    }
-
-    private void validateNotifyPayloadForIkeAndNewChild() throws InvalidSyntaxException {
-        if (protocolId != PROTOCOL_ID_UNSET) {
-            throw new InvalidSyntaxException(
-                    "Expected Procotol ID unset: Protocol ID is " + protocolId);
-        }
-
-        if (notifyType == ERROR_TYPE_INVALID_SELECTORS
-                || notifyType == ERROR_TYPE_CHILD_SA_NOT_FOUND) {
-            throw new InvalidSyntaxException(
-                    "Expected Notify Type concerning IKE SA or new Child SA under negotiation"
-                            + ": Notify Type is "
-                            + notifyType);
-        }
-    }
-
-    /**
-     * Generate NAT DETECTION notification data.
-     *
-     * <p>This method calculates NAT DETECTION notification data which is a SHA-1 digest of the IKE
-     * initiator's SPI, IKE responder's SPI, IP address and port. Source address and port should be
-     * used for generating NAT_DETECTION_SOURCE_IP data. Destination address and port should be used
-     * for generating NAT_DETECTION_DESTINATION_IP data. Here "source" and "destination" mean the
-     * direction of this IKE message.
-     *
-     * @param initiatorIkeSpi the SPI of IKE initiator
-     * @param responderIkeSpi the SPI of IKE responder
-     * @param ipAddress the IP address
-     * @param port the port
-     * @return the generated NAT DETECTION notification data as a byte array.
-     */
-    public static byte[] generateNatDetectionData(
-            long initiatorIkeSpi, long responderIkeSpi, InetAddress ipAddress, int port) {
-        byte[] rawIpAddr = ipAddress.getAddress();
-
-        ByteBuffer byteBuffer =
-                ByteBuffer.allocate(2 * SPI_LEN_IKE + rawIpAddr.length + IP_PORT_LEN);
-        byteBuffer
-                .putLong(initiatorIkeSpi)
-                .putLong(responderIkeSpi)
-                .put(rawIpAddr)
-                .putShort((short) port);
-
-        try {
-            MessageDigest natDetectionDataDigest =
-                    MessageDigest.getInstance(
-                            NAT_DETECTION_DIGEST_ALGORITHM, IkeMessage.getSecurityProvider());
-            return natDetectionDataDigest.digest(byteBuffer.array());
-        } catch (NoSuchAlgorithmException e) {
-            throw new ProviderException(
-                    "Failed to obtain algorithm :" + NAT_DETECTION_DIGEST_ALGORITHM, e);
-        }
-    }
-
-    /**
-     * Encode Notify payload to ByteBuffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer.put((byte) protocolId).put(spiSize).putShort((short) notifyType);
-        if (spiSize == SPI_LEN_IPSEC) {
-            byteBuffer.putInt(spi);
-        }
-        byteBuffer.put(notifyData);
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        return GENERIC_HEADER_LENGTH + NOTIFY_HEADER_LEN + spiSize + notifyData.length;
-    }
-
-    protected IkeNotifyPayload(
-            @ProtocolId int protocolId, byte spiSize, int spi, int notifyType, byte[] notifyData) {
-        super(PAYLOAD_TYPE_NOTIFY, false);
-        this.protocolId = protocolId;
-        this.spiSize = spiSize;
-        this.spi = spi;
-        this.notifyType = notifyType;
-        this.notifyData = notifyData;
-    }
-
-    /**
-     * Construct IkeNotifyPayload concerning either an IKE SA, or Child SA that is going to be
-     * negotiated with associated notification data.
-     *
-     * @param notifyType the notify type concerning IKE SA
-     * @param notifytData status or error data transmitted. Values for this field are notify type
-     *     specific.
-     */
-    public IkeNotifyPayload(int notifyType, byte[] notifyData) {
-        this(PROTOCOL_ID_UNSET, SPI_LEN_NOT_INCLUDED, SPI_NOT_INCLUDED, notifyType, notifyData);
-        try {
-            validateNotifyPayloadForIkeAndNewChild();
-        } catch (InvalidSyntaxException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    /**
-     * Construct IkeNotifyPayload concerning either an IKE SA, or Child SA that is going to be
-     * negotiated without additional notification data.
-     *
-     * @param notifyType the notify type concerning IKE SA
-     */
-    public IkeNotifyPayload(int notifyType) {
-        this(notifyType, new byte[0]);
-    }
-
-    /**
-     * Construct IkeNotifyPayload concerning existing Child SA
-     *
-     * @param notifyType the notify type concerning Child SA
-     * @param notifytData status or error data transmitted. Values for this field are notify type
-     *     specific.
-     */
-    public IkeNotifyPayload(
-            @ProtocolId int protocolId, int spi, int notifyType, byte[] notifyData) {
-        this(protocolId, SPI_LEN_IPSEC, spi, notifyType, notifyData);
-        try {
-            validateNotifyPayloadForExistingChildSa();
-        } catch (InvalidSyntaxException e) {
-            throw new IllegalArgumentException(e);
-        }
-    }
-
-    /**
-     * Indicates if this is an error notification payload.
-     *
-     * @return if this is an error notification payload.
-     */
-    public boolean isErrorNotify() {
-        return notifyType <= ERROR_NOTIFY_TYPE_MAX;
-    }
-
-    /**
-     * Indicates if this is an notification for a new Child SA negotiation.
-     *
-     * <p>This notification may provide additional configuration information for negotiating a new
-     * Child SA or is an error notification of the Child SA negotiation failure.
-     *
-     * @return if this is an notification for a new Child SA negotiation.
-     */
-    public boolean isNewChildSaNotify() {
-        return VALID_NOTIFY_TYPES_FOR_NEW_CHILD_SA.contains(notifyType);
-    }
-
-    /**
-     * Validate error data and build IkeProtocolException for this error notification.
-     *
-     * @return the IkeProtocolException that represents this error.
-     * @throws InvalidSyntaxException if error data has invalid size.
-     */
-    public IkeProtocolException validateAndBuildIkeException() throws InvalidSyntaxException {
-        if (!isErrorNotify()) {
-            throw new IllegalArgumentException(
-                    "Do not support building IkeException for a non-error notificaton. Notify"
-                            + " type: "
-                            + notifyType);
-        }
-
-        try {
-            switch (notifyType) {
-                case ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD:
-                    return new UnsupportedCriticalPayloadException(notifyData);
-                case ERROR_TYPE_INVALID_MAJOR_VERSION:
-                    return new InvalidMajorVersionException(notifyData);
-                case ERROR_TYPE_INVALID_SYNTAX:
-                    return new InvalidSyntaxException(notifyData);
-                case ERROR_TYPE_INVALID_MESSAGE_ID:
-                    return new InvalidMessageIdException(notifyData);
-                case ERROR_TYPE_NO_PROPOSAL_CHOSEN:
-                    return new NoValidProposalChosenException(notifyData);
-                case ERROR_TYPE_INVALID_KE_PAYLOAD:
-                    return new InvalidKeException(notifyData);
-                case ERROR_TYPE_AUTHENTICATION_FAILED:
-                    return new AuthenticationFailedException(notifyData);
-                case ERROR_TYPE_TS_UNACCEPTABLE:
-                    return new TsUnacceptableException(notifyData);
-                case ERROR_TYPE_TEMPORARY_FAILURE:
-                    return new TemporaryFailureException(notifyData);
-                default:
-                    return new UnrecognizedIkeProtocolException(notifyType, notifyData);
-            }
-        } catch (IllegalArgumentException e) {
-            // Notification data length is invalid.
-            throw new InvalidSyntaxException(e);
-        }
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        String notifyTypeString = NOTIFY_TYPE_TO_STRING.get(notifyType);
-
-        if (notifyTypeString == null) {
-            return "Notify(" + notifyType + ")";
-        }
-        return "Notify(" + notifyTypeString + ")";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
deleted file mode 100644
index 3cce625..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayload.java
+++ /dev/null
@@ -1,1773 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static android.net.ipsec.ike.IkeManager.getIkeLog;
-import static android.net.ipsec.ike.SaProposal.DhGroup;
-import static android.net.ipsec.ike.SaProposal.EncryptionAlgorithm;
-import static android.net.ipsec.ike.SaProposal.IntegrityAlgorithm;
-import static android.net.ipsec.ike.SaProposal.PseudorandomFunction;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.net.IpSecManager;
-import android.net.IpSecManager.ResourceUnavailableException;
-import android.net.IpSecManager.SecurityParameterIndex;
-import android.net.IpSecManager.SpiUnavailableException;
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.IkeSaProposal;
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.util.ArraySet;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-
-/**
- * IkeSaPayload represents a Security Association payload. It contains one or more {@link Proposal}.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeSaPayload extends IkePayload {
-    private static final String TAG = "IkeSaPayload";
-
-    public final boolean isSaResponse;
-    public final List<Proposal> proposalList;
-    /**
-     * Construct an instance of IkeSaPayload for decoding an inbound packet.
-     *
-     * @param critical indicates if this payload is critical. Ignored in supported payload as
-     *     instructed by the RFC 7296.
-     * @param isResp indicates if this payload is in a response message.
-     * @param payloadBody the encoded payload body in byte array.
-     */
-    IkeSaPayload(boolean critical, boolean isResp, byte[] payloadBody) throws IkeProtocolException {
-        super(IkePayload.PAYLOAD_TYPE_SA, critical);
-
-        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
-        proposalList = new LinkedList<>();
-        while (inputBuffer.hasRemaining()) {
-            Proposal proposal = Proposal.readFrom(inputBuffer);
-            proposalList.add(proposal);
-        }
-
-        if (proposalList.isEmpty()) {
-            throw new InvalidSyntaxException("Found no SA Proposal in this SA Payload.");
-        }
-
-        // An SA response must have exactly one SA proposal.
-        if (isResp && proposalList.size() != 1) {
-            throw new InvalidSyntaxException(
-                    "Expected only one negotiated proposal from SA response: "
-                            + "Multiple negotiated proposals found.");
-        }
-        isSaResponse = isResp;
-
-        boolean firstIsIkeProposal = (proposalList.get(0).protocolId == PROTOCOL_ID_IKE);
-        for (int i = 1; i < proposalList.size(); i++) {
-            boolean isIkeProposal = (proposalList.get(i).protocolId == PROTOCOL_ID_IKE);
-            if (firstIsIkeProposal != isIkeProposal) {
-                getIkeLog()
-                        .w(TAG, "Found both IKE proposals and Child proposals in this SA Payload.");
-                break;
-            }
-        }
-
-        getIkeLog().d(TAG, "Receive " + toString());
-    }
-
-    /** Package private constructor for building a request for IKE SA initial creation or rekey */
-    @VisibleForTesting
-    IkeSaPayload(
-            boolean isResp, byte spiSize, IkeSaProposal[] saProposals, InetAddress localAddress)
-            throws IOException {
-        this(isResp, spiSize, localAddress);
-
-        if (saProposals.length < 1 || isResp && (saProposals.length > 1)) {
-            throw new IllegalArgumentException("Invalid SA payload.");
-        }
-
-        for (int i = 0; i < saProposals.length; i++) {
-            // Proposal number must start from 1.
-            proposalList.add(
-                    IkeProposal.createIkeProposal(
-                            (byte) (i + 1) /*number*/, spiSize, saProposals[i], localAddress));
-        }
-
-        getIkeLog().d(TAG, "Generate " + toString());
-    }
-
-    /** Package private constructor for building an response SA Payload for IKE SA rekeys. */
-    @VisibleForTesting
-    IkeSaPayload(
-            boolean isResp,
-            byte spiSize,
-            byte proposalNumber,
-            IkeSaProposal saProposal,
-            InetAddress localAddress)
-            throws IOException {
-        this(isResp, spiSize, localAddress);
-
-        proposalList.add(
-                IkeProposal.createIkeProposal(
-                        proposalNumber /*number*/, spiSize, saProposal, localAddress));
-
-        getIkeLog().d(TAG, "Generate " + toString());
-    }
-
-    private IkeSaPayload(boolean isResp, byte spiSize, InetAddress localAddress)
-            throws IOException {
-        super(IkePayload.PAYLOAD_TYPE_SA, false);
-
-        // TODO: Check that proposals.length <= 255 in IkeSessionOptions and ChildSessionOptions
-        isSaResponse = isResp;
-
-        // TODO: Allocate IKE SPI and pass to IkeProposal.createIkeProposal()
-
-        // ProposalList populated in other constructors
-        proposalList = new ArrayList<Proposal>();
-    }
-
-    /**
-     * Package private constructor for building an outbound request SA Payload for Child SA
-     * negotiation.
-     */
-    @VisibleForTesting
-    IkeSaPayload(ChildSaProposal[] saProposals, IpSecManager ipSecManager, InetAddress localAddress)
-            throws ResourceUnavailableException {
-        this(false /*isResp*/, ipSecManager, localAddress);
-
-        if (saProposals.length < 1) {
-            throw new IllegalArgumentException("Invalid SA payload.");
-        }
-
-        // TODO: Check that saProposals.length <= 255 in IkeSessionOptions and ChildSessionOptions
-
-        for (int i = 0; i < saProposals.length; i++) {
-            // Proposal number must start from 1.
-            proposalList.add(
-                    ChildProposal.createChildProposal(
-                            (byte) (i + 1) /*number*/, saProposals[i], ipSecManager, localAddress));
-        }
-
-        getIkeLog().d(TAG, "Generate " + toString());
-    }
-
-    /**
-     * Package private constructor for building an outbound response SA Payload for Child SA
-     * negotiation.
-     */
-    @VisibleForTesting
-    IkeSaPayload(
-            byte proposalNumber,
-            ChildSaProposal saProposal,
-            IpSecManager ipSecManager,
-            InetAddress localAddress)
-            throws ResourceUnavailableException {
-        this(true /*isResp*/, ipSecManager, localAddress);
-
-        proposalList.add(
-                ChildProposal.createChildProposal(
-                        proposalNumber /*number*/, saProposal, ipSecManager, localAddress));
-
-        getIkeLog().d(TAG, "Generate " + toString());
-    }
-
-    /** Constructor for building an outbound SA Payload for Child SA negotiation. */
-    private IkeSaPayload(boolean isResp, IpSecManager ipSecManager, InetAddress localAddress) {
-        super(IkePayload.PAYLOAD_TYPE_SA, false);
-
-        isSaResponse = isResp;
-
-        // TODO: Allocate Child SPI and pass to ChildProposal.createChildProposal()
-
-        // ProposalList populated in other constructors
-        proposalList = new ArrayList<Proposal>();
-    }
-
-    /**
-     * Construct an instance of IkeSaPayload for building an outbound IKE initial setup request.
-     *
-     * <p>According to RFC 7296, for an initial IKE SA negotiation, no SPI is included in SA
-     * Proposal. IKE library, as a client, only supports requesting this initial negotiation.
-     *
-     * @param saProposals the array of all SA Proposals.
-     */
-    public static IkeSaPayload createInitialIkeSaPayload(IkeSaProposal[] saProposals)
-            throws IOException {
-        return new IkeSaPayload(false /*isResp*/, SPI_LEN_NOT_INCLUDED, saProposals, null);
-    }
-
-    /**
-     * Construct an instance of IkeSaPayload for building an outbound request for Rekey IKE.
-     *
-     * @param saProposals the array of all IKE SA Proposals.
-     * @param localAddress the local address assigned on-device.
-     */
-    public static IkeSaPayload createRekeyIkeSaRequestPayload(
-            IkeSaProposal[] saProposals, InetAddress localAddress) throws IOException {
-        return new IkeSaPayload(false /*isResp*/, SPI_LEN_IKE, saProposals, localAddress);
-    }
-
-    /**
-     * Construct an instance of IkeSaPayload for building an outbound response for Rekey IKE.
-     *
-     * @param respProposalNumber the selected proposal's number.
-     * @param saProposal the expected selected IKE SA Proposal.
-     * @param localAddress the local address assigned on-device.
-     */
-    public static IkeSaPayload createRekeyIkeSaResponsePayload(
-            byte respProposalNumber, IkeSaProposal saProposal, InetAddress localAddress)
-            throws IOException {
-        return new IkeSaPayload(
-                true /*isResp*/, SPI_LEN_IKE, respProposalNumber, saProposal, localAddress);
-    }
-
-    /**
-     * Construct an instance of IkeSaPayload for building an outbound request for Child SA
-     * negotiation.
-     *
-     * @param saProposals the array of all Child SA Proposals.
-     * @param ipSecManager the IpSecManager for generating IPsec SPIs.
-     * @param localAddress the local address assigned on-device.
-     * @throws ResourceUnavailableException if too many SPIs are currently allocated for this user.
-     */
-    public static IkeSaPayload createChildSaRequestPayload(
-            ChildSaProposal[] saProposals, IpSecManager ipSecManager, InetAddress localAddress)
-            throws ResourceUnavailableException {
-
-        return new IkeSaPayload(saProposals, ipSecManager, localAddress);
-    }
-
-    /**
-     * Construct an instance of IkeSaPayload for building an outbound response for Child SA
-     * negotiation.
-     *
-     * @param respProposalNumber the selected proposal's number.
-     * @param saProposal the expected selected Child SA Proposal.
-     * @param ipSecManager the IpSecManager for generating IPsec SPIs.
-     * @param localAddress the local address assigned on-device.
-     */
-    public static IkeSaPayload createChildSaResponsePayload(
-            byte respProposalNumber,
-            ChildSaProposal saProposal,
-            IpSecManager ipSecManager,
-            InetAddress localAddress)
-            throws ResourceUnavailableException {
-        return new IkeSaPayload(respProposalNumber, saProposal, ipSecManager, localAddress);
-    }
-
-    /**
-     * Finds the proposal in this (request) payload that matches the response proposal.
-     *
-     * @param respProposal the Proposal to match against.
-     * @return the byte-value proposal number of the selected proposal
-     * @throws NoValidProposalChosenException if no matching proposal was found.
-     */
-    public byte getNegotiatedProposalNumber(SaProposal respProposal)
-            throws NoValidProposalChosenException {
-        for (int i = 0; i < proposalList.size(); i++) {
-            Proposal reqProposal = proposalList.get(i);
-            if (respProposal.isNegotiatedFrom(reqProposal.getSaProposal())
-                    && reqProposal.getSaProposal().getProtocolId()
-                            == respProposal.getProtocolId()) {
-                return reqProposal.number;
-            }
-        }
-        throw new NoValidProposalChosenException("No remotely proposed protocol acceptable");
-    }
-
-    /**
-     * Validate the IKE SA Payload pair (request/response) and return the IKE SA negotiation result.
-     *
-     * <p>Caller is able to extract the negotiated IKE SA Proposal from the response Proposal and
-     * the IKE SPI pair generated by both sides.
-     *
-     * <p>In a locally-initiated case all IKE SA proposals (from users in initial creation or from
-     * previously negotiated proposal in rekey creation) in the locally generated reqSaPayload have
-     * been validated during building and are unmodified. All Transform combinations in these SA
-     * proposals are valid for IKE SA negotiation. It means each IKE SA request proposal MUST have
-     * Encryption algorithms, DH group configurations and PRFs. Integrity algorithms can only be
-     * omitted when AEAD is used.
-     *
-     * <p>In a remotely-initiated case the locally generated respSaPayload has exactly one SA
-     * proposal. It is validated during building and are unmodified. This proposal has a valid
-     * Transform combination for an IKE SA and has at most one value for each Transform type.
-     *
-     * <p>The response IKE SA proposal is validated against one of the request IKE SA proposals. It
-     * is guaranteed that for each Transform type that the request proposal has provided options,
-     * the response proposal has exact one Transform value.
-     *
-     * @param reqSaPayload the request payload.
-     * @param respSaPayload the response payload.
-     * @param remoteAddress the address of the remote IKE peer.
-     * @return the Pair of selected IkeProposal in request and the IkeProposal in response.
-     * @throws NoValidProposalChosenException if the response SA Payload cannot be negotiated from
-     *     the request SA Payload.
-     */
-    public static Pair<IkeProposal, IkeProposal> getVerifiedNegotiatedIkeProposalPair(
-            IkeSaPayload reqSaPayload, IkeSaPayload respSaPayload, InetAddress remoteAddress)
-            throws NoValidProposalChosenException, IOException {
-        Pair<Proposal, Proposal> proposalPair =
-                getVerifiedNegotiatedProposalPair(reqSaPayload, respSaPayload);
-        IkeProposal reqProposal = (IkeProposal) proposalPair.first;
-        IkeProposal respProposal = (IkeProposal) proposalPair.second;
-
-        try {
-            // Allocate initiator's inbound SPI as needed for remotely initiated IKE SA creation
-            if (reqProposal.spiSize != SPI_NOT_INCLUDED
-                    && reqProposal.getIkeSpiResource() == null) {
-                reqProposal.allocateResourceForRemoteIkeSpi(remoteAddress);
-            }
-            // Allocate responder's inbound SPI as needed for locally initiated IKE SA creation
-            if (respProposal.spiSize != SPI_NOT_INCLUDED
-                    && respProposal.getIkeSpiResource() == null) {
-                respProposal.allocateResourceForRemoteIkeSpi(remoteAddress);
-            }
-
-            return new Pair(reqProposal, respProposal);
-        } catch (Exception e) {
-            reqProposal.releaseSpiResourceIfExists();
-            respProposal.releaseSpiResourceIfExists();
-            throw e;
-        }
-    }
-
-    /**
-     * Validate the SA Payload pair (request/response) and return the Child SA negotiation result.
-     *
-     * <p>Caller is able to extract the negotiated SA Proposal from the response Proposal and the
-     * IPsec SPI pair generated by both sides.
-     *
-     * <p>In a locally-initiated case all Child SA proposals (from users in initial creation or from
-     * previously negotiated proposal in rekey creation) in the locally generated reqSaPayload have
-     * been validated during building and are unmodified. All Transform combinations in these SA
-     * proposals are valid for Child SA negotiation. It means each request SA proposal MUST have
-     * Encryption algorithms and ESN configurations.
-     *
-     * <p>In a remotely-initiated case the locally generated respSapayload has exactly one SA
-     * proposal. It is validated during building and are unmodified. This proposal has a valid
-     * Transform combination for an Child SA and has at most one value for each Transform type.
-     *
-     * <p>The response Child SA proposal is validated against one of the request SA proposals. It is
-     * guaranteed that for each Transform type that the request proposal has provided options, the
-     * response proposal has exact one Transform value.
-     *
-     * @param reqSaPayload the request payload.
-     * @param respSaPayload the response payload.
-     * @param ipSecManager the IpSecManager to allocate SPI resource for the Proposal in this
-     *     inbound SA Payload.
-     * @param remoteAddress the address of the remote IKE peer.
-     * @return the Pair of selected ChildProposal in the locally generated request and the
-     *     ChildProposal in this response.
-     * @throws NoValidProposalChosenException if the response SA Payload cannot be negotiated from
-     *     the request SA Payload.
-     * @throws ResourceUnavailableException if too many SPIs are currently allocated for this user.
-     * @throws SpiUnavailableException if the remotely generated SPI is in use.
-     */
-    public static Pair<ChildProposal, ChildProposal> getVerifiedNegotiatedChildProposalPair(
-            IkeSaPayload reqSaPayload,
-            IkeSaPayload respSaPayload,
-            IpSecManager ipSecManager,
-            InetAddress remoteAddress)
-            throws NoValidProposalChosenException, ResourceUnavailableException,
-                    SpiUnavailableException {
-        Pair<Proposal, Proposal> proposalPair =
-                getVerifiedNegotiatedProposalPair(reqSaPayload, respSaPayload);
-        ChildProposal reqProposal = (ChildProposal) proposalPair.first;
-        ChildProposal respProposal = (ChildProposal) proposalPair.second;
-
-        try {
-            // Allocate initiator's inbound SPI as needed for remotely initiated Child SA creation
-            if (reqProposal.getChildSpiResource() == null) {
-                reqProposal.allocateResourceForRemoteChildSpi(ipSecManager, remoteAddress);
-            }
-            // Allocate responder's inbound SPI as needed for locally initiated Child SA creation
-            if (respProposal.getChildSpiResource() == null) {
-                respProposal.allocateResourceForRemoteChildSpi(ipSecManager, remoteAddress);
-            }
-
-            return new Pair(reqProposal, respProposal);
-        } catch (Exception e) {
-            reqProposal.releaseSpiResourceIfExists();
-            respProposal.releaseSpiResourceIfExists();
-            throw e;
-        }
-    }
-
-    private static Pair<Proposal, Proposal> getVerifiedNegotiatedProposalPair(
-            IkeSaPayload reqSaPayload, IkeSaPayload respSaPayload)
-            throws NoValidProposalChosenException {
-        try {
-            // If negotiated proposal has an unrecognized Transform, throw an exception.
-            Proposal respProposal = respSaPayload.proposalList.get(0);
-            if (respProposal.hasUnrecognizedTransform) {
-                throw new NoValidProposalChosenException(
-                        "Negotiated proposal has unrecognized Transform.");
-            }
-
-            // In SA request payload, the first proposal MUST be 1, and subsequent proposals MUST be
-            // one more than the previous proposal. In SA response payload, the negotiated proposal
-            // number MUST match the selected proposal number in SA request Payload.
-            int negotiatedProposalNum = respProposal.number;
-            List<Proposal> reqProposalList = reqSaPayload.proposalList;
-            if (negotiatedProposalNum < 1 || negotiatedProposalNum > reqProposalList.size()) {
-                throw new NoValidProposalChosenException(
-                        "Negotiated proposal has invalid proposal number.");
-            }
-
-            Proposal reqProposal = reqProposalList.get(negotiatedProposalNum - 1);
-            if (!respProposal.isNegotiatedFrom(reqProposal)) {
-                throw new NoValidProposalChosenException("Invalid negotiated proposal.");
-            }
-
-            // In a locally-initiated creation, release locally generated SPIs in unselected request
-            // Proposals. In remotely-initiated SA creation, unused proposals do not have SPIs, and
-            // will silently succeed.
-            for (Proposal p : reqProposalList) {
-                if (reqProposal != p) p.releaseSpiResourceIfExists();
-            }
-
-            return new Pair<Proposal, Proposal>(reqProposal, respProposal);
-        } catch (Exception e) {
-            // In a locally-initiated case, release all locally generated SPIs in the SA request
-            // payload.
-            for (Proposal p : reqSaPayload.proposalList) p.releaseSpiResourceIfExists();
-            throw e;
-        }
-    }
-
-    @VisibleForTesting
-    interface TransformDecoder {
-        Transform[] decodeTransforms(int count, ByteBuffer inputBuffer) throws IkeProtocolException;
-    }
-
-    // TODO: Add another constructor for building outbound message.
-
-    /**
-     * This class represents the common information of an IKE Proposal and a Child Proposal.
-     *
-     * <p>Proposal represents a set contains cryptographic algorithms and key generating materials.
-     * It contains multiple {@link Transform}.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.1">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     *     <p>Proposals with an unrecognized Protocol ID, containing an unrecognized Transform Type
-     *     or lacking a necessary Transform Type shall be ignored when processing a received SA
-     *     Payload.
-     */
-    public abstract static class Proposal {
-        private static final byte LAST_PROPOSAL = 0;
-        private static final byte NOT_LAST_PROPOSAL = 2;
-
-        private static final int PROPOSAL_RESERVED_FIELD_LEN = 1;
-        private static final int PROPOSAL_HEADER_LEN = 8;
-
-        @VisibleForTesting
-        static TransformDecoder sTransformDecoder =
-                new TransformDecoder() {
-                    @Override
-                    public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer)
-                            throws IkeProtocolException {
-                        Transform[] transformArray = new Transform[count];
-                        for (int i = 0; i < count; i++) {
-                            Transform transform = Transform.readFrom(inputBuffer);
-                            if (transform.isSupported) {
-                                transformArray[i] = transform;
-                            }
-                        }
-                        return transformArray;
-                    }
-                };
-
-        public final byte number;
-        /** All supported protocol will fall into {@link ProtocolId} */
-        public final int protocolId;
-
-        public final byte spiSize;
-        public final long spi;
-
-        public final boolean hasUnrecognizedTransform;
-
-        @VisibleForTesting
-        Proposal(
-                byte number,
-                int protocolId,
-                byte spiSize,
-                long spi,
-                boolean hasUnrecognizedTransform) {
-            this.number = number;
-            this.protocolId = protocolId;
-            this.spiSize = spiSize;
-            this.spi = spi;
-            this.hasUnrecognizedTransform = hasUnrecognizedTransform;
-        }
-
-        @VisibleForTesting
-        static Proposal readFrom(ByteBuffer inputBuffer) throws IkeProtocolException {
-            byte isLast = inputBuffer.get();
-            if (isLast != LAST_PROPOSAL && isLast != NOT_LAST_PROPOSAL) {
-                throw new InvalidSyntaxException(
-                        "Invalid value of Last Proposal Substructure: " + isLast);
-            }
-            // Skip RESERVED byte
-            inputBuffer.get(new byte[PROPOSAL_RESERVED_FIELD_LEN]);
-
-            int length = Short.toUnsignedInt(inputBuffer.getShort());
-            byte number = inputBuffer.get();
-            int protocolId = Byte.toUnsignedInt(inputBuffer.get());
-
-            byte spiSize = inputBuffer.get();
-            int transformCount = Byte.toUnsignedInt(inputBuffer.get());
-
-            // TODO: Add check: spiSize must be 0 in initial IKE SA negotiation
-            // spiSize should be either 8 for IKE or 4 for IPsec.
-            long spi = SPI_NOT_INCLUDED;
-            switch (spiSize) {
-                case SPI_LEN_NOT_INCLUDED:
-                    // No SPI attached for IKE initial exchange.
-                    break;
-                case SPI_LEN_IPSEC:
-                    spi = Integer.toUnsignedLong(inputBuffer.getInt());
-                    break;
-                case SPI_LEN_IKE:
-                    spi = inputBuffer.getLong();
-                    break;
-                default:
-                    throw new InvalidSyntaxException(
-                            "Invalid value of spiSize in Proposal Substructure: " + spiSize);
-            }
-
-            Transform[] transformArray =
-                    sTransformDecoder.decodeTransforms(transformCount, inputBuffer);
-            // TODO: Validate that sum of all Transforms' lengths plus Proposal header length equals
-            // to Proposal's length.
-
-            List<EncryptionTransform> encryptAlgoList = new LinkedList<>();
-            List<PrfTransform> prfList = new LinkedList<>();
-            List<IntegrityTransform> integAlgoList = new LinkedList<>();
-            List<DhGroupTransform> dhGroupList = new LinkedList<>();
-            List<EsnTransform> esnList = new LinkedList<>();
-
-            boolean hasUnrecognizedTransform = false;
-
-            for (Transform transform : transformArray) {
-                switch (transform.type) {
-                    case Transform.TRANSFORM_TYPE_ENCR:
-                        encryptAlgoList.add((EncryptionTransform) transform);
-                        break;
-                    case Transform.TRANSFORM_TYPE_PRF:
-                        prfList.add((PrfTransform) transform);
-                        break;
-                    case Transform.TRANSFORM_TYPE_INTEG:
-                        integAlgoList.add((IntegrityTransform) transform);
-                        break;
-                    case Transform.TRANSFORM_TYPE_DH:
-                        dhGroupList.add((DhGroupTransform) transform);
-                        break;
-                    case Transform.TRANSFORM_TYPE_ESN:
-                        esnList.add((EsnTransform) transform);
-                        break;
-                    default:
-                        hasUnrecognizedTransform = true;
-                }
-            }
-
-            if (protocolId == PROTOCOL_ID_IKE) {
-                IkeSaProposal saProposal =
-                        new IkeSaProposal(
-                                encryptAlgoList.toArray(
-                                        new EncryptionTransform[encryptAlgoList.size()]),
-                                prfList.toArray(new PrfTransform[prfList.size()]),
-                                integAlgoList.toArray(new IntegrityTransform[integAlgoList.size()]),
-                                dhGroupList.toArray(new DhGroupTransform[dhGroupList.size()]));
-                return new IkeProposal(number, spiSize, spi, saProposal, hasUnrecognizedTransform);
-            } else {
-                ChildSaProposal saProposal =
-                        new ChildSaProposal(
-                                encryptAlgoList.toArray(
-                                        new EncryptionTransform[encryptAlgoList.size()]),
-                                integAlgoList.toArray(new IntegrityTransform[integAlgoList.size()]),
-                                dhGroupList.toArray(new DhGroupTransform[dhGroupList.size()]),
-                                esnList.toArray(new EsnTransform[esnList.size()]));
-                return new ChildProposal(number, spi, saProposal, hasUnrecognizedTransform);
-            }
-        }
-
-        /** Package private */
-        boolean isNegotiatedFrom(Proposal reqProposal) {
-            if (protocolId != reqProposal.protocolId || number != reqProposal.number) {
-                return false;
-            }
-            return getSaProposal().isNegotiatedFrom(reqProposal.getSaProposal());
-        }
-
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            Transform[] allTransforms = getSaProposal().getAllTransforms();
-            byte isLastIndicator = isLast ? LAST_PROPOSAL : NOT_LAST_PROPOSAL;
-
-            byteBuffer
-                    .put(isLastIndicator)
-                    .put(new byte[PROPOSAL_RESERVED_FIELD_LEN])
-                    .putShort((short) getProposalLength())
-                    .put(number)
-                    .put((byte) protocolId)
-                    .put(spiSize)
-                    .put((byte) allTransforms.length);
-
-            switch (spiSize) {
-                case SPI_LEN_NOT_INCLUDED:
-                    // No SPI attached for IKE initial exchange.
-                    break;
-                case SPI_LEN_IPSEC:
-                    byteBuffer.putInt((int) spi);
-                    break;
-                case SPI_LEN_IKE:
-                    byteBuffer.putLong((long) spi);
-                    break;
-                default:
-                    throw new IllegalArgumentException(
-                            "Invalid value of spiSize in Proposal Substructure: " + spiSize);
-            }
-
-            // Encode all Transform.
-            for (int i = 0; i < allTransforms.length; i++) {
-                // The last transform has the isLast flag set to true.
-                allTransforms[i].encodeToByteBuffer(i == allTransforms.length - 1, byteBuffer);
-            }
-        }
-
-        protected int getProposalLength() {
-            int len = PROPOSAL_HEADER_LEN + spiSize;
-
-            Transform[] allTransforms = getSaProposal().getAllTransforms();
-            for (Transform t : allTransforms) len += t.getTransformLength();
-            return len;
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return "Proposal(" + number + ") " + getSaProposal().toString();
-        }
-
-        /** Package private method for releasing SPI resource in this unselected Proposal. */
-        abstract void releaseSpiResourceIfExists();
-
-        /** Package private method for getting SaProposal */
-        abstract SaProposal getSaProposal();
-    }
-
-    /** This class represents a Proposal for IKE SA negotiation. */
-    public static final class IkeProposal extends Proposal {
-        private IkeSecurityParameterIndex mIkeSpiResource;
-
-        public final IkeSaProposal saProposal;
-
-        /**
-         * Construct IkeProposal from a decoded inbound message for IKE negotiation.
-         *
-         * <p>Package private
-         */
-        IkeProposal(
-                byte number,
-                byte spiSize,
-                long spi,
-                IkeSaProposal saProposal,
-                boolean hasUnrecognizedTransform) {
-            super(number, PROTOCOL_ID_IKE, spiSize, spi, hasUnrecognizedTransform);
-            this.saProposal = saProposal;
-        }
-
-        /** Construct IkeProposal for an outbound message for IKE negotiation. */
-        private IkeProposal(
-                byte number,
-                byte spiSize,
-                IkeSecurityParameterIndex ikeSpiResource,
-                IkeSaProposal saProposal) {
-            super(
-                    number,
-                    PROTOCOL_ID_IKE,
-                    spiSize,
-                    ikeSpiResource == null ? SPI_NOT_INCLUDED : ikeSpiResource.getSpi(),
-                    false /*hasUnrecognizedTransform*/);
-            mIkeSpiResource = ikeSpiResource;
-            this.saProposal = saProposal;
-        }
-
-        /**
-         * Construct IkeProposal for an outbound message for IKE negotiation.
-         *
-         * <p>Package private
-         */
-        @VisibleForTesting
-        static IkeProposal createIkeProposal(
-                byte number, byte spiSize, IkeSaProposal saProposal, InetAddress localAddress)
-                throws IOException {
-            // IKE_INIT uses SPI_LEN_NOT_INCLUDED, while rekeys use SPI_LEN_IKE
-            IkeSecurityParameterIndex spiResource =
-                    (spiSize == SPI_LEN_NOT_INCLUDED
-                            ? null
-                            : IkeSecurityParameterIndex.allocateSecurityParameterIndex(
-                                    localAddress));
-            return new IkeProposal(number, spiSize, spiResource, saProposal);
-        }
-
-        /** Package private method for releasing SPI resource in this unselected Proposal. */
-        void releaseSpiResourceIfExists() {
-            // mIkeSpiResource is null when doing IKE initial exchanges.
-            if (mIkeSpiResource == null) return;
-            mIkeSpiResource.close();
-            mIkeSpiResource = null;
-        }
-
-        /**
-         * Package private method for allocating SPI resource for a validated remotely generated IKE
-         * SA proposal.
-         */
-        void allocateResourceForRemoteIkeSpi(InetAddress remoteAddress) throws IOException {
-            mIkeSpiResource =
-                    IkeSecurityParameterIndex.allocateSecurityParameterIndex(remoteAddress, spi);
-        }
-
-        @Override
-        public SaProposal getSaProposal() {
-            return saProposal;
-        }
-
-        /**
-         * Get the IKE SPI resource.
-         *
-         * @return the IKE SPI resource or null for IKE initial exchanges.
-         */
-        public IkeSecurityParameterIndex getIkeSpiResource() {
-            return mIkeSpiResource;
-        }
-    }
-
-    /** This class represents a Proposal for Child SA negotiation. */
-    public static final class ChildProposal extends Proposal {
-        private SecurityParameterIndex mChildSpiResource;
-
-        public final ChildSaProposal saProposal;
-
-        /**
-         * Construct ChildProposal from a decoded inbound message for Child SA negotiation.
-         *
-         * <p>Package private
-         */
-        ChildProposal(
-                byte number,
-                long spi,
-                ChildSaProposal saProposal,
-                boolean hasUnrecognizedTransform) {
-            super(
-                    number,
-                    PROTOCOL_ID_ESP,
-                    SPI_LEN_IPSEC,
-                    spi,
-                    hasUnrecognizedTransform);
-            this.saProposal = saProposal;
-        }
-
-        /** Construct ChildProposal for an outbound message for Child SA negotiation. */
-        private ChildProposal(
-                byte number, SecurityParameterIndex childSpiResource, ChildSaProposal saProposal) {
-            super(
-                    number,
-                    PROTOCOL_ID_ESP,
-                    SPI_LEN_IPSEC,
-                    (long) childSpiResource.getSpi(),
-                    false /*hasUnrecognizedTransform*/);
-            mChildSpiResource = childSpiResource;
-            this.saProposal = saProposal;
-        }
-
-        /**
-         * Construct ChildProposal for an outbound message for Child SA negotiation.
-         *
-         * <p>Package private
-         */
-        @VisibleForTesting
-        static ChildProposal createChildProposal(
-                byte number,
-                ChildSaProposal saProposal,
-                IpSecManager ipSecManager,
-                InetAddress localAddress)
-                throws ResourceUnavailableException {
-            return new ChildProposal(
-                    number, ipSecManager.allocateSecurityParameterIndex(localAddress), saProposal);
-        }
-
-        /** Package private method for releasing SPI resource in this unselected Proposal. */
-        void releaseSpiResourceIfExists() {
-            if (mChildSpiResource ==  null) return;
-
-            mChildSpiResource.close();
-            mChildSpiResource = null;
-        }
-
-        /**
-         * Package private method for allocating SPI resource for a validated remotely generated
-         * Child SA proposal.
-         */
-        void allocateResourceForRemoteChildSpi(IpSecManager ipSecManager, InetAddress remoteAddress)
-                throws ResourceUnavailableException, SpiUnavailableException {
-            mChildSpiResource =
-                    ipSecManager.allocateSecurityParameterIndex(remoteAddress, (int) spi);
-        }
-
-        @Override
-        public SaProposal getSaProposal() {
-            return saProposal;
-        }
-
-        /**
-         * Get the IPsec SPI resource.
-         *
-         * @return the IPsec SPI resource.
-         */
-        public SecurityParameterIndex getChildSpiResource() {
-            return mChildSpiResource;
-        }
-    }
-
-    @VisibleForTesting
-    interface AttributeDecoder {
-        List<Attribute> decodeAttributes(int length, ByteBuffer inputBuffer)
-                throws IkeProtocolException;
-    }
-
-    /**
-     * Transform is an abstract base class that represents the common information for all Transform
-     * types. It may contain one or more {@link Attribute}.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     *     <p>Transforms with unrecognized Transform ID or containing unrecognized Attribute Type
-     *     shall be ignored when processing received SA payload.
-     */
-    public abstract static class Transform {
-
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef({
-            TRANSFORM_TYPE_ENCR,
-            TRANSFORM_TYPE_PRF,
-            TRANSFORM_TYPE_INTEG,
-            TRANSFORM_TYPE_DH,
-            TRANSFORM_TYPE_ESN
-        })
-        public @interface TransformType {}
-
-        public static final int TRANSFORM_TYPE_ENCR = 1;
-        public static final int TRANSFORM_TYPE_PRF = 2;
-        public static final int TRANSFORM_TYPE_INTEG = 3;
-        public static final int TRANSFORM_TYPE_DH = 4;
-        public static final int TRANSFORM_TYPE_ESN = 5;
-
-        private static final byte LAST_TRANSFORM = 0;
-        private static final byte NOT_LAST_TRANSFORM = 3;
-
-        // Length of reserved field of a Transform.
-        private static final int TRANSFORM_RESERVED_FIELD_LEN = 1;
-
-        // Length of the Transform that with no Attribute.
-        protected static final int BASIC_TRANSFORM_LEN = 8;
-
-        // TODO: Add constants for supported algorithms
-
-        @VisibleForTesting
-        static AttributeDecoder sAttributeDecoder =
-                new AttributeDecoder() {
-                    public List<Attribute> decodeAttributes(int length, ByteBuffer inputBuffer)
-                            throws IkeProtocolException {
-                        List<Attribute> list = new LinkedList<>();
-                        int parsedLength = BASIC_TRANSFORM_LEN;
-                        while (parsedLength < length) {
-                            Pair<Attribute, Integer> pair = Attribute.readFrom(inputBuffer);
-                            parsedLength += pair.second;
-                            list.add(pair.first);
-                        }
-                        // TODO: Validate that parsedLength equals to length.
-                        return list;
-                    }
-                };
-
-        // Only supported type falls into {@link TransformType}
-        public final int type;
-        public final int id;
-        public final boolean isSupported;
-
-        /** Construct an instance of Transform for building an outbound packet. */
-        protected Transform(int type, int id) {
-            this.type = type;
-            this.id = id;
-            if (!isSupportedTransformId(id)) {
-                throw new IllegalArgumentException(
-                        "Unsupported " + getTransformTypeString() + " Algorithm ID: " + id);
-            }
-            this.isSupported = true;
-        }
-
-        /** Construct an instance of Transform for decoding an inbound packet. */
-        protected Transform(int type, int id, List<Attribute> attributeList) {
-            this.type = type;
-            this.id = id;
-            this.isSupported =
-                    isSupportedTransformId(id) && !hasUnrecognizedAttribute(attributeList);
-        }
-
-        @VisibleForTesting
-        static Transform readFrom(ByteBuffer inputBuffer) throws IkeProtocolException {
-            byte isLast = inputBuffer.get();
-            if (isLast != LAST_TRANSFORM && isLast != NOT_LAST_TRANSFORM) {
-                throw new InvalidSyntaxException(
-                        "Invalid value of Last Transform Substructure: " + isLast);
-            }
-
-            // Skip RESERVED byte
-            inputBuffer.get(new byte[TRANSFORM_RESERVED_FIELD_LEN]);
-
-            int length = Short.toUnsignedInt(inputBuffer.getShort());
-            int type = Byte.toUnsignedInt(inputBuffer.get());
-
-            // Skip RESERVED byte
-            inputBuffer.get(new byte[TRANSFORM_RESERVED_FIELD_LEN]);
-
-            int id = Short.toUnsignedInt(inputBuffer.getShort());
-
-            // Decode attributes
-            List<Attribute> attributeList = sAttributeDecoder.decodeAttributes(length, inputBuffer);
-
-            validateAttributeUniqueness(attributeList);
-
-            switch (type) {
-                case TRANSFORM_TYPE_ENCR:
-                    return new EncryptionTransform(id, attributeList);
-                case TRANSFORM_TYPE_PRF:
-                    return new PrfTransform(id, attributeList);
-                case TRANSFORM_TYPE_INTEG:
-                    return new IntegrityTransform(id, attributeList);
-                case TRANSFORM_TYPE_DH:
-                    return new DhGroupTransform(id, attributeList);
-                case TRANSFORM_TYPE_ESN:
-                    return new EsnTransform(id, attributeList);
-                default:
-                    return new UnrecognizedTransform(type, id, attributeList);
-            }
-        }
-
-        // Throw InvalidSyntaxException if there are multiple Attributes of the same type
-        private static void validateAttributeUniqueness(List<Attribute> attributeList)
-                throws IkeProtocolException {
-            Set<Integer> foundTypes = new ArraySet<>();
-            for (Attribute attr : attributeList) {
-                if (!foundTypes.add(attr.type)) {
-                    throw new InvalidSyntaxException(
-                            "There are multiple Attributes of the same type. ");
-                }
-            }
-        }
-
-        // Check if there is Attribute with unrecognized type.
-        protected abstract boolean hasUnrecognizedAttribute(List<Attribute> attributeList);
-
-        // Check if this Transform ID is supported.
-        protected abstract boolean isSupportedTransformId(int id);
-
-        // Encode Transform to a ByteBuffer.
-        protected abstract void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer);
-
-        // Get entire Transform length.
-        protected abstract int getTransformLength();
-
-        protected void encodeBasicTransformToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            byte isLastIndicator = isLast ? LAST_TRANSFORM : NOT_LAST_TRANSFORM;
-            byteBuffer
-                    .put(isLastIndicator)
-                    .put(new byte[TRANSFORM_RESERVED_FIELD_LEN])
-                    .putShort((short) getTransformLength())
-                    .put((byte) type)
-                    .put(new byte[TRANSFORM_RESERVED_FIELD_LEN])
-                    .putShort((short) id);
-        }
-
-        /**
-         * Get Tranform Type as a String.
-         *
-         * @return Tranform Type as a String.
-         */
-        public abstract String getTransformTypeString();
-
-        // TODO: Add abstract getTransformIdString() to return specific algorithm/dhGroup name
-    }
-
-    /**
-     * EncryptionTransform represents an encryption algorithm. It may contain an Atrribute
-     * specifying the key length.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     */
-    public static final class EncryptionTransform extends Transform {
-        public static final int KEY_LEN_UNSPECIFIED = 0;
-
-        // When using encryption algorithm with variable-length keys, mSpecifiedKeyLength MUST be
-        // set and a KeyLengthAttribute MUST be attached. Otherwise, mSpecifiedKeyLength MUST NOT be
-        // set and KeyLengthAttribute MUST NOT be attached.
-        private final int mSpecifiedKeyLength;
-
-        /**
-         * Contruct an instance of EncryptionTransform with fixed key length for building an
-         * outbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         */
-        public EncryptionTransform(@EncryptionAlgorithm int id) {
-            this(id, KEY_LEN_UNSPECIFIED);
-        }
-
-        /**
-         * Contruct an instance of EncryptionTransform with variable key length for building an
-         * outbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         * @param specifiedKeyLength the specified key length of this encryption algorithm.
-         */
-        public EncryptionTransform(@EncryptionAlgorithm int id, int specifiedKeyLength) {
-            super(Transform.TRANSFORM_TYPE_ENCR, id);
-
-            mSpecifiedKeyLength = specifiedKeyLength;
-            try {
-                validateKeyLength();
-            } catch (InvalidSyntaxException e) {
-                throw new IllegalArgumentException(e);
-            }
-        }
-
-        /**
-         * Contruct an instance of EncryptionTransform for decoding an inbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         * @param attributeList the decoded list of Attribute.
-         * @throws InvalidSyntaxException for syntax error.
-         */
-        protected EncryptionTransform(int id, List<Attribute> attributeList)
-                throws InvalidSyntaxException {
-            super(Transform.TRANSFORM_TYPE_ENCR, id, attributeList);
-            if (!isSupported) {
-                mSpecifiedKeyLength = KEY_LEN_UNSPECIFIED;
-            } else {
-                if (attributeList.size() == 0) {
-                    mSpecifiedKeyLength = KEY_LEN_UNSPECIFIED;
-                } else {
-                    KeyLengthAttribute attr = getKeyLengthAttribute(attributeList);
-                    mSpecifiedKeyLength = attr.keyLength;
-                }
-                validateKeyLength();
-            }
-        }
-
-        /**
-         * Get the specified key length.
-         *
-         * @return the specified key length.
-         */
-        public int getSpecifiedKeyLength() {
-            return mSpecifiedKeyLength;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, id, mSpecifiedKeyLength);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof EncryptionTransform)) return false;
-
-            EncryptionTransform other = (EncryptionTransform) o;
-            return (type == other.type
-                    && id == other.id
-                    && mSpecifiedKeyLength == other.mSpecifiedKeyLength);
-        }
-
-        @Override
-        protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedEncryptionAlgorithm(id);
-        }
-
-        @Override
-        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
-            for (Attribute attr : attributeList) {
-                if (attr instanceof UnrecognizedAttribute) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        private KeyLengthAttribute getKeyLengthAttribute(List<Attribute> attributeList) {
-            for (Attribute attr : attributeList) {
-                if (attr.type == Attribute.ATTRIBUTE_TYPE_KEY_LENGTH) {
-                    return (KeyLengthAttribute) attr;
-                }
-            }
-            throw new IllegalArgumentException("Cannot find Attribute with Key Length type");
-        }
-
-        private void validateKeyLength() throws InvalidSyntaxException {
-            switch (id) {
-                case SaProposal.ENCRYPTION_ALGORITHM_3DES:
-                    if (mSpecifiedKeyLength != KEY_LEN_UNSPECIFIED) {
-                        throw new InvalidSyntaxException(
-                                "Must not set Key Length value for this "
-                                        + getTransformTypeString()
-                                        + " Algorithm ID: "
-                                        + id);
-                    }
-                    return;
-                case SaProposal.ENCRYPTION_ALGORITHM_AES_CBC:
-                    /* fall through */
-                case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8:
-                    /* fall through */
-                case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12:
-                    /* fall through */
-                case SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16:
-                    if (mSpecifiedKeyLength == KEY_LEN_UNSPECIFIED) {
-                        throw new InvalidSyntaxException(
-                                "Must set Key Length value for this "
-                                        + getTransformTypeString()
-                                        + " Algorithm ID: "
-                                        + id);
-                    }
-                    if (mSpecifiedKeyLength != SaProposal.KEY_LEN_AES_128
-                            && mSpecifiedKeyLength != SaProposal.KEY_LEN_AES_192
-                            && mSpecifiedKeyLength != SaProposal.KEY_LEN_AES_256) {
-                        throw new InvalidSyntaxException(
-                                "Invalid key length for this "
-                                        + getTransformTypeString()
-                                        + " Algorithm ID: "
-                                        + id);
-                    }
-                    return;
-                default:
-                    // Won't hit here.
-                    throw new IllegalArgumentException(
-                            "Unrecognized Encryption Algorithm ID: " + id);
-            }
-        }
-
-        @Override
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
-
-            if (mSpecifiedKeyLength != KEY_LEN_UNSPECIFIED) {
-                new KeyLengthAttribute(mSpecifiedKeyLength).encodeToByteBuffer(byteBuffer);
-            }
-        }
-
-        @Override
-        protected int getTransformLength() {
-            int len = BASIC_TRANSFORM_LEN;
-
-            if (mSpecifiedKeyLength != KEY_LEN_UNSPECIFIED) {
-                len += new KeyLengthAttribute(mSpecifiedKeyLength).getAttributeLength();
-            }
-
-            return len;
-        }
-
-        @Override
-        public String getTransformTypeString() {
-            return "Encryption Algorithm";
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return SaProposal.getEncryptionAlgorithmString(id)
-                    + "("
-                    + getSpecifiedKeyLength()
-                    + ")";
-        }
-    }
-
-    /**
-     * PrfTransform represents an pseudorandom function.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     */
-    public static final class PrfTransform extends Transform {
-        /**
-         * Contruct an instance of PrfTransform for building an outbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         */
-        public PrfTransform(@PseudorandomFunction int id) {
-            super(Transform.TRANSFORM_TYPE_PRF, id);
-        }
-
-        /**
-         * Contruct an instance of PrfTransform for decoding an inbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         * @param attributeList the decoded list of Attribute.
-         * @throws InvalidSyntaxException for syntax error.
-         */
-        protected PrfTransform(int id, List<Attribute> attributeList)
-                throws InvalidSyntaxException {
-            super(Transform.TRANSFORM_TYPE_PRF, id, attributeList);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, id);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof PrfTransform)) return false;
-
-            PrfTransform other = (PrfTransform) o;
-            return (type == other.type && id == other.id);
-        }
-
-        @Override
-        protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedPseudorandomFunction(id);
-        }
-
-        @Override
-        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
-            return !attributeList.isEmpty();
-        }
-
-        @Override
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
-        }
-
-        @Override
-        protected int getTransformLength() {
-            return BASIC_TRANSFORM_LEN;
-        }
-
-        @Override
-        public String getTransformTypeString() {
-            return "Pseudorandom Function";
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return SaProposal.getPseudorandomFunctionString(id);
-        }
-    }
-
-    /**
-     * IntegrityTransform represents an integrity algorithm.
-     *
-     * <p>Proposing integrity algorithm for ESP SA is optional. Omitting the IntegrityTransform is
-     * equivalent to including it with a value of NONE. When multiple integrity algorithms are
-     * provided, choosing any of them are acceptable.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     */
-    public static final class IntegrityTransform extends Transform {
-        /**
-         * Contruct an instance of IntegrityTransform for building an outbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         */
-        public IntegrityTransform(@IntegrityAlgorithm int id) {
-            super(Transform.TRANSFORM_TYPE_INTEG, id);
-        }
-
-        /**
-         * Contruct an instance of IntegrityTransform for decoding an inbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         * @param attributeList the decoded list of Attribute.
-         * @throws InvalidSyntaxException for syntax error.
-         */
-        protected IntegrityTransform(int id, List<Attribute> attributeList)
-                throws InvalidSyntaxException {
-            super(Transform.TRANSFORM_TYPE_INTEG, id, attributeList);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, id);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof IntegrityTransform)) return false;
-
-            IntegrityTransform other = (IntegrityTransform) o;
-            return (type == other.type && id == other.id);
-        }
-
-        @Override
-        protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedIntegrityAlgorithm(id);
-        }
-
-        @Override
-        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
-            return !attributeList.isEmpty();
-        }
-
-        @Override
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
-        }
-
-        @Override
-        protected int getTransformLength() {
-            return BASIC_TRANSFORM_LEN;
-        }
-
-        @Override
-        public String getTransformTypeString() {
-            return "Integrity Algorithm";
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return SaProposal.getIntegrityAlgorithmString(id);
-        }
-    }
-
-    /**
-     * DhGroupTransform represents a Diffie-Hellman Group
-     *
-     * <p>Proposing DH group for non-first Child SA is optional. Omitting the DhGroupTransform is
-     * equivalent to including it with a value of NONE. When multiple DH groups are provided,
-     * choosing any of them are acceptable.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     */
-    public static final class DhGroupTransform extends Transform {
-        /**
-         * Contruct an instance of DhGroupTransform for building an outbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         */
-        public DhGroupTransform(@DhGroup int id) {
-            super(Transform.TRANSFORM_TYPE_DH, id);
-        }
-
-        /**
-         * Contruct an instance of DhGroupTransform for decoding an inbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         * @param attributeList the decoded list of Attribute.
-         * @throws InvalidSyntaxException for syntax error.
-         */
-        protected DhGroupTransform(int id, List<Attribute> attributeList)
-                throws InvalidSyntaxException {
-            super(Transform.TRANSFORM_TYPE_DH, id, attributeList);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, id);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof DhGroupTransform)) return false;
-
-            DhGroupTransform other = (DhGroupTransform) o;
-            return (type == other.type && id == other.id);
-        }
-
-        @Override
-        protected boolean isSupportedTransformId(int id) {
-            return SaProposal.isSupportedDhGroup(id);
-        }
-
-        @Override
-        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
-            return !attributeList.isEmpty();
-        }
-
-        @Override
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
-        }
-
-        @Override
-        protected int getTransformLength() {
-            return BASIC_TRANSFORM_LEN;
-        }
-
-        @Override
-        public String getTransformTypeString() {
-            return "Diffie-Hellman Group";
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            return SaProposal.getDhGroupString(id);
-        }
-    }
-
-    /**
-     * EsnTransform represents ESN policy that indicates if IPsec SA uses tranditional 32-bit
-     * sequence numbers or extended(64-bit) sequence numbers.
-     *
-     * <p>Currently IKE library only supports negotiating IPsec SA that do not use extended sequence
-     * numbers. The Transform ID of EsnTransform in outbound packets is not user configurable.
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.2">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     */
-    public static final class EsnTransform extends Transform {
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef({ESN_POLICY_NO_EXTENDED, ESN_POLICY_EXTENDED})
-        public @interface EsnPolicy {}
-
-        public static final int ESN_POLICY_NO_EXTENDED = 0;
-        public static final int ESN_POLICY_EXTENDED = 1;
-
-        /**
-         * Construct an instance of EsnTransform indicates using no-extended sequence numbers for
-         * building an outbound packet.
-         */
-        public EsnTransform() {
-            super(Transform.TRANSFORM_TYPE_ESN, ESN_POLICY_NO_EXTENDED);
-        }
-
-        /**
-         * Contruct an instance of EsnTransform for decoding an inbound packet.
-         *
-         * @param id the IKE standard Transform ID.
-         * @param attributeList the decoded list of Attribute.
-         * @throws InvalidSyntaxException for syntax error.
-         */
-        protected EsnTransform(int id, List<Attribute> attributeList)
-                throws InvalidSyntaxException {
-            super(Transform.TRANSFORM_TYPE_ESN, id, attributeList);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(type, id);
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (!(o instanceof EsnTransform)) return false;
-
-            EsnTransform other = (EsnTransform) o;
-            return (type == other.type && id == other.id);
-        }
-
-        @Override
-        protected boolean isSupportedTransformId(int id) {
-            return (id == ESN_POLICY_NO_EXTENDED || id == ESN_POLICY_EXTENDED);
-        }
-
-        @Override
-        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
-            return !attributeList.isEmpty();
-        }
-
-        @Override
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            encodeBasicTransformToByteBuffer(isLast, byteBuffer);
-        }
-
-        @Override
-        protected int getTransformLength() {
-            return BASIC_TRANSFORM_LEN;
-        }
-
-        @Override
-        public String getTransformTypeString() {
-            return "Extended Sequence Numbers";
-        }
-
-        @Override
-        @NonNull
-        public String toString() {
-            if (id == ESN_POLICY_NO_EXTENDED) {
-                return "ESN_No_Extended";
-            }
-            return "ESN_Extended";
-        }
-    }
-
-    /**
-     * UnrecognizedTransform represents a Transform with unrecognized Transform Type.
-     *
-     * <p>Proposals containing an UnrecognizedTransform should be ignored.
-     */
-    protected static final class UnrecognizedTransform extends Transform {
-        protected UnrecognizedTransform(int type, int id, List<Attribute> attributeList) {
-            super(type, id, attributeList);
-        }
-
-        @Override
-        protected boolean isSupportedTransformId(int id) {
-            return false;
-        }
-
-        @Override
-        protected boolean hasUnrecognizedAttribute(List<Attribute> attributeList) {
-            return !attributeList.isEmpty();
-        }
-
-        @Override
-        protected void encodeToByteBuffer(boolean isLast, ByteBuffer byteBuffer) {
-            throw new UnsupportedOperationException(
-                    "It is not supported to encode a Transform with" + getTransformTypeString());
-        }
-
-        @Override
-        protected int getTransformLength() {
-            throw new UnsupportedOperationException(
-                    "It is not supported to get length of a Transform with "
-                            + getTransformTypeString());
-        }
-
-        /**
-         * Return Tranform Type of Unrecognized Transform as a String.
-         *
-         * @return Tranform Type of Unrecognized Transform as a String.
-         */
-        @Override
-        public String getTransformTypeString() {
-            return "Unrecognized Transform Type.";
-        }
-    }
-
-    /**
-     * Attribute is an abtract base class for completing the specification of some {@link
-     * Transform}.
-     *
-     * <p>Attribute is either in Type/Value format or Type/Length/Value format. For TV format,
-     * Attribute length is always 4 bytes containing value for 2 bytes. While for TLV format,
-     * Attribute length is determined by length field.
-     *
-     * <p>Currently only Key Length type is supported
-     *
-     * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.3.5">RFC 7296, Internet Key
-     *     Exchange Protocol Version 2 (IKEv2)</a>
-     */
-    public abstract static class Attribute {
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef({ATTRIBUTE_TYPE_KEY_LENGTH})
-        public @interface AttributeType {}
-
-        // Support only one Attribute type: Key Length. Should use Type/Value format.
-        public static final int ATTRIBUTE_TYPE_KEY_LENGTH = 14;
-
-        // Mask to extract the left most AF bit to indicate Attribute Format.
-        private static final int ATTRIBUTE_FORMAT_MASK = 0x8000;
-        // Mask to extract 15 bits after the AF bit to indicate Attribute Type.
-        private static final int ATTRIBUTE_TYPE_MASK = 0x7fff;
-
-        // Package private mask to indicate that Type-Value (TV) Attribute Format is used.
-        static final int ATTRIBUTE_FORMAT_TV = ATTRIBUTE_FORMAT_MASK;
-
-        // Package private
-        static final int TV_ATTRIBUTE_VALUE_LEN = 2;
-        static final int TV_ATTRIBUTE_TOTAL_LEN = 4;
-        static final int TVL_ATTRIBUTE_HEADER_LEN = TV_ATTRIBUTE_TOTAL_LEN;
-
-        // Only Key Length type belongs to AttributeType
-        public final int type;
-
-        /** Construct an instance of an Attribute when decoding message. */
-        protected Attribute(int type) {
-            this.type = type;
-        }
-
-        @VisibleForTesting
-        static Pair<Attribute, Integer> readFrom(ByteBuffer inputBuffer)
-                throws IkeProtocolException {
-            short formatAndType = inputBuffer.getShort();
-            int format = formatAndType & ATTRIBUTE_FORMAT_MASK;
-            int type = formatAndType & ATTRIBUTE_TYPE_MASK;
-
-            int length = 0;
-            byte[] value = new byte[0];
-            if (format == ATTRIBUTE_FORMAT_TV) {
-                // Type/Value format
-                length = TV_ATTRIBUTE_TOTAL_LEN;
-                value = new byte[TV_ATTRIBUTE_VALUE_LEN];
-            } else {
-                // Type/Length/Value format
-                if (type == ATTRIBUTE_TYPE_KEY_LENGTH) {
-                    throw new InvalidSyntaxException("Wrong format in Transform Attribute");
-                }
-
-                length = Short.toUnsignedInt(inputBuffer.getShort());
-                int valueLen = length - TVL_ATTRIBUTE_HEADER_LEN;
-                // IkeMessage will catch exception if valueLen is negative.
-                value = new byte[valueLen];
-            }
-
-            inputBuffer.get(value);
-
-            switch (type) {
-                case ATTRIBUTE_TYPE_KEY_LENGTH:
-                    return new Pair(new KeyLengthAttribute(value), length);
-                default:
-                    return new Pair(new UnrecognizedAttribute(type, value), length);
-            }
-        }
-
-        // Encode Attribute to a ByteBuffer.
-        protected abstract void encodeToByteBuffer(ByteBuffer byteBuffer);
-
-        // Get entire Attribute length.
-        protected abstract int getAttributeLength();
-    }
-
-    /** KeyLengthAttribute represents a Key Length type Attribute */
-    public static final class KeyLengthAttribute extends Attribute {
-        public final int keyLength;
-
-        protected KeyLengthAttribute(byte[] value) {
-            this(Short.toUnsignedInt(ByteBuffer.wrap(value).getShort()));
-        }
-
-        protected KeyLengthAttribute(int keyLength) {
-            super(ATTRIBUTE_TYPE_KEY_LENGTH);
-            this.keyLength = keyLength;
-        }
-
-        @Override
-        protected void encodeToByteBuffer(ByteBuffer byteBuffer) {
-            byteBuffer
-                    .putShort((short) (ATTRIBUTE_FORMAT_TV | ATTRIBUTE_TYPE_KEY_LENGTH))
-                    .putShort((short) keyLength);
-        }
-
-        @Override
-        protected int getAttributeLength() {
-            return TV_ATTRIBUTE_TOTAL_LEN;
-        }
-    }
-
-    /**
-     * UnrecognizedAttribute represents a Attribute with unrecoginzed Attribute Type.
-     *
-     * <p>Transforms containing UnrecognizedAttribute should be ignored.
-     */
-    protected static final class UnrecognizedAttribute extends Attribute {
-        protected UnrecognizedAttribute(int type, byte[] value) {
-            super(type);
-        }
-
-        @Override
-        protected void encodeToByteBuffer(ByteBuffer byteBuffer) {
-            throw new UnsupportedOperationException(
-                    "It is not supported to encode an unrecognized Attribute.");
-        }
-
-        @Override
-        protected int getAttributeLength() {
-            throw new UnsupportedOperationException(
-                    "It is not supported to get length of an unrecognized Attribute.");
-        }
-    }
-
-    /**
-     * Encode SA payload to ByteBUffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-
-        for (int i = 0; i < proposalList.size(); i++) {
-            // The last proposal has the isLast flag set to true.
-            proposalList.get(i).encodeToByteBuffer(i == proposalList.size() - 1, byteBuffer);
-        }
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        int len = GENERIC_HEADER_LENGTH;
-
-        for (Proposal p : proposalList) len += p.getProposalLength();
-
-        return len;
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "SA";
-    }
-
-    @Override
-    @NonNull
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        if (isSaResponse) {
-            sb.append("SA Response: ");
-        } else {
-            sb.append("SA Request: ");
-        }
-
-        int len = proposalList.size();
-        for (int i = 0; i < len; i++) {
-            sb.append(proposalList.get(i).toString());
-            if (i < len - 1) sb.append(", ");
-        }
-
-        return sb.toString();
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayload.java
deleted file mode 100644
index 0c2d1ff..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayload.java
+++ /dev/null
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.annotation.Nullable;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-
-/**
- * IkeSkPayload represents the common information of an Encrypted and Authenticated Payload and an
- * Encrypted and Authenticated Fragment Payload.
- *
- * <p>It contains other payloads in encrypted form. It is must be the last payload in the message.
- * It should be the only payload in this implementation.
- *
- * <p>Critical bit must be ignored when doing decoding.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#page-105">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public class IkeSkPayload extends IkePayload {
-
-    protected final IkeEncryptedPayloadBody mIkeEncryptedPayloadBody;
-
-    /**
-     * Construct an instance of IkeSkPayload from decrypting an incoming packet.
-     *
-     * @param critical indicates if it is a critical payload.
-     * @param message the byte array contains the whole IKE message.
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param decryptCipher the negotiated encryption algorithm.
-     * @param integrityKey the negotiated integrity algorithm key.
-     * @param decryptionKey the negotiated decryption key.
-     */
-    @VisibleForTesting
-    IkeSkPayload(
-            boolean critical,
-            byte[] message,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher decryptCipher,
-            byte[] integrityKey,
-            byte[] decryptionKey)
-            throws IkeProtocolException, GeneralSecurityException {
-
-        this(
-                false /*isSkf*/,
-                critical,
-                IkeHeader.IKE_HEADER_LENGTH + GENERIC_HEADER_LENGTH,
-                message,
-                integrityMac,
-                decryptCipher,
-                integrityKey,
-                decryptionKey);
-    }
-
-    /** Construct an instance of IkeSkPayload for testing.*/
-    @VisibleForTesting
-    IkeSkPayload(boolean isSkf, IkeEncryptedPayloadBody encryptedPayloadBody) {
-        super(isSkf ? PAYLOAD_TYPE_SKF : PAYLOAD_TYPE_SK, false/*critical*/);
-        mIkeEncryptedPayloadBody = encryptedPayloadBody;
-    }
-
-    /** Construct an instance of IkeSkPayload from decrypting an incoming packet. */
-    protected IkeSkPayload(
-            boolean isSkf,
-            boolean critical,
-            int encryptedBodyOffset,
-            byte[] message,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher decryptCipher,
-            byte[] integrityKey,
-            byte[] decryptionKey)
-            throws IkeProtocolException, GeneralSecurityException {
-        super(isSkf ? PAYLOAD_TYPE_SKF : PAYLOAD_TYPE_SK, critical);
-
-        // TODO: Support constructing IkeEncryptedPayloadBody using AEAD.
-
-        mIkeEncryptedPayloadBody =
-                new IkeEncryptedPayloadBody(
-                        message,
-                        encryptedBodyOffset,
-                        integrityMac,
-                        decryptCipher,
-                        integrityKey,
-                        decryptionKey);
-    }
-
-    /**
-     * Construct an instance of IkeSkPayload for building outbound packet.
-     *
-     * @param ikeHeader the IKE header.
-     * @param firstPayloadType the type of first payload nested in SkPayload.
-     * @param unencryptedPayloads the encoded payload list to protect.
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param encryptCipher the negotiated encryption algorithm.
-     * @param integrityKey the negotiated integrity algorithm key.
-     * @param encryptionKey the negotiated encryption key.
-     */
-    @VisibleForTesting
-    IkeSkPayload(
-            IkeHeader ikeHeader,
-            @PayloadType int firstPayloadType,
-            byte[] unencryptedPayloads,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher encryptCipher,
-            byte[] integrityKey,
-            byte[] encryptionKey) {
-
-        this(
-                ikeHeader,
-                firstPayloadType,
-                new byte[0] /*skfHeaderBytes*/,
-                unencryptedPayloads,
-                integrityMac,
-                encryptCipher,
-                integrityKey,
-                encryptionKey);
-    }
-
-    /** Construct an instance of IkeSkPayload for building outbound packet. */
-    @VisibleForTesting
-    protected IkeSkPayload(
-            IkeHeader ikeHeader,
-            @PayloadType int firstPayloadType,
-            byte[] skfHeaderBytes,
-            byte[] unencryptedPayloads,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher encryptCipher,
-            byte[] integrityKey,
-            byte[] encryptionKey) {
-        super(skfHeaderBytes.length == 0 ? PAYLOAD_TYPE_SK : PAYLOAD_TYPE_SKF, false);
-
-        // TODO: Support constructing IkeEncryptedPayloadBody using AEAD.
-
-        mIkeEncryptedPayloadBody =
-                new IkeEncryptedPayloadBody(
-                        ikeHeader,
-                        firstPayloadType,
-                        skfHeaderBytes,
-                        unencryptedPayloads,
-                        integrityMac,
-                        encryptCipher,
-                        integrityKey,
-                        encryptionKey);
-    }
-
-    /**
-     * Return unencrypted data.
-     *
-     * @return unencrypted data in a byte array.
-     */
-    public byte[] getUnencryptedData() {
-        return mIkeEncryptedPayloadBody.getUnencryptedData();
-    }
-
-    /**
-     * Encode this payload to a ByteBuffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer.put(mIkeEncryptedPayloadBody.encode());
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        return GENERIC_HEADER_LENGTH + mIkeEncryptedPayloadBody.getLength();
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "SK";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayload.java
deleted file mode 100644
index 6faea12..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayload.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.annotation.Nullable;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-
-/**
- * IkeSkfPayload represents an Encrypted and Authenticated Fragment Payload.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7383">RFC 7383, Internet Key Exchange Protocol
- *     Version 2 (IKEv2) Message Fragmentation</a>
- */
-public final class IkeSkfPayload extends IkeSkPayload {
-    public static final int SKF_HEADER_LEN = 4;
-
-    /** Current Fragment message number, starting from 1 */
-    public final int fragmentNum;
-    /** Number of Fragment messages into which the original message was divided */
-    public final int totalFragments;
-
-    /**
-     * Construct an instance of IkeSkfPayload by authenticating and decrypting an incoming packet.
-     *
-     * <p>SKF Payload with invalid fragmentNum or invalid totalFragments, or cannot be authenticated
-     * or decrypted MUST be discarded
-     *
-     * @param critical indicates if it is a critical payload.
-     * @param message the byte array contains the whole IKE message.
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param decryptCipher the negotiated encryption algorithm.
-     * @param integrityKey the negotiated integrity algorithm key.
-     * @param decryptionKey the negotiated decryption key.
-     */
-    IkeSkfPayload(
-            boolean critical,
-            byte[] message,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher decryptCipher,
-            byte[] integrityKey,
-            byte[] decryptionKey)
-            throws IkeProtocolException, GeneralSecurityException {
-        super(
-                true /*isSkf*/,
-                critical,
-                IkeHeader.IKE_HEADER_LENGTH + GENERIC_HEADER_LENGTH + SKF_HEADER_LEN,
-                message,
-                integrityMac,
-                decryptCipher,
-                integrityKey,
-                decryptionKey);
-
-        // TODO: Support constructing IkeEncryptedPayloadBody using AEAD.
-
-        ByteBuffer inputBuffer = ByteBuffer.wrap(message);
-        inputBuffer.get(new byte[IkeHeader.IKE_HEADER_LENGTH + GENERIC_HEADER_LENGTH]);
-
-        fragmentNum = Short.toUnsignedInt(inputBuffer.getShort());
-        totalFragments = Short.toUnsignedInt(inputBuffer.getShort());
-
-        if (fragmentNum < 1 || totalFragments < 1 || fragmentNum > totalFragments) {
-            throw new InvalidSyntaxException(
-                    "Received invalid Fragment Number or Total Fragments Number. Fragment Number: "
-                            + fragmentNum
-                            + "  Total Fragments: "
-                            + totalFragments);
-        }
-    }
-
-    /**
-     * Construct an instance of IkeSkfPayload for building outbound packet.
-     *
-     * @param ikeHeader the IKE header.
-     * @param firstPayloadType the type of first payload nested in SkPayload.
-     * @param unencryptedPayloads the encoded payload list to protect.
-     * @param integrityMac the negotiated integrity algorithm.
-     * @param encryptCipher the negotiated encryption algorithm.
-     * @param integrityKey the negotiated integrity algorithm key.
-     * @param encryptionKey the negotiated encryption key.
-     */
-    IkeSkfPayload(
-            IkeHeader ikeHeader,
-            @PayloadType int firstPayloadType,
-            byte[] unencryptedPayloads,
-            @Nullable IkeMacIntegrity integrityMac,
-            IkeCipher encryptCipher,
-            byte[] integrityKey,
-            byte[] encryptionKey,
-            int fragNum,
-            int totalFrags) {
-        super(
-                ikeHeader,
-                firstPayloadType,
-                encodeSkfHeader(fragNum, totalFrags),
-                unencryptedPayloads,
-                integrityMac,
-                encryptCipher,
-                integrityKey,
-                encryptionKey);
-        fragmentNum = fragNum;
-        totalFragments = totalFrags;
-    }
-
-    /** Construct an instance of IkeSkfPayload for testing. */
-    @VisibleForTesting
-    IkeSkfPayload(IkeEncryptedPayloadBody encryptedPayloadBody, int fragNum, int totalFrags) {
-        super(true /*isSkf*/, encryptedPayloadBody);
-        fragmentNum = fragNum;
-        totalFragments = totalFrags;
-    }
-
-    @VisibleForTesting
-    static byte[] encodeSkfHeader(int fragNum, int totalFrags) {
-        ByteBuffer buffer = ByteBuffer.allocate(SKF_HEADER_LEN);
-        buffer.putShort((short) fragNum).putShort((short) totalFrags);
-        return buffer.array();
-    }
-
-    /**
-     * Encode this payload to a ByteBuffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-        byteBuffer
-                .putShort((short) fragmentNum)
-                .putShort((short) totalFragments)
-                .put(mIkeEncryptedPayloadBody.encode());
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        return GENERIC_HEADER_LENGTH + SKF_HEADER_LEN + mIkeEncryptedPayloadBody.getLength();
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        return "SKF";
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayload.java b/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayload.java
deleted file mode 100644
index 207bdc3..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayload.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import android.net.ipsec.ike.IkeTrafficSelector;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import java.nio.ByteBuffer;
-
-/**
- * IkeTsPayload represents an Traffic Selector Initiator Payload or an Traffic Selector Responder
- * Payload.
- *
- * <p>Traffic Selector Initiator Payload and Traffic Selector Responder Payload have same format but
- * different payload types. They describe the address ranges and port ranges of Child SA initiator
- * and Child SA responder.
- *
- * @see <a href="https://tools.ietf.org/html/rfc7296#section-3.13">RFC 7296, Internet Key Exchange
- *     Protocol Version 2 (IKEv2)</a>
- */
-public final class IkeTsPayload extends IkePayload {
-    // Length of Traffic Selector Payload header.
-    private static final int TS_HEADER_LEN = 4;
-    // Length of reserved field in octets.
-    private static final int TS_HEADER_RESERVED_LEN = 3;
-
-    /** Number of Traffic Selectors */
-    public final int numTs;
-    /** Array of Traffic Selectors */
-    public final IkeTrafficSelector[] trafficSelectors;
-
-    IkeTsPayload(boolean critical, byte[] payloadBody, boolean isInitiator)
-            throws IkeProtocolException {
-        super((isInitiator ? PAYLOAD_TYPE_TS_INITIATOR : PAYLOAD_TYPE_TS_RESPONDER), critical);
-
-        ByteBuffer inputBuffer = ByteBuffer.wrap(payloadBody);
-        numTs = Byte.toUnsignedInt(inputBuffer.get());
-        if (numTs == 0) {
-            throw new InvalidSyntaxException("Cannot find Traffic Selector in TS payload.");
-        }
-
-        // Skip RESERVED byte
-        inputBuffer.get(new byte[TS_HEADER_RESERVED_LEN]);
-
-        // Decode Traffic Selectors
-        byte[] tsBytes = new byte[inputBuffer.remaining()];
-        inputBuffer.get(tsBytes);
-        trafficSelectors = IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-    }
-
-    /**
-     * Construct an instance of IkeTsPayload for building an outbound IKE message.
-     *
-     * @param isInitiator indicates if this payload is for a Child SA initiator or responder.
-     * @param ikeTrafficSelectors the array of included traffic selectors.
-     */
-    public IkeTsPayload(boolean isInitiator, IkeTrafficSelector[] ikeTrafficSelectors) {
-        super((isInitiator ? PAYLOAD_TYPE_TS_INITIATOR : PAYLOAD_TYPE_TS_RESPONDER), false);
-
-        if (ikeTrafficSelectors == null || ikeTrafficSelectors.length == 0) {
-            throw new IllegalArgumentException(
-                    "TS Payload requires at least one Traffic Selector.");
-        }
-
-        numTs = ikeTrafficSelectors.length;
-        trafficSelectors = ikeTrafficSelectors;
-    }
-
-    /**
-     * Check if this TS payload contains the all TS in the provided TS payload.
-     *
-     * <p>A TS response cannot be narrower than a TS request. When doing rekey, the newly negotiated
-     * TS cannot be narrower than old negotiated TS.
-     *
-     * <p>This method will be used to (1) validate that an inbound response is subset of a locally
-     * generated request; and (2) validate that an inbound rekey request/response is superset of
-     * current negotiated TS.
-     *
-     * @param tsPayload the other TS payload to validate
-     * @return true if current TS Payload contains all TS in the input tsPayload
-     */
-    public boolean contains(IkeTsPayload tsPayload) {
-        subTsLoop:
-        for (IkeTrafficSelector subTs : tsPayload.trafficSelectors) {
-            for (IkeTrafficSelector superTs : this.trafficSelectors) {
-                if (superTs.contains(subTs)) {
-                    continue subTsLoop;
-                }
-            }
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Encode Traffic Selector Payload to ByteBuffer.
-     *
-     * @param nextPayload type of payload that follows this payload.
-     * @param byteBuffer destination ByteBuffer that stores encoded payload.
-     */
-    @Override
-    protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-        encodePayloadHeaderToByteBuffer(nextPayload, getPayloadLength(), byteBuffer);
-
-        byteBuffer.put((byte) numTs).put(new byte[TS_HEADER_RESERVED_LEN]);
-        for (IkeTrafficSelector ts : trafficSelectors) {
-            ts.encodeToByteBuffer(byteBuffer);
-        }
-    }
-
-    /**
-     * Get entire payload length.
-     *
-     * @return entire payload length.
-     */
-    @Override
-    protected int getPayloadLength() {
-        int len = GENERIC_HEADER_LENGTH + TS_HEADER_LEN;
-        for (IkeTrafficSelector ts : trafficSelectors) {
-            len += ts.selectorLength;
-        }
-
-        return len;
-    }
-
-    /**
-     * Return the payload type as a String.
-     *
-     * @return the payload type as a String.
-     */
-    @Override
-    public String getTypeString() {
-        switch (payloadType) {
-            case PAYLOAD_TYPE_TS_INITIATOR:
-                return "TSi";
-            case PAYLOAD_TYPE_TS_RESPONDER:
-                return "TSr";
-            default:
-                // Won't reach here.
-                throw new IllegalArgumentException(
-                        "Invalid Payload Type for Traffic Selector Payload.");
-        }
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/utils/FdEventsReader.java b/src/java/com/android/internal/net/ipsec/ike/utils/FdEventsReader.java
deleted file mode 100644
index 65f9ced..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/utils/FdEventsReader.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.utils;
-
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_ERROR;
-import static android.os.MessageQueue.OnFileDescriptorEventListener.EVENT_INPUT;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.util.SocketUtils;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.MessageQueue;
-import android.system.ErrnoException;
-import android.system.OsConstants;
-
-import java.io.FileDescriptor;
-import java.io.IOException;
-
-/**
- * This class encapsulates the mechanics of registering a file descriptor
- * with a thread's Looper and handling read events (and errors).
- *
- * Subclasses MUST implement createFd() and SHOULD override handlePacket(). They MAY override
- * onStop() and onStart().
- *
- * Subclasses can expect a call life-cycle like the following:
- *
- *     [1] when a client calls start(), createFd() is called, followed by the onStart() hook if all
- *         goes well. Implementations may override onStart() for additional initialization.
- *
- *     [2] yield, waiting for read event or error notification:
- *
- *             [a] readPacket() && handlePacket()
- *
- *             [b] if (no error):
- *                     goto 2
- *                 else:
- *                     goto 3
- *
- *     [3] when a client calls stop(), the onStop() hook is called (unless already stopped or never
- *         started). Implementations may override onStop() for additional cleanup.
- *
- * The packet receive buffer is recycled on every read call, so subclasses
- * should make any copies they would like inside their handlePacket()
- * implementation.
- *
- * All public methods MUST only be called from the same thread with which
- * the Handler constructor argument is associated.
- *
- * <p> This code is an exact copy of {@link FdEventsReader} in
- * frameworks/base/packages/NetworkStack/src/android/net/util/FdEventsReader.java, except the class
- * name is changed to avoid confusion.
- *
- * FIXME: b/130058477 Find a way to share the code between network stack and code outside.
- *
- * @param <BufferType> the type of the buffer used to read data.
- * @hide
- */
-public abstract class FdEventsReader<BufferType> {
-    private static final int FD_EVENTS = EVENT_INPUT | EVENT_ERROR;
-    private static final int UNREGISTER_THIS_FD = 0;
-
-    @NonNull
-    private final Handler mHandler;
-    @NonNull
-    private final MessageQueue mQueue;
-    @NonNull
-    private final BufferType mBuffer;
-    @Nullable
-    private FileDescriptor mFd;
-    private long mPacketsReceived;
-
-    protected static void closeFd(FileDescriptor fd) {
-        try {
-            SocketUtils.closeSocket(fd);
-        } catch (IOException ignored) {
-        }
-    }
-
-    protected FdEventsReader(@NonNull Handler h, @NonNull BufferType buffer) {
-        mHandler = h;
-        mQueue = mHandler.getLooper().getQueue();
-        mBuffer = buffer;
-    }
-
-    /** Start this FdEventsReader. */
-    public void start() {
-        if (onCorrectThread()) {
-            createAndRegisterFd();
-        } else {
-            mHandler.post(() -> {
-                logError("start() called from off-thread", null);
-                createAndRegisterFd();
-            });
-        }
-    }
-
-    /** Stop this FdEventsReader and destroy the file descriptor. */
-    public void stop() {
-        if (onCorrectThread()) {
-            unregisterAndDestroyFd();
-        } else {
-            mHandler.post(() -> {
-                logError("stop() called from off-thread", null);
-                unregisterAndDestroyFd();
-            });
-        }
-    }
-
-    @NonNull
-    public Handler getHandler() {
-        return mHandler;
-    }
-
-    protected abstract int recvBufSize(@NonNull BufferType buffer);
-
-    /** Returns the size of the receive buffer. */
-    public int recvBufSize() {
-        return recvBufSize(mBuffer);
-    }
-
-    /**
-     * Get the number of successful calls to {@link #readPacket(FileDescriptor, Object)}.
-     *
-     * <p>A call was successful if {@link #readPacket(FileDescriptor, Object)} returned a value > 0.
-     */
-    public final long numPacketsReceived() {
-        return mPacketsReceived;
-    }
-
-    /**
-     * Subclasses MUST create the listening socket here, including setting all desired socket
-     * options, interface or address/port binding, etc. The socket MUST be created nonblocking.
-     */
-    @Nullable
-    protected abstract FileDescriptor createFd();
-
-    /**
-     * Implementations MUST return the bytes read or throw an Exception.
-     *
-     * <p>The caller may throw a {@link ErrnoException} with {@link OsConstants#EAGAIN} or
-     * {@link OsConstants#EINTR}, in which case {@link FdEventsReader} will ignore the buffer
-     * contents and respectively wait for further input or retry the read immediately. For all other
-     * exceptions, the {@link FdEventsReader} will be stopped with no more interactions with this
-     * method.
-     */
-    protected abstract int readPacket(@NonNull FileDescriptor fd, @NonNull BufferType buffer)
-            throws Exception;
-
-    /**
-     * Called by the main loop for every packet.  Any desired copies of
-     * |recvbuf| should be made in here, as the underlying byte array is
-     * reused across all reads.
-     */
-    protected void handlePacket(@NonNull BufferType recvbuf, int length) {}
-
-    /**
-     * Called by the main loop to log errors.  In some cases |e| may be null.
-     */
-    protected void logError(@NonNull String msg, @Nullable Exception e) {}
-
-    /**
-     * Called by start(), if successful, just prior to returning.
-     */
-    protected void onStart() {}
-
-    /**
-     * Called by stop() just prior to returning.
-     */
-    protected void onStop() {}
-
-    private void createAndRegisterFd() {
-        if (mFd != null) return;
-
-        try {
-            mFd = createFd();
-        } catch (Exception e) {
-            logError("Failed to create socket: ", e);
-            closeFd(mFd);
-            mFd = null;
-        }
-
-        if (mFd == null) return;
-
-        mQueue.addOnFileDescriptorEventListener(
-                mFd,
-                FD_EVENTS,
-                (fd, events) -> {
-                    // Always call handleInput() so read/recvfrom are given
-                    // a proper chance to encounter a meaningful errno and
-                    // perhaps log a useful error message.
-                    if (!isRunning() || !handleInput()) {
-                        unregisterAndDestroyFd();
-                        return UNREGISTER_THIS_FD;
-                    }
-                    return FD_EVENTS;
-                });
-        onStart();
-    }
-
-    private boolean isRunning() {
-        return (mFd != null) && mFd.valid();
-    }
-
-    // Keep trying to read until we get EAGAIN/EWOULDBLOCK or some fatal error.
-    private boolean handleInput() {
-        while (isRunning()) {
-            final int bytesRead;
-
-            try {
-                bytesRead = readPacket(mFd, mBuffer);
-                if (bytesRead < 1) {
-                    if (isRunning()) logError("Socket closed, exiting", null);
-                    break;
-                }
-                mPacketsReceived++;
-            } catch (ErrnoException e) {
-                if (e.errno == OsConstants.EAGAIN) {
-                    // We've read everything there is to read this time around.
-                    return true;
-                } else if (e.errno == OsConstants.EINTR) {
-                    continue;
-                } else {
-                    if (isRunning()) logError("readPacket error: ", e);
-                    break;
-                }
-            } catch (Exception e) {
-                if (isRunning()) logError("readPacket error: ", e);
-                break;
-            }
-
-            try {
-                handlePacket(mBuffer, bytesRead);
-            } catch (Exception e) {
-                logError("handlePacket error: ", e);
-                break;
-            }
-        }
-
-        return false;
-    }
-
-    private void unregisterAndDestroyFd() {
-        if (mFd == null) return;
-
-        mQueue.removeOnFileDescriptorEventListener(mFd);
-        closeFd(mFd);
-        mFd = null;
-        onStop();
-    }
-
-    private boolean onCorrectThread() {
-        return (mHandler.getLooper() == Looper.myLooper());
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/utils/PacketReader.java b/src/java/com/android/internal/net/ipsec/ike/utils/PacketReader.java
deleted file mode 100644
index cd6b98d..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/utils/PacketReader.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.utils;
-
-import static java.lang.Math.max;
-
-import android.os.Handler;
-import android.system.Os;
-
-import java.io.FileDescriptor;
-
-/**
- * Specialization of {@link FdEventsReader} that reads packets into a byte array.
- *
- * TODO: rename this class to something more correctly descriptive (something
- * like [or less horrible than] IkeFdReadEventsHandler?).
- *
- * <p> This code is a exact copy of {@link PacketReader} in
- * frameworks/base/packages/NetworkStack/src/android/net/util/PacketReader.java, except the class
- * name is changed to avoid confusion.
- *
- * FIXME: b/130058477 Find a way to share the code between network stack and code outside.
- *
- * @hide
- */
-public abstract class PacketReader extends FdEventsReader<byte[]> {
-
-    public static final int DEFAULT_RECV_BUF_SIZE = 2 * 1024;
-
-    protected PacketReader(Handler h) {
-        this(h, DEFAULT_RECV_BUF_SIZE);
-    }
-
-    protected PacketReader(Handler h, int recvBufSize) {
-        super(h, new byte[max(recvBufSize, DEFAULT_RECV_BUF_SIZE)]);
-    }
-
-    @Override
-    protected final int recvBufSize(byte[] buffer) {
-        return buffer.length;
-    }
-
-    /**
-     * Subclasses MAY override this to change the default read() implementation
-     * in favour of, say, recvfrom().
-     *
-     * Implementations MUST return the bytes read or throw an Exception.
-     */
-    @Override
-    protected int readPacket(FileDescriptor fd, byte[] packetBuffer) throws Exception {
-        return Os.read(fd, packetBuffer, 0, packetBuffer.length);
-    }
-}
diff --git a/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java b/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java
deleted file mode 100644
index 778d685..0000000
--- a/src/java/com/android/internal/net/ipsec/ike/utils/Retransmitter.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.utils;
-
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RETRANSMIT;
-
-import android.os.Handler;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-
-/**
- * Retransmitter represents a class that will send a message and trigger delayed retransmissions
- *
- * <p>The Retransmitter class will queue retransmission signals on the provided handler. The owner
- * of this retransmitter instance is expected to wait for the signal, and call retransmit() on the
- * instance of this class.
- */
-public abstract class Retransmitter {
-    private static IBackoffTimeoutCalculator sBackoffTimeoutCalculator =
-            new BackoffTimeoutCalculator();
-
-    /*
-     * Retransmit parameters
-     *
-     * (Re)transmission count   | Relative timeout  | Absolute timeout
-     * -------------------------+-------------------+------------------
-     * 0                        | 500ms             | 500ms
-     * 1                        | 1s                | 1.5s
-     * 2                        | 2s                | 3.5s
-     * 3                        | 4s                | 7.5s
-     * 4                        | 8s                | 15.5s
-     * 5                        | 16s               | 31.5s
-     *
-     * TODO: Add retransmitter configurability
-     */
-    static final double RETRANSMIT_BACKOFF_FACTOR = 2.0;
-    static final long RETRANSMIT_TIMEOUT_MS = 500L;
-    static final int RETRANSMIT_MAX_ATTEMPTS = 5;
-
-    private final Handler mHandler;
-    private final IkeMessage mRetransmitMsg;
-    private int mRetransmitCount = 0;
-
-    public Retransmitter(Handler handler, IkeMessage msg) {
-        mHandler = handler;
-        mRetransmitMsg = msg;
-    }
-
-    /**
-     * Triggers a (re)transmission. Will enqueue a future retransmission signal on the given handler
-     */
-    public void retransmit() {
-        if (mRetransmitMsg == null) {
-            return;
-        }
-
-        // If the failed iteration is beyond the max attempts, clean up and shut down.
-        if (mRetransmitCount > RETRANSMIT_MAX_ATTEMPTS) {
-            handleRetransmissionFailure();
-            return;
-        }
-
-        send(mRetransmitMsg);
-
-        long timeout = sBackoffTimeoutCalculator.getExponentialBackoffTimeout(mRetransmitCount++);
-        mHandler.sendMessageDelayed(mHandler.obtainMessage(CMD_RETRANSMIT, this), timeout);
-    }
-
-    /** Cancels any future retransmissions */
-    public void stopRetransmitting() {
-        mHandler.removeMessages(CMD_RETRANSMIT, this);
-    }
-
-    /** Retrieves the message this retransmitter is tracking */
-    public IkeMessage getMessage() {
-        return mRetransmitMsg;
-    }
-
-    /**
-     * Implementation-provided sender
-     *
-     * <p>For Retransmitter-internal use only.
-     *
-     * @param msg the message to be sent
-     */
-    protected abstract void send(IkeMessage msg);
-
-    /**
-     * Callback for implementations to be informed that we have reached the max retransmissions.
-     *
-     * <p>For Retransmitter-internal use only.
-     */
-    protected abstract void handleRetransmissionFailure();
-
-    /**
-     * IBackoffTimeoutCalculator provides interface for calculating retransmission backoff timeout.
-     *
-     * <p>IBackoffTimeoutCalculator exists so that the interface is injectable for testing.
-     */
-    @VisibleForTesting
-    public interface IBackoffTimeoutCalculator {
-        /** Calculate retransmission backoff timeout */
-        long getExponentialBackoffTimeout(int retransmitCount);
-    }
-
-    private static final class BackoffTimeoutCalculator implements IBackoffTimeoutCalculator {
-        @Override
-        public long getExponentialBackoffTimeout(int retransmitCount) {
-            double expBackoffFactor = Math.pow(RETRANSMIT_BACKOFF_FACTOR, retransmitCount);
-            return (long) (RETRANSMIT_TIMEOUT_MS * expBackoffFactor);
-        }
-    }
-
-    /** Sets IBackoffTimeoutCalculator */
-    @VisibleForTesting
-    public static void setBackoffTimeoutCalculator(IBackoffTimeoutCalculator calculator) {
-        sBackoffTimeoutCalculator = calculator;
-    }
-
-    /** Resets BackoffTimeoutCalculator of retransmitter */
-    @VisibleForTesting
-    public static void resetBackoffTimeoutCalculator() {
-        sBackoffTimeoutCalculator = new BackoffTimeoutCalculator();
-    }
-}
diff --git a/src/java/com/android/internal/net/utils/Log.java b/src/java/com/android/internal/net/utils/Log.java
deleted file mode 100644
index 55ea091..0000000
--- a/src/java/com/android/internal/net/utils/Log.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.utils;
-
-import android.os.Build;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.Locale;
-import java.util.Objects;
-
-/**
- * Manages logging for all IKE packages. Wraps Android's Log class to prevent leakage of PII.
- */
-public class Log {
-    private final String mTAG;
-    private final boolean mIsEngBuild;
-    private final boolean mLogSensitive;
-
-    /**
-     * Constructs a Log instance configured with the given tag and logSensitive flag
-     *
-     * @param tag the String tag to be used for this Log's logging
-     * @param logSensitive boolean flag marking whether sensitive data (PII) should be logged
-     */
-    public Log(String tag, boolean logSensitive) {
-        this(tag, Build.IS_ENG, logSensitive);
-    }
-
-    @VisibleForTesting
-    Log(String tag, boolean isEngBuild, boolean logSensitive) {
-        this.mTAG = tag;
-        this.mIsEngBuild = isEngBuild;
-        this.mLogSensitive = logSensitive;
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#VERBOSE} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     */
-    public void v(String prefix, String msg) {
-        if (isLoggable(android.util.Log.VERBOSE)) {
-            android.util.Log.v(mTAG, prefix + ": " + msg);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#VERBOSE} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     * @param tr an Exception to log
-     */
-    public void v(String prefix, String msg, Throwable tr) {
-        if (isLoggable(android.util.Log.VERBOSE)) {
-            android.util.Log.v(mTAG, prefix + ": " + msg, tr);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#DEBUG} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     */
-    public void d(String prefix, String msg) {
-        if (isLoggable(android.util.Log.DEBUG)) {
-            android.util.Log.d(mTAG, prefix + ": " + msg);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#DEBUG} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     * @param tr an Exception to log
-     */
-    public void d(String prefix, String msg, Throwable tr) {
-        if (isLoggable(android.util.Log.DEBUG)) {
-            android.util.Log.d(mTAG, prefix + ": " + msg, tr);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#INFO} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     */
-    public void i(String prefix, String msg) {
-        if (isLoggable(android.util.Log.INFO)) {
-            android.util.Log.i(mTAG, prefix + ": " + msg);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#INFO} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     * @param tr an Exception to log
-     */
-    public void i(String prefix, String msg, Throwable tr) {
-        if (isLoggable(android.util.Log.INFO)) {
-            android.util.Log.i(mTAG, prefix + ": " + msg, tr);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#WARN} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     */
-    public void w(String prefix, String msg) {
-        if (isLoggable(android.util.Log.WARN)) {
-            android.util.Log.w(mTAG, prefix + ": " + msg);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#WARN} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     * @param tr an Exception to log
-     */
-    public void w(String prefix, String msg, Throwable tr) {
-        if (isLoggable(android.util.Log.WARN)) {
-            android.util.Log.w(mTAG, prefix + ": " + msg, tr);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#ERROR} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     */
-    public void e(String prefix, String msg) {
-        if (isLoggable(android.util.Log.ERROR)) {
-            android.util.Log.e(mTAG, prefix + ": " + msg);
-        }
-    }
-
-    /**
-     * Logs the given prefix and msg Strings.
-     *
-     * <p>Note: Logging is only done if this instance's logging level is {@link
-     * android.util.Log#ERROR} or higher.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     * @param tr an Exception to log
-     */
-    public void e(String prefix, String msg, Throwable tr) {
-        if (isLoggable(android.util.Log.ERROR)) {
-            android.util.Log.e(mTAG, prefix + ": " + msg, tr);
-        }
-    }
-
-    /**
-     * What a Terrible Failure: Report a condition that should never happen.
-     * The error will always be logged at level ASSERT with the call stack.
-     * Depending on system configuration, a report may be added to the
-     * {@link android.os.DropBoxManager} and/or the process may be terminated
-     * immediately with an error dialog.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     */
-    public void wtf(String prefix, String msg) {
-        android.util.Log.wtf(mTAG, prefix + ": " + msg);
-
-    }
-
-    /**
-     * What a Terrible Failure: Report a condition that should never happen.
-     * The error will always be logged at level ASSERT with the call stack.
-     * Depending on system configuration, a report may be added to the
-     * {@link android.os.DropBoxManager} and/or the process may be terminated
-     * immediately with an error dialog.
-     *
-     * @param prefix the String prefix to be used for this log entry
-     * @param msg the String msg to be logged
-     * @param tr an Exception to log
-     */
-    public void wtf(String prefix, String msg, Throwable tr) {
-        android.util.Log.wtf(mTAG, prefix + ": " + msg, tr);
-    }
-
-    /**
-     * Returns a String-formatted version of the given PII.
-     *
-     * <p>Depending on the logging configurations and build-type, the returned PII may be
-     * obfuscated.
-     *
-     * @param pii the PII to be formatted
-     * @return the String-formatted version of the PII
-     */
-    public String pii(Object pii) {
-        if (!mIsEngBuild || !mLogSensitive) {
-            return String.valueOf(Objects.hashCode(pii));
-        } else {
-            if (pii instanceof byte[]) {
-                return byteArrayToHexString((byte[]) pii);
-            }
-            return String.valueOf(pii);
-        }
-    }
-
-    /**
-     * Checks whether the given logging level (defined in {@link android.util.Log}) is loggable for
-     * this Log.
-     *
-     * @param level the logging level to be checked for being loggable
-     * @return true iff level is at the configured logging level or higher
-     */
-    private boolean isLoggable(int level) {
-        return android.util.Log.isLoggable(mTAG, level);
-    }
-
-    /**
-     * Returns the hex-String representation of the given byte[].
-     *
-     * @param data the byte[] to be represented
-     * @return the String representation of data
-     */
-    public static String byteArrayToHexString(byte[] data) {
-        if (data == null || data.length == 0) {
-            return "";
-        }
-
-        StringBuilder sb = new StringBuilder();
-        for (byte b : data) {
-            sb.append(String.format(Locale.US, "%02X", b));
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/java/com/android/internal/net/utils/SimpleStateMachine.java b/src/java/com/android/internal/net/utils/SimpleStateMachine.java
deleted file mode 100644
index a2fffdd..0000000
--- a/src/java/com/android/internal/net/utils/SimpleStateMachine.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.utils;
-
-/**
- * SimpleStateMachine provides a minimal, synchronous state machine framework.
- *
- * <p>This state machine is of limited functionality, but sufficient for implementation of simple
- * protocols. Due to the limited functionality, it is also easy to read and maintain.
- *
- * SimpleStateMachine defaults to the null state. Implementers should immediately transition
- * to their default state when instantiated.
- *
- * @param <T> The input message type.
- * @param <R> The result type. For SimpleStateMachines without a return value, use {@link
- *     java.lang.Void}
- */
-public abstract class SimpleStateMachine<T, R> {
-    protected final SimpleState mNullState =
-            new SimpleState() {
-                public R process(T msg) {
-                    throw new IllegalStateException("Process called on null state");
-                }
-            };
-
-    protected SimpleState mState = mNullState;
-
-    // Non-static to allow for compiler verification of T, R from SimpleStateMachine
-    protected abstract class SimpleState {
-        public abstract R process(T msg);
-    }
-
-    /**
-     * Processes the given message based on the current {@link SimpleState}
-     *
-     * @param msg The message to be processed by the current state
-     * @return The result of the processing by the current state
-     */
-    public R process(T msg) {
-        return mState.process(msg);
-    }
-
-    /**
-     * Transitions to a new state
-     *
-     * @param newState The {@link SimpleState} that the {@link SimpleStateMachine} should
-     *     transition to
-     * @throws IllegalArgumentException if newState is null
-     */
-    protected void transitionTo(SimpleState newState) {
-        if (newState == null) {
-            throw new IllegalArgumentException("SimpleState value must be non-null.");
-        }
-
-        mState = newState;
-    }
-
-    /**
-     * Transitions to a new state, and lets the new state process the given message
-     *
-     * @param newState The {@link SimpleState} that the {@link SimpleStateMachine} should transition
-     *     to. This state will immediately be requested to process the given message.
-     * @param msg The message that should be processed by the new state
-     * @return The result of the processing by the new state
-     * @throws IllegalArgumentException if newState is null
-     */
-    protected R transitionAndProcess(SimpleState newState, T msg) {
-        transitionTo(newState);
-        return mState.process(msg);
-    }
-}
diff --git a/tests/Android.mk b/tests/Android.mk
new file mode 100644
index 0000000..caa27f6
--- /dev/null
+++ b/tests/Android.mk
@@ -0,0 +1,18 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
\ No newline at end of file
diff --git a/tests/iketests/Android.bp b/tests/iketests/Android.bp
deleted file mode 100644
index c526353..0000000
--- a/tests/iketests/Android.bp
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (C) 2018 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.
-
-android_test {
-    name: "FrameworksIkeTests",
-
-    srcs: ["src/java/**/*.java"],
-
-    platform_apis: false,
-    certificate: "platform",
-    test_suites: ["device-tests"],
-
-    libs: ["android.test.runner"],
-
-    static_libs: [
-        "ike",
-        "androidx.test.rules",
-        "frameworks-base-testutils",
-        "mockito-target-inline-minus-junit4",
-        "services.core",
-    ],
-
-    jni_libs: [
-        "libdexmakerjvmtiagent",
-        "libstaticjvmtiagent",
-        "libmultiplejvmtiagentsinterferenceagent",
-    ],
-}
diff --git a/tests/iketests/Android.mk b/tests/iketests/Android.mk
new file mode 100644
index 0000000..0da49b4
--- /dev/null
+++ b/tests/iketests/Android.mk
@@ -0,0 +1,35 @@
+# Copyright (C) 2018 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+LOCAL_PATH := $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src/java)
+
+LOCAL_PACKAGE_NAME := FrameworksIkeTests
+LOCAL_PRIVATE_PLATFORM_APIS := false
+LOCAL_CERTIFICATE := platform
+LOCAL_COMPATIBILITY_SUITE := device-tests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_STATIC_JAVA_LIBRARIES := ike \
+        androidx.test.rules \
+        frameworks-base-testutils \
+        mockito-target-minus-junit4 \
+        NetworkStackBase
+
+include $(BUILD_PACKAGE)
\ No newline at end of file
diff --git a/tests/iketests/AndroidManifest.xml b/tests/iketests/AndroidManifest.xml
index 7260e62..d69cbc8 100644
--- a/tests/iketests/AndroidManifest.xml
+++ b/tests/iketests/AndroidManifest.xml
@@ -20,14 +20,7 @@
 
     <uses-permission android:name="android.permission.INTERNET"/>
 
-    <!--
-       'debuggable=true' is required to properly load mockito jvmti dependencies,
-        otherwise it gives the following error at runtime:
-
-        Openjdkjvmti plugin was loaded on a non-debuggable Runtime.
-        Plugin was loaded too late to change runtime state to DEBUGGABLE.
-    -->
-    <application android:label="FrameworksIkeTests" android:debuggable="true">
+    <application android:label="FrameworksIkeTests">
         <uses-library android:name="android.test.runner" />
     </application>
 
diff --git a/tests/iketests/assets/key/end-cert-key-a.key b/tests/iketests/assets/key/end-cert-key-a.key
deleted file mode 100644
index a506a35..0000000
--- a/tests/iketests/assets/key/end-cert-key-a.key
+++ /dev/null
@@ -1,10 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAphl0fstit/XcelkX
-2iKoosGsZ2U5rU+mYWR/9RJIY+qR3OYrBeqqtdvjPOu2fNjHEtsO//dCRvdxVWdx
-20ADPQIDAQABAkApsawXg/Bk4zeUErc1D4wrRtiDH9rJkXvfaL3iA9PeGIU2j2ci
-WwqbJY6HhGSJiNAKMVHRMRAtoaBeX80DOqH1AiEA0pWj6kItG2zTww09sqc6ymTc
-1aknFaGuXZY+RO0MTF8CIQDJ68uKQ8LV6labUnnmLPUnIYfVPY8XTNpvkwazeTuV
-4wIgDy60u637vI9zEQwCV8AQ0AjHlyvz4m5euOadJLEGgvcCIQCc9BpsySsjmFnl
-tgBm+L8+wYOSL52QYP7SB5kH3M6CPQIgQQIVYRKf44G9agh09utnaiw11FCwRr0M
-EKsdiVmkw+o=
------END PRIVATE KEY-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/end-cert-a.pem b/tests/iketests/assets/pem/end-cert-a.pem
deleted file mode 100644
index 2e87295..0000000
--- a/tests/iketests/assets/pem/end-cert-a.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDRzCCAi+gAwIBAgIIZSciRUaEUakwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxHDAaBgNVBAMTE2NhLnRlc3QuYW5kcm9p
-ZC5uZXQwHhcNMTkwNzE2MTcxODMxWhcNMjQwNzE0MTcxODMxWjBBMQswCQYDVQQG
-EwJVUzEQMA4GA1UEChMHQW5kcm9pZDEgMB4GA1UEAxMXc2VydmVyLnRlc3QuYW5k
-cm9pZC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpU5M+c3Qg
-Sej5NeCboB5T6R0XaODqo/hpZFkjTXt5ku2lvsioLU0xC38K9Cym7kPU0kGMAl1p
-tatMZ2Uxde/sDiLyFwYgx//TniDNnxdDXYYxcZNbfV4ERcuPmTexq9t86MneVkxn
-hJ9dEBJcr2goFaFIebCUlj3DF827/JQhWgV54M9trPOGOyoRy5HvH+IxOOt8PXaL
-vySQZxo4bC6m+qeQQZCgZAwvGagFF9KjVFyKt9ZAVp97wQi7yo+Bzm5I54C4EUbT
-XnTRITQXqFKOUXVGYPChwgZTEz/2s6Wh1CR0LjNFTaDMlsUJkUbGn27iZc90nd5w
-6WAXYQgsmXnTAgMBAAGjRzBFMB8GA1UdIwQYMBaAFGYUzuvZUaVJl8mcxejuFiUN
-GcTfMCIGA1UdEQQbMBmCF3NlcnZlci50ZXN0LmFuZHJvaWQubmV0MA0GCSqGSIb3
-DQEBCwUAA4IBAQByajAzcLrMc2gjDSzTd+5/VTgLhoJfJul3FgsUzZHa9EiRUChV
-O94ZCLWWoZxeB0iejaUqrLz/xCJqeC3wbNP7LejiW2qgUAoJdOvNtDGiVx2P7wid
-iXS4y49+IYP+T1BVWNNrI+zcAycN2uiQlEKR5KQ3cNXVHZoiVOroheHzi8ezSeYM
-j5bhJ2GbpOw9/4PkaBonnQNs9sljkyZ2keYrir1xzf4PI9gieXniJcNuAjYNaAAA
-oaHKXah9NggbAVEXEZjLoKtQQqWFz9wNE8AXsIdoD4gOeBuwNQSyn+FmDJdI/mpA
-enbz3qbTVurltTHySye0+nhlP7XTifyEanXM
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/end-cert-b.pem b/tests/iketests/assets/pem/end-cert-b.pem
deleted file mode 100644
index f25d352..0000000
--- a/tests/iketests/assets/pem/end-cert-b.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDWDCCAkCgAwIBAgIIRs9N2RKvOUYwDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0LmFu
-ZHJvaWQubmV0MB4XDTE5MDkzMDE4NDg1MVoXDTI0MDkyODE4NDg1MVowQTELMAkG
-A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3NlcnZlci50ZXN0
-LmFuZHJvaWQubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxmhy
-posM/dhFPvmHpiqk+bJR2yfw5AeWhspnjuIJB1X3/TFCRTmLLsQ8VGRQnSKYlAYJ
-2r5XpgYQ09r4DYAbHwL2oSYtktMzqax22JlR73czZH4D3UTtKk7CdLtc1NPFXYFm
-lJ9uE/TD1pXvXwj9vdYp8tVuls2Rv+hBNtgM4nT1FqyMpp1sr5t2LIdx+WpDR4PC
-8C7HExeuw4wOBY6mWp4uErWqDFBfQNI3dzwpySRtnuMVKSX5Qcj6Z+bqKmtAgAnZ
-qdoLegn4sBbELDFW1QYNqp9QgdJO9P9R2lI8LZvKcd2yB8zJ2+JK1Efh9ErzhqFn
-Rc1BzbsBxKJBbppZXQIDAQABo1QwUjAfBgNVHSMEGDAWgBRypK7W5FhP8MtsugM1
-TPfyca8IpDAaBgNVHREEEzARgg9pa2UuYW5kcm9pZC5uZXQwEwYDVR0lBAwwCgYI
-KwYBBQUHAwEwDQYJKoZIhvcNAQELBQADggEBADJu4bfbDO/PUSjTMuH1u6x9iTdx
-PKVkzFHqeiAsEKccyenuFKrwkkoIF+gieJeKKDj6lKFDP4uPOYIuNxs9td8G52+1
-5XKX2v9heaw6uFU3AlMmoAHKwIiM+U6eweuG+rVG2doTbMW2OOrEfJ5mgQtky7tx
-EIPUL9gUpAKqvsC7pJ7nrakm6TBkhYaTtDYOvdD97LyH9/5h32WKn9zU2H4dog+4
-87K6icdjBpd4ViPXbOBuOLvEsnMDmbSC3/12hv59swAf865SZN10B7ScYbg/yS9V
-x2YtMxPMNOOqC71Z/JE5mc80Un0nd9eJFxPueWqeH/4cGA6gL7ZtAeor0BE=
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/end-cert-small.pem b/tests/iketests/assets/pem/end-cert-small.pem
deleted file mode 100644
index b21aa0d..0000000
--- a/tests/iketests/assets/pem/end-cert-small.pem
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBtjCCAWCgAwIBAgIIC0mN0a99ZR0wDQYJKoZIhvcNAQELBQAwQzELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIjAgBgNVBAMTGXNtYWxsLmNhLnRlc3Qu
-YW5kcm9pZC5uZXQwHhcNMTkwNzE2MjIyMzM0WhcNMjQwNzE0MjIyMzM0WjBHMQsw
-CQYDVQQGEwJVUzEQMA4GA1UEChMHQW5kcm9pZDEmMCQGA1UEAxMdc21hbGwuc2Vy
-dmVyLnRlc3QuYW5kcm9pZC5uZXQwXDANBgkqhkiG9w0BAQEFAANLADBIAkEAphl0
-fstit/XcelkX2iKoosGsZ2U5rU+mYWR/9RJIY+qR3OYrBeqqtdvjPOu2fNjHEtsO
-//dCRvdxVWdx20ADPQIDAQABozQwMjAfBgNVHSMEGDAWgBRuPvsaYu/KSLILNs2l
-qzN0Q3bo8jAPBgNVHREECDAGhwTAqCuKMA0GCSqGSIb3DQEBCwUAA0EA1HWQseq+
-kfL5YaYN7Klb3WiPPg8Vxj4dMNYiQTSH7AG7Gt1Yc6NqBLhmMpa+1T+gwlDdvkD4
-RPIxjfK12sbbog==
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/intermediate-ca-b-one.pem b/tests/iketests/assets/pem/intermediate-ca-b-one.pem
deleted file mode 100644
index 707e575..0000000
--- a/tests/iketests/assets/pem/intermediate-ca-b-one.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDaDCCAlCgAwIBAgIIIbjMyRn2770wDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h
-bmRyb2lkLm5ldDAeFw0xOTA5MzAxODQzMThaFw0yNDA5MjgxODQzMThaMEExCzAJ
-BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSAwHgYDVQQDExdvbmUuY2EudGVz
-dC5hbmRyb2lkLm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKNN
-sRr5Z30rAEw2jrAh/BIekbEy/MvOucAr1w0lxH71p+ybRBx5Bj7G07UGXbL659gm
-meMV6nabY4HjQXNMq22POiJBZj+U+rw34br6waljBttxCmmJac1VvgqNsSspXjRy
-NbiVQdFjyKSX0NOPcEkwANk15mZbOgJBaYYc8jQCY2G/p8eARVBTLJCy8LEwEU6j
-XRv/4eYST79qpBFc7gQQj2FLmh9oppDIvcIVBHwtd1tBoVuehRSud1o8vQRkl/HJ
-Mrwp24nO5YYhmVNSFRtBpmWMSu1KknFUwkOebINUNsKXXHebVa7cP4XIQUL8mRT3
-5X9rFJFSQJE01S3NjNMCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B
-Af8EBAMCAQYwHQYDVR0OBBYEFHK3FIm7g8dxEIwK9zMAO8EWhRYxMB8GA1UdIwQY
-MBaAFEmfqEeF14Nj91ekIpR+sVhCEoAaMA0GCSqGSIb3DQEBCwUAA4IBAQAeMlXT
-TnxZo8oz0204gKZ63RzlgDpJ7SqA3qFG+pV+TiqGfSuVkXuIdOskjxJnA9VxUzrr
-LdMTCn5e0FK6wCYjZ2GT/CD7oD3vSMkzGbLGNcNJhhDHUq8BOLPkPzz/rwQFPBSb
-zr6hsiVXphEt/psGoN7Eu9blPeQaIwMfWnaufAwF664S/3dmCRbNMWSam1qzzz8q
-jr0cDOIMa//ZIAcM16cvoBK6pFGnUmuoJYYRtfpY5MmfCWz0sCJxENIX/lxyhd7N
-FdRALA1ZP3E//Tn2vQoeFjbKaAba527RE26HgHJ9zZDo1nn8J8J/YwYRJdBWM/3S
-LYebNiMtcyB5nIkj
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/intermediate-ca-b-two.pem b/tests/iketests/assets/pem/intermediate-ca-b-two.pem
deleted file mode 100644
index 39808f8..0000000
--- a/tests/iketests/assets/pem/intermediate-ca-b-two.pem
+++ /dev/null
@@ -1,21 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgIIKWCREnNCs+wwDQYJKoZIhvcNAQELBQAwQTELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF29uZS5jYS50ZXN0LmFu
-ZHJvaWQubmV0MB4XDTE5MDkzMDE4NDQwMloXDTI0MDkyODE4NDQwMlowQTELMAkG
-A1UEBhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIDAeBgNVBAMTF3R3by5jYS50ZXN0
-LmFuZHJvaWQubmV0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLUa
-RqkYl2m7lUmMnkooqO0DNNY1aN9r7mJc3ndYn5gjkpb3yLgOYPDNLcQerV6uWk/u
-qKudNHed2dInGonl3oxwwv7++6oUvvtrSWLDZlRg16GsdIE1Y98DSMQWkSxevYy9
-Nh6FGTdlBFQVMpiMa8qHEkrOyKsy85yCW1sgzlpGTIBwbDAqYtwe3rgbwyHwUtfy
-0EU++DBcR4ll/pDqB0OQtW5E3AOq2GH1iaGeFLKSUQ5KAbdI8y4/b8IkSDffvxcc
-kXig7S54aLrNlL/ZjQ+H4Chgjj2A5wMucd81+Fb60Udej73ICL9PpMPnXQ1+BVYd
-MJ/txjLNmrOJG9yEHQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
-/wQEAwIBBjAdBgNVHQ4EFgQUcqSu1uRYT/DLbLoDNUz38nGvCKQwHwYDVR0jBBgw
-FoAUcrcUibuDx3EQjAr3MwA7wRaFFjEwDQYJKoZIhvcNAQELBQADggEBADY461GT
-Rw0dGnD07xaGJcI0i0pV+WnGSrl1s1PAIdMYihJAqYnh10fXbFXLm2WMWVmv/pxs
-FI/xDJno+pd4mCa/sIhm63ar/Nv+lFQmcpIlvSlKnhhV4SLNBeqbVhPBGTCHfrG4
-aIyCwm1KJsnkWbf03crhSskR/2CXIjX6lcAy7K3fE2u1ELpAdH0kMJR7VXkLFLUm
-gqe9YCluR0weMpe2sCaOGzdVzQSmMMCzGP5cxeFR5U6K40kMOpiW11JNmQ06xI/m
-YVkMNwoiV/ITT0/C/g9FxJmkO0mVSLEqxaLS/hNiQNDlroVM0rbxhzviXLI3R3AO
-50VvlOQYGxWed/I=
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/self-signed-ca-a.pem b/tests/iketests/assets/pem/self-signed-ca-a.pem
deleted file mode 100644
index 5135ea7..0000000
--- a/tests/iketests/assets/pem/self-signed-ca-a.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDPjCCAiagAwIBAgIICrKLpR7LxlowDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxHDAaBgNVBAMTE2NhLnRlc3QuYW5kcm9p
-ZC5uZXQwHhcNMTkwNzE2MTcxNTUyWhcNMjkwNzEzMTcxNTUyWjA9MQswCQYDVQQG
-EwJVUzEQMA4GA1UEChMHQW5kcm9pZDEcMBoGA1UEAxMTY2EudGVzdC5hbmRyb2lk
-Lm5ldDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANsvTwad2Nie0VOy
-Xb1VtHL0R760Jm4vr14JWMcX4oiE6jUdTNdXQ0CGb65wvulP2aEeukFH0D/cvBMR
-Bv9+haEwo9/grIXg9ALNKp+GfuZYw/dfnUMHFn3g2+SUgP6BoMZc4lkHktjkDKxp
-99Q6h4NP/ip1labkhBeB9+Z6l78LTixKRKspNITWASJed9bjzshYxKHi6dJy3maQ
-1LwYKmK7PEGRpoDoT8yZhFbxsVDUojGnJKH1RLXVOn/psG6dI/+IsbTipAttj5zc
-g2VAD56PZG2Jd+vsup+g4Dy72hyy242x5c/H2LKZn4X0B0B+IXyii/ZVc+DJldQ5
-JqplOL8CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-HQYDVR0OBBYEFGYUzuvZUaVJl8mcxejuFiUNGcTfMA0GCSqGSIb3DQEBCwUAA4IB
-AQDQYeqjvHsK2ZqSqxakDp0nu36Plbj48Wvx1ru7GW2faz7i0w/Zkxh06zniILCb
-QJRjDebSTHc5SSbCFrRTvqagaLDhbH42/hQncWqIoJqW+pmznJET4JiBO0sqzm05
-yQWsLI/h9Ir28Y2g5N+XPBU0VVVejQqH4iI0iwQx7y7ABssQ0Xa/K73VPbeGaKd6
-Prt4wjJvTlIL2yE2+0MggJ3F2rNptL5SDpg3g+4/YQ6wVRBFil95kUqplEsCtU4P
-t+8RghiEmsRx/8CywKfZ5Hex87ODhsSDmDApcefbd5gxoWVkqxZUkPcKwYv1ucm8
-u4r44fj4/9W0Zeooav5Yoh1q
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/self-signed-ca-b.pem b/tests/iketests/assets/pem/self-signed-ca-b.pem
deleted file mode 100644
index 972fd55..0000000
--- a/tests/iketests/assets/pem/self-signed-ca-b.pem
+++ /dev/null
@@ -1,20 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDSDCCAjCgAwIBAgIITJQJ6HC1rjwwDQYJKoZIhvcNAQELBQAwQjELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxITAfBgNVBAMTGHJvb3QuY2EudGVzdC5h
-bmRyb2lkLm5ldDAeFw0xOTA5MzAxNzU1NTJaFw0yOTA5MjcxNzU1NTJaMEIxCzAJ
-BgNVBAYTAlVTMRAwDgYDVQQKEwdBbmRyb2lkMSEwHwYDVQQDExhyb290LmNhLnRl
-c3QuYW5kcm9pZC5uZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCT
-q3hGF+JvLaB1xW7KGKmaxiQ7BxX2Sn7cbp7ggoVYXsFlBUuPPv3+Vg5PfPCPhsJ8
-/7w4HyKo3uc/vHs5HpQ7rSd9blhAkfmJci2ULLq73FB8Mix4CzPwMx29RrN1X9bU
-z4G0vJMczIBGxbZ0uw7n8bKcXBV7AIeax+J8lseEZ3k8iSuBkUJqGIpPFKTqByFZ
-A1Lvt47xkON5SZh6c/Oe+o6291wXaCOJUSAKv6PAWZkq9HeD2fqKA/ck9dBaz1M3
-YvzQ9V/7so3/dECjAfKia388h1I6XSGNUM+d5hpxMXpAFgG42eUXHpJ10OjDvSwd
-7ZSC91/kRQewUomEKBK1AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
-AQH/BAQDAgEGMB0GA1UdDgQWBBRJn6hHhdeDY/dXpCKUfrFYQhKAGjANBgkqhkiG
-9w0BAQsFAAOCAQEAig/94aGfHBhZuvbbhwAK4rUNpizmR567u0ZJ+QUEKyAlo9lT
-ZWYHSm7qTAZYvPEjzTQIptnAlxCHePXh3Cfwgo+r82lhG2rcdI03iRyvHWjM8gyk
-BXCJTi0Q08JHHpTP6GnAqpz58qEIFkk8P766zNXdhYrGPOydF+p7MFcb1Zv1gum3
-zmRLt0XUAMfjPUv1Bl8kTKFxH5lkMBLR1E0jnoJoTTfgRPrf9CuFSoh48n7YhoBT
-KV75xZY8b8+SuB0v6BvQmkpKZGoxBjuVsShyG7q1+4JTAtwhiP7BlkDvVkaBEi7t
-WIMFp2r2ZDisHgastNaeYFyzHYz9g1FCCrHQ4w==
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/assets/pem/self-signed-ca-small.pem b/tests/iketests/assets/pem/self-signed-ca-small.pem
deleted file mode 100644
index bb587bc..0000000
--- a/tests/iketests/assets/pem/self-signed-ca-small.pem
+++ /dev/null
@@ -1,12 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIBwDCCAWqgAwIBAgIIWKLr7BJ1wyEwDQYJKoZIhvcNAQELBQAwQzELMAkGA1UE
-BhMCVVMxEDAOBgNVBAoTB0FuZHJvaWQxIjAgBgNVBAMTGXNtYWxsLmNhLnRlc3Qu
-YW5kcm9pZC5uZXQwHhcNMTkwNzE2MjIwNjAzWhcNMjkwNzEzMjIwNjAzWjBDMQsw
-CQYDVQQGEwJVUzEQMA4GA1UEChMHQW5kcm9pZDEiMCAGA1UEAxMZc21hbGwuY2Eu
-dGVzdC5hbmRyb2lkLm5ldDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQDY/gUvbZjF
-YuslvcYduKyWeUr30dgOcC6UmAy0toNjnowtsjwp1Zqkp6+SB/vkmRatrMIDgyu9
-KXKRfy9TFUY9AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgEGMB0GA1UdDgQWBBRuPvsaYu/KSLILNs2lqzN0Q3bo8jANBgkqhkiG9w0BAQsF
-AANBAMRtcdhE8Ebew9PGNwZtfsp1KiI0ZGLE6zP9YKZYk5VZxqpr914LzEMKZpXA
-BqlgNWIcp4nRbuIhLNLyvWRdW0A=
------END CERTIFICATE-----
\ No newline at end of file
diff --git a/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java b/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
deleted file mode 100644
index eed32e3..0000000
--- a/tests/iketests/src/java/android/net/eap/EapSessionConfigTest.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.eap;
-
-import static android.net.eap.EapSessionConfig.DEFAULT_IDENTITY;
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.net.eap.EapSessionConfig.EapAkaPrimeConfig;
-import android.net.eap.EapSessionConfig.EapMethodConfig;
-import android.net.eap.EapSessionConfig.EapMsChapV2Config;
-import android.net.eap.EapSessionConfig.EapSimConfig;
-
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-
-public class EapSessionConfigTest {
-    private static final byte[] EAP_IDENTITY =
-            "test@android.net".getBytes(StandardCharsets.US_ASCII);
-    private static final int SUB_ID = 1;
-    private static final String NETWORK_NAME = "android.net";
-    private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = true;
-    private static final String USERNAME = "username";
-    private static final String PASSWORD = "password";
-
-    @Test
-    public void testBuildEapSim() {
-        EapSessionConfig result = new EapSessionConfig.Builder()
-                .setEapIdentity(EAP_IDENTITY)
-                .setEapSimConfig(SUB_ID, APPTYPE_USIM)
-                .build();
-
-        assertArrayEquals(EAP_IDENTITY, result.eapIdentity);
-
-        EapMethodConfig eapMethodConfig = result.eapConfigs.get(EAP_TYPE_SIM);
-        assertEquals(EAP_TYPE_SIM, eapMethodConfig.methodType);
-        EapSimConfig eapSimConfig = (EapSimConfig) eapMethodConfig;
-        assertEquals(SUB_ID, eapSimConfig.subId);
-        assertEquals(APPTYPE_USIM, eapSimConfig.apptype);
-    }
-
-    @Test
-    public void testBuildEapAka() {
-        EapSessionConfig result = new EapSessionConfig.Builder()
-                .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
-                .build();
-
-        assertArrayEquals(DEFAULT_IDENTITY, result.eapIdentity);
-        EapMethodConfig eapMethodConfig = result.eapConfigs.get(EAP_TYPE_AKA);
-        EapAkaConfig eapAkaConfig = (EapAkaConfig) eapMethodConfig;
-        assertEquals(SUB_ID, eapAkaConfig.subId);
-        assertEquals(APPTYPE_USIM, eapAkaConfig.apptype);
-    }
-
-    @Test
-    public void testBuildEapAkaPrime() {
-        EapSessionConfig result =
-                new EapSessionConfig.Builder()
-                        .setEapAkaPrimeConfig(
-                                SUB_ID, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES)
-                        .build();
-
-        assertEquals(DEFAULT_IDENTITY, result.eapIdentity);
-        EapMethodConfig eapMethodConfig = result.eapConfigs.get(EAP_TYPE_AKA_PRIME);
-        EapAkaPrimeConfig eapAkaPrimeConfig = (EapAkaPrimeConfig) eapMethodConfig;
-        assertEquals(SUB_ID, eapAkaPrimeConfig.subId);
-        assertEquals(APPTYPE_USIM, eapAkaPrimeConfig.apptype);
-        assertEquals(NETWORK_NAME, eapAkaPrimeConfig.networkName);
-        assertTrue(eapAkaPrimeConfig.allowMismatchedNetworkNames);
-    }
-
-    @Test
-    public void testBuildEapMsChapV2() {
-        EapSessionConfig result =
-                new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
-
-        EapMsChapV2Config config = (EapMsChapV2Config) result.eapConfigs.get(EAP_TYPE_MSCHAP_V2);
-        assertEquals(USERNAME, config.username);
-        assertEquals(PASSWORD, config.password);
-    }
-
-    @Test
-    public void testBuildWithoutConfigs() {
-        try {
-            new EapSessionConfig.Builder().build();
-            fail("build() should throw an IllegalStateException if no EAP methods are configured");
-        } catch (IllegalStateException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java b/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java
deleted file mode 100644
index 08d8994..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionConfigurationTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-
-import android.net.LinkAddress;
-
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.util.LinkedList;
-import java.util.List;
-
-public final class ChildSessionConfigurationTest {
-    private static final int IP4_PREFIX_LEN = 28;
-    private static final Inet4Address IPV4_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-    private static final Inet4Address IPV4_NETMASK =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.240"));
-    private static final LinkAddress IPV4_LINK_ADDRESS =
-            new LinkAddress(IPV4_ADDRESS, IP4_PREFIX_LEN);
-
-    private static final int IP6_PREFIX_LEN = 64;
-    private static final Inet6Address IPV6_ADDRESS =
-            (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8::1"));
-    private static final LinkAddress IPV6_LINK_ADDRESS =
-            new LinkAddress(IPV6_ADDRESS, IP6_PREFIX_LEN);
-
-    private List mMockInTsList;
-    private List mMockOutTsList;
-
-    private ConfigAttributeIpv4Address mIpv4Attr;
-    private ConfigAttributeIpv4Netmask mNetmaskAttr;
-    private ConfigAttributeIpv6Address mIpv6Attr;
-
-    @Before
-    public void setUp() throws Exception {
-        mMockInTsList = new LinkedList<IkeTrafficSelector>();
-        mMockInTsList.add(mock(IkeTrafficSelector.class));
-
-        mMockOutTsList = new LinkedList<IkeTrafficSelector>();
-        mMockOutTsList.add(mock(IkeTrafficSelector.class));
-        mMockOutTsList.add(mock(IkeTrafficSelector.class));
-
-        mIpv4Attr = new ConfigAttributeIpv4Address(IPV4_ADDRESS);
-        mNetmaskAttr = new ConfigAttributeIpv4Netmask(IPV4_NETMASK.getAddress());
-        mIpv6Attr = new ConfigAttributeIpv6Address(IPV6_LINK_ADDRESS);
-    }
-
-    private void verifySessionConfigCommon(ChildSessionConfiguration sessionConfig) {
-        verifyTsList(mMockInTsList, sessionConfig.getInboundTrafficSelectors());
-        verifyTsList(mMockOutTsList, sessionConfig.getOutboundTrafficSelectors());
-    }
-
-    private void verifyTsList(
-            List<IkeTrafficSelector> expectedList, List<IkeTrafficSelector> tsList) {
-        assertEquals(expectedList.size(), tsList.size());
-        for (int i = 0; i < expectedList.size(); i++) {
-            assertEquals(expectedList.get(i), tsList.get(i));
-        }
-    }
-
-    @Test
-    public void testBuildWithoutConfig() {
-        ChildSessionConfiguration sessionConfig =
-                new ChildSessionConfiguration(mMockInTsList, mMockOutTsList);
-
-        verifySessionConfigCommon(sessionConfig);
-    }
-
-    @Test
-    public void testBuildWithNetmaskAttr() {
-        List<ConfigAttribute> attributeList = new LinkedList<>();
-        attributeList.add(mIpv4Attr);
-        attributeList.add(mNetmaskAttr);
-        attributeList.add(mIpv6Attr);
-
-        IkeConfigPayload configPayload = new IkeConfigPayload(true /*isReply*/, attributeList);
-
-        ChildSessionConfiguration sessionConfig =
-                new ChildSessionConfiguration(mMockInTsList, mMockOutTsList, configPayload);
-
-        verifySessionConfigCommon(sessionConfig);
-
-        List<LinkAddress> expectedInternalAddrList = new LinkedList<>();
-        expectedInternalAddrList.add(IPV4_LINK_ADDRESS);
-        expectedInternalAddrList.add(IPV6_LINK_ADDRESS);
-
-        assertEquals(
-                expectedInternalAddrList.size(), sessionConfig.getInternalAddressList().size());
-        for (int i = 0; i < expectedInternalAddrList.size(); i++) {
-            assertEquals(
-                    expectedInternalAddrList.get(i), sessionConfig.getInternalAddressList().get(i));
-        }
-    }
-
-    @Test
-    public void testBuildWithoutNetmaskAttr() {
-        List<ConfigAttribute> attributeList = new LinkedList<>();
-        attributeList.add(mIpv4Attr);
-        attributeList.add(mIpv6Attr);
-
-        IkeConfigPayload configPayload = new IkeConfigPayload(true /*isReply*/, attributeList);
-
-        ChildSessionConfiguration sessionConfig =
-                new ChildSessionConfiguration(mMockInTsList, mMockOutTsList, configPayload);
-
-        verifySessionConfigCommon(sessionConfig);
-
-        List<LinkAddress> expectedInternalAddrList = new LinkedList<>();
-        expectedInternalAddrList.add(new LinkAddress(IPV4_ADDRESS, 32));
-        expectedInternalAddrList.add(IPV6_LINK_ADDRESS);
-
-        assertEquals(
-                expectedInternalAddrList.size(), sessionConfig.getInternalAddressList().size());
-        for (int i = 0; i < expectedInternalAddrList.size(); i++) {
-            assertEquals(
-                    expectedInternalAddrList.get(i), sessionConfig.getInternalAddressList().get(i));
-        }
-    }
-
-    @Test
-    public void testBuildWithConfigReq() {
-        List<ConfigAttribute> attributeList = new LinkedList<>();
-        attributeList.add(mIpv4Attr);
-        attributeList.add(mIpv6Attr);
-
-        IkeConfigPayload configPayload = new IkeConfigPayload(false /*isReply*/, attributeList);
-
-        try {
-            new ChildSessionConfiguration(mMockInTsList, mMockOutTsList, configPayload);
-            fail("Expected to fail because provided config paylaod is not a reply.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java b/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java
deleted file mode 100644
index 242957d..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/ChildSessionOptionsTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-
-public final class ChildSessionOptionsTest {
-    private static final int NUM_TS = 1;
-
-    @Test
-    public void testBuild() throws Exception {
-        ChildSaProposal saProposal =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
-                                SaProposal.KEY_LEN_AES_128)
-                        .build();
-        ChildSessionOptions sessionOptions =
-                new TunnelModeChildSessionOptions.Builder().addSaProposal(saProposal).build();
-
-        assertArrayEquals(new SaProposal[] {saProposal}, sessionOptions.getSaProposals());
-        assertEquals(NUM_TS, sessionOptions.getLocalTrafficSelectors().length);
-        assertEquals(NUM_TS, sessionOptions.getRemoteTrafficSelectors().length);
-        assertFalse(sessionOptions.isTransportMode());
-    }
-
-    @Test
-    public void testBuildWithoutSaProposal() throws Exception {
-        try {
-            new TunnelModeChildSessionOptions.Builder().build();
-            fail("Expected to fail due to the absence of SA proposal.");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java
deleted file mode 100644
index fa077d1..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionOptionsTest.java
+++ /dev/null
@@ -1,258 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthConfig;
-import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthDigitalSignLocalConfig;
-import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthDigitalSignRemoteConfig;
-import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthEapConfig;
-import static android.net.ipsec.ike.IkeSessionOptions.IkeAuthPskConfig;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.eap.EapSessionConfig;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.net.TestUtils;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.DSAPrivateKey;
-import java.security.interfaces.RSAPrivateKey;
-
-public final class IkeSessionOptionsTest {
-    private static final String PSK_HEX_STRING = "6A756E69706572313233";
-    private static final byte[] PSK = TestUtils.hexStringToByteArray(PSK_HEX_STRING);
-
-    private static final Inet4Address LOCAL_IPV4_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private static final Inet4Address REMOTE_IPV4_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-
-    private UdpEncapsulationSocket mUdpEncapSocket;
-    private IkeSaProposal mIkeSaProposal;
-    private IkeIdentification mLocalIdentification;
-    private IkeIdentification mRemoteIdentification;
-
-    private X509Certificate mMockServerCaCert;
-    private X509Certificate mMockClientEndCert;
-    private PrivateKey mMockRsaPrivateKey;
-
-    @Before
-    public void setUp() throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE);
-        mUdpEncapSocket = ipSecManager.openUdpEncapsulationSocket();
-
-        mIkeSaProposal =
-                new IkeSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
-                                SaProposal.KEY_LEN_AES_128)
-                        .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
-                        .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
-                        .build();
-        mLocalIdentification = new IkeIpv4AddrIdentification(LOCAL_IPV4_ADDRESS);
-        mRemoteIdentification = new IkeIpv4AddrIdentification(REMOTE_IPV4_ADDRESS);
-
-        mMockServerCaCert = mock(X509Certificate.class);
-        mMockClientEndCert = mock(X509Certificate.class);
-        mMockRsaPrivateKey = mock(RSAPrivateKey.class);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mUdpEncapSocket.close();
-    }
-
-    private void verifyIkeSessionOptionsCommon(IkeSessionOptions sessionOptions) {
-        assertEquals(REMOTE_IPV4_ADDRESS, sessionOptions.getServerAddress());
-        assertEquals(mUdpEncapSocket, sessionOptions.getUdpEncapsulationSocket());
-        assertArrayEquals(new SaProposal[] {mIkeSaProposal}, sessionOptions.getSaProposals());
-
-        assertEquals(mLocalIdentification, sessionOptions.getLocalIdentification());
-        assertEquals(mRemoteIdentification, sessionOptions.getRemoteIdentification());
-
-        assertFalse(sessionOptions.isIkeFragmentationSupported());
-    }
-
-    @Test
-    public void testBuildWithPsk() throws Exception {
-        IkeSessionOptions sessionOptions =
-                new IkeSessionOptions.Builder()
-                        .setServerAddress(REMOTE_IPV4_ADDRESS)
-                        .setUdpEncapsulationSocket(mUdpEncapSocket)
-                        .addSaProposal(mIkeSaProposal)
-                        .setLocalIdentification(mLocalIdentification)
-                        .setRemoteIdentification(mRemoteIdentification)
-                        .setAuthPsk(PSK)
-                        .build();
-
-        verifyIkeSessionOptionsCommon(sessionOptions);
-
-        IkeAuthConfig localConfig = sessionOptions.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthPskConfig);
-        assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PSK, localConfig.mAuthMethod);
-        assertArrayEquals(PSK, ((IkeAuthPskConfig) localConfig).mPsk);
-
-        IkeAuthConfig remoteConfig = sessionOptions.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthPskConfig);
-        assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PSK, remoteConfig.mAuthMethod);
-        assertArrayEquals(PSK, ((IkeAuthPskConfig) remoteConfig).mPsk);
-    }
-
-    @Test
-    public void testBuildWithEap() throws Exception {
-        EapSessionConfig eapConfig = mock(EapSessionConfig.class);
-
-        IkeSessionOptions sessionOptions =
-                new IkeSessionOptions.Builder()
-                        .setServerAddress(REMOTE_IPV4_ADDRESS)
-                        .setUdpEncapsulationSocket(mUdpEncapSocket)
-                        .addSaProposal(mIkeSaProposal)
-                        .setLocalIdentification(mLocalIdentification)
-                        .setRemoteIdentification(mRemoteIdentification)
-                        .setAuthEap(mMockServerCaCert, eapConfig)
-                        .build();
-
-        verifyIkeSessionOptionsCommon(sessionOptions);
-
-        IkeAuthConfig localConfig = sessionOptions.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthEapConfig);
-        assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_EAP, localConfig.mAuthMethod);
-        assertEquals(eapConfig, ((IkeAuthEapConfig) localConfig).mEapConfig);
-
-        IkeAuthConfig remoteConfig = sessionOptions.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
-        assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, remoteConfig.mAuthMethod);
-        assertEquals(
-                mMockServerCaCert,
-                ((IkeAuthDigitalSignRemoteConfig) remoteConfig).mTrustAnchor.getTrustedCert());
-    }
-
-    @Test
-    public void testBuildWithDigitalSignatureAuth() throws Exception {
-        IkeSessionOptions sessionOptions =
-                new IkeSessionOptions.Builder()
-                        .setServerAddress(REMOTE_IPV4_ADDRESS)
-                        .setUdpEncapsulationSocket(mUdpEncapSocket)
-                        .addSaProposal(mIkeSaProposal)
-                        .setLocalIdentification(mLocalIdentification)
-                        .setRemoteIdentification(mRemoteIdentification)
-                        .setAuthDigitalSignature(
-                                mMockServerCaCert, mMockClientEndCert, mMockRsaPrivateKey)
-                        .build();
-
-        verifyIkeSessionOptionsCommon(sessionOptions);
-
-        IkeAuthConfig localConfig = sessionOptions.getLocalAuthConfig();
-        assertTrue(localConfig instanceof IkeAuthDigitalSignLocalConfig);
-
-        IkeAuthDigitalSignLocalConfig localAuthConfig = (IkeAuthDigitalSignLocalConfig) localConfig;
-        assertEquals(
-                IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, localAuthConfig.mAuthMethod);
-        assertEquals(mMockClientEndCert, localAuthConfig.mEndCert);
-        assertTrue(localAuthConfig.mIntermediateCerts.isEmpty());
-        assertEquals(mMockRsaPrivateKey, localAuthConfig.mPrivateKey);
-
-        IkeAuthConfig remoteConfig = sessionOptions.getRemoteAuthConfig();
-        assertTrue(remoteConfig instanceof IkeAuthDigitalSignRemoteConfig);
-        assertEquals(IkeSessionOptions.IKE_AUTH_METHOD_PUB_KEY_SIGNATURE, remoteConfig.mAuthMethod);
-        assertEquals(
-                mMockServerCaCert,
-                ((IkeAuthDigitalSignRemoteConfig) remoteConfig).mTrustAnchor.getTrustedCert());
-    }
-
-    @Test
-    public void testBuildWithDsaDigitalSignatureAuth() throws Exception {
-        try {
-            IkeSessionOptions sessionOptions =
-                    new IkeSessionOptions.Builder()
-                            .setServerAddress(REMOTE_IPV4_ADDRESS)
-                            .setUdpEncapsulationSocket(mUdpEncapSocket)
-                            .addSaProposal(mIkeSaProposal)
-                            .setLocalIdentification(mLocalIdentification)
-                            .setRemoteIdentification(mRemoteIdentification)
-                            .setAuthDigitalSignature(
-                                    mMockServerCaCert,
-                                    mMockClientEndCert,
-                                    mock(DSAPrivateKey.class))
-                            .build();
-            fail("Expected to fail because DSA is not supported");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildWithoutSaProposal() throws Exception {
-        try {
-            new IkeSessionOptions.Builder()
-                    .setServerAddress(REMOTE_IPV4_ADDRESS)
-                    .setUdpEncapsulationSocket(mUdpEncapSocket)
-                    .build();
-            fail("Expected to fail due to absence of SA proposal.");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testBuildWithoutLocalId() throws Exception {
-        try {
-            new IkeSessionOptions.Builder()
-                    .setServerAddress(REMOTE_IPV4_ADDRESS)
-                    .setUdpEncapsulationSocket(mUdpEncapSocket)
-                    .addSaProposal(mIkeSaProposal)
-                    .setRemoteIdentification(mRemoteIdentification)
-                    .setAuthPsk(PSK)
-                    .build();
-            fail("Expected to fail because local identification is not set.");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testBuildWithoutSetAuth() throws Exception {
-        try {
-            new IkeSessionOptions.Builder()
-                    .setServerAddress(REMOTE_IPV4_ADDRESS)
-                    .setUdpEncapsulationSocket(mUdpEncapSocket)
-                    .addSaProposal(mIkeSaProposal)
-                    .setLocalIdentification(mLocalIdentification)
-                    .setRemoteIdentification(mRemoteIdentification)
-                    .build();
-            fail("Expected to fail because authentiction method is not set.");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
deleted file mode 100644
index 8bf1281..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/IkeSessionTest.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.os.Looper;
-import android.os.test.TestLooper;
-import android.util.Log;
-
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachineTest;
-import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-
-public final class IkeSessionTest {
-    private static final int TIMEOUT_MS = 500;
-
-    private static final Inet4Address LOCAL_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private static final Inet4Address REMOTE_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("127.0.0.1"));
-
-    private MockIpSecTestUtils mMockIpSecTestUtils;
-    private IpSecManager mIpSecManager;
-    private Context mContext;
-
-    private IkeSessionOptions mIkeSessionOptions;
-    private ChildSessionOptions mMockChildSessionOptions;
-    private Executor mUserCbExecutor;
-    private IkeSessionCallback mMockIkeSessionCb;
-    private ChildSessionCallback mMockChildSessionCb;
-
-    @Before
-    public void setUp() throws Exception {
-        if (Looper.myLooper() == null) Looper.prepare();
-
-        mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec();
-        mIpSecManager = mMockIpSecTestUtils.getIpSecManager();
-        mContext = mMockIpSecTestUtils.getContext();
-
-        mIkeSessionOptions = buildIkeSessionOptions();
-        mMockChildSessionOptions = mock(ChildSessionOptions.class);
-        mUserCbExecutor = (r) -> r.run(); // Inline executor for testing purposes.
-        mMockIkeSessionCb = mock(IkeSessionCallback.class);
-        mMockChildSessionCb = mock(ChildSessionCallback.class);
-    }
-
-    private IkeSessionOptions buildIkeSessionOptions() throws Exception {
-        return new IkeSessionOptions.Builder()
-                .setServerAddress(REMOTE_ADDRESS)
-                .setUdpEncapsulationSocket(mIpSecManager.openUdpEncapsulationSocket())
-                .addSaProposal(IkeSessionStateMachineTest.buildSaProposal())
-                .setLocalIdentification(new IkeIpv4AddrIdentification((Inet4Address) LOCAL_ADDRESS))
-                .setRemoteIdentification(
-                        new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS))
-                .setAuthPsk(new byte[0] /* psk, unused */)
-                .build();
-    }
-
-    @Test
-    public void testConstructIkeSession() throws Exception {
-        IkeSession ikeSession =
-                new IkeSession(
-                        mContext,
-                        mIkeSessionOptions,
-                        mMockChildSessionOptions,
-                        mUserCbExecutor,
-                        mMockIkeSessionCb,
-                        mMockChildSessionCb);
-        assertNotNull(ikeSession.mIkeSessionStateMachine.getHandler().getLooper());
-    }
-
-    /**
-     * Test that when users construct IkeSessions from different threads, these IkeSessions will
-     * still be running on the same IKE worker thread.
-     */
-    @Test
-    public void testConstructFromDifferentThreads() throws Exception {
-        final int numSession = 2;
-        IkeSession[] sessions = new IkeSession[numSession];
-
-        final CountDownLatch cntLatch = new CountDownLatch(2);
-
-        for (int i = 0; i < numSession; i++) {
-            int index = i;
-            new Thread() {
-                @Override
-                public void run() {
-                    try {
-                        sessions[index] =
-                                new IkeSession(
-                                        mContext,
-                                        mIkeSessionOptions,
-                                        mMockChildSessionOptions,
-                                        mUserCbExecutor,
-                                        mMockIkeSessionCb,
-                                        mMockChildSessionCb);
-                        cntLatch.countDown();
-                    } catch (Exception e) {
-                        Log.e("IkeSessionTest", "error encountered constructing IkeSession. ", e);
-                    }
-                }
-            }.start();
-        }
-
-        assertTrue(cntLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
-        // Verify that two sessions use the same looper.
-        assertEquals(
-                sessions[0].mIkeSessionStateMachine.getHandler().getLooper(),
-                sessions[1].mIkeSessionStateMachine.getHandler().getLooper());
-    }
-
-    @Test
-    public void testOpensIkeSession() throws Exception {
-        TestLooper testLooper = new TestLooper();
-        IkeSession ikeSession =
-                new IkeSession(
-                        testLooper.getLooper(),
-                        mContext,
-                        mIpSecManager,
-                        mIkeSessionOptions,
-                        mMockChildSessionOptions,
-                        mUserCbExecutor,
-                        mMockIkeSessionCb,
-                        mMockChildSessionCb);
-        testLooper.dispatchAll();
-
-        assertTrue(
-                ikeSession.mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit);
-    }
-}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java b/tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java
deleted file mode 100644
index 65cf056..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/IkeTrafficSelectorTest.java
+++ /dev/null
@@ -1,312 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.nio.ByteBuffer;
-
-public final class IkeTrafficSelectorTest {
-    private static final String TS_IPV4_ONE_HEX_STRING = "070000100010fff0c0000264c0000365";
-    private static final int TS_ONE_START_PORT = 16;
-    private static final int TS_ONE_END_PORT = 65520;
-    private static final Inet4Address TS_ONE_START_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-    private static final Inet4Address TS_ONE_END_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.3.101"));
-
-    private static final String TS_IPV4_TWO_HEX_STRING = "070000100000ffffc0000464c0000466";
-    private static final int TS_TWO_START_PORT = 0;
-    private static final int TS_TWO_END_PORT = 65535;
-    private static final Inet4Address TS_TWO_START_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.100"));
-    private static final Inet4Address TS_TWO_END_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.102"));
-
-    private static final String TX_IPV4_INVALID_PORT_RANGE_HEX_STRING =
-            "0700001022221111c0000464c0000466";
-    private static final String TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING =
-            "070000100000ffffc0000466c0000366";
-
-    private static final int TS_TYPE_OFFSET = 0;
-    private static final int PROTOCOL_ID_OFFSET = 1;
-    private static final int TS_LENGTH_OFFSET = 2;
-
-    private IkeTrafficSelector mTsOne;
-    private IkeTrafficSelector mTsTwo;
-
-    public IkeTrafficSelectorTest() {
-        mTsOne =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT,
-                        TS_ONE_END_PORT,
-                        TS_ONE_START_ADDRESS,
-                        TS_ONE_END_ADDRESS);
-        mTsTwo =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_TWO_START_PORT,
-                        TS_TWO_END_PORT,
-                        TS_TWO_START_ADDRESS,
-                        TS_TWO_END_ADDRESS);
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectors() throws Exception {
-        int numTs = 2;
-
-        byte[] tsBytes =
-                TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + TS_IPV4_TWO_HEX_STRING);
-        IkeTrafficSelector[] selectors =
-                IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-
-        assertEquals(numTs, selectors.length);
-
-        // Verify first traffic selector
-        IkeTrafficSelector tsOne = selectors[0];
-
-        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsOne.tsType);
-        assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsOne.ipProtocolId);
-        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsOne.selectorLength);
-        assertEquals(TS_ONE_START_PORT, tsOne.startPort);
-        assertEquals(TS_ONE_END_PORT, tsOne.endPort);
-        assertEquals(TS_ONE_START_ADDRESS, tsOne.startingAddress);
-        assertEquals(TS_ONE_END_ADDRESS, tsOne.endingAddress);
-
-        // Verify second traffic selector
-        IkeTrafficSelector tsTwo = selectors[1];
-
-        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsTwo.tsType);
-        assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsTwo.ipProtocolId);
-        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsTwo.selectorLength);
-        assertEquals(TS_TWO_START_PORT, tsTwo.startPort);
-        assertEquals(TS_TWO_END_PORT, tsTwo.endPort);
-        assertEquals(TS_TWO_START_ADDRESS, tsTwo.startingAddress);
-        assertEquals(TS_TWO_END_ADDRESS, tsTwo.endingAddress);
-    }
-
-    @Test
-    public void testBuildAndEncodeIkeTrafficSelector() throws Exception {
-        IkeTrafficSelector ts =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT,
-                        TS_ONE_END_PORT,
-                        TS_ONE_START_ADDRESS,
-                        TS_ONE_END_ADDRESS);
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(ts.selectorLength);
-        ts.encodeToByteBuffer(byteBuffer);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
-        assertArrayEquals(expectedBytes, byteBuffer.array());
-    }
-
-    @Test
-    public void testEquals() throws Exception {
-        IkeTrafficSelector tsOneOther =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT,
-                        TS_ONE_END_PORT,
-                        TS_ONE_START_ADDRESS,
-                        TS_ONE_END_ADDRESS);
-
-        assertEquals(mTsOne, tsOneOther);
-        assertNotEquals(mTsOne, mTsTwo);
-    }
-
-    @Test
-    public void testContains() throws Exception {
-        IkeTrafficSelector tsOneSubset =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT + 1,
-                        TS_ONE_END_PORT,
-                        TS_ONE_START_ADDRESS,
-                        TS_ONE_END_ADDRESS);
-        assertTrue(mTsOne.contains(tsOneSubset));
-        assertFalse(tsOneSubset.contains(mTsOne));
-
-        assertTrue(mTsOne.contains(mTsOne));
-        assertFalse(mTsOne.contains(mTsTwo));
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectorWithInvalidTsType() throws Exception {
-        int numTs = 1;
-        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
-        tsBytes[TS_TYPE_OFFSET] = -1;
-
-        try {
-            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-            fail("Expected to fail due to invalid Traffic Selector Type.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectorWithInvalidIpProtocol() throws Exception {
-        int numTs = 1;
-        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
-        tsBytes[PROTOCOL_ID_OFFSET] = -1;
-
-        try {
-            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-            fail("Expected to fail due to invalid IP Protocol ID.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectorWithExpectedTrailing() throws Exception {
-        int numTs = 1;
-        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + "FFFF");
-
-        try {
-            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-            fail("Expected to fail due to unexpected trailing characters.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectorWithInvalidTsLength() throws Exception {
-        int numTs = 1;
-        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
-
-        // Traffic Selector field is two octets
-        tsBytes[TS_LENGTH_OFFSET] = 0;
-        tsBytes[TS_LENGTH_OFFSET + 1] = 0;
-
-        try {
-            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-            fail("Expected to fail due to invalid Traffic Selector length.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectorWithInvalidPortRange() throws Exception {
-        int numTs = 1;
-        byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_PORT_RANGE_HEX_STRING);
-
-        try {
-            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-            fail("Expected to fail when start port is larger than end port.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
-        int numTs = 1;
-        byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING);
-
-        try {
-            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
-            fail("Expected to fail when starting address is larger than ending address.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIkeTrafficSelectorWithInvalidTsType() throws Exception {
-        try {
-            IkeTrafficSelector ts =
-                    new IkeTrafficSelector(
-                            0,
-                            TS_ONE_START_PORT,
-                            TS_ONE_END_PORT,
-                            TS_ONE_START_ADDRESS,
-                            TS_ONE_END_ADDRESS);
-            fail("Expected to fail due to unrecognized Traffic Selector type.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIkeTrafficSelectorWithInvalidPortRange() throws Exception {
-        try {
-            IkeTrafficSelector ts =
-                    new IkeTrafficSelector(
-                            IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                            TS_ONE_END_PORT,
-                            TS_ONE_START_PORT,
-                            TS_ONE_START_ADDRESS,
-                            TS_ONE_END_ADDRESS);
-            fail("Expected to fail due to invalid port range.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIkeTrafficSelectorWithMismatchedAddressType() throws Exception {
-        Inet6Address inet6Address =
-                (Inet6Address) (InetAddressUtils.parseNumericAddress("0:2001:0:db8::1"));
-        try {
-            IkeTrafficSelector ts =
-                    new IkeTrafficSelector(
-                            IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                            TS_ONE_START_PORT,
-                            TS_ONE_END_PORT,
-                            inet6Address,
-                            TS_ONE_END_ADDRESS);
-            fail("Expected to fail due to mismatched address format.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
-        try {
-            IkeTrafficSelector ts =
-                    new IkeTrafficSelector(
-                            IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                            TS_ONE_START_PORT,
-                            TS_ONE_END_PORT,
-                            TS_ONE_END_ADDRESS,
-                            TS_ONE_START_ADDRESS);
-            fail("Expected to fail due to invalid address range.");
-        } catch (IllegalArgumentException e) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java b/tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java
deleted file mode 100644
index b0f81dc..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/TunnelModeChildSessionOptionsTest.java
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net.ipsec.ike;
-
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.AF_INET6;
-
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DHCP;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_DNS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_SUBNET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
-
-import android.util.SparseArray;
-
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-
-public final class TunnelModeChildSessionOptionsTest {
-    private static final int NUM_TS = 1;
-
-    private static final int IP4_PREFIX_LEN = 32;
-    private static final int IP6_PREFIX_LEN = 64;
-
-    private static final int INVALID_ADDR_FAMILY = 5;
-
-    private static final Inet4Address IPV4_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-    private static final Inet6Address IPV6_ADDRESS =
-            (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8::1"));
-
-    private static final Inet4Address IPV4_DNS_SERVER =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.8.8"));
-    private static final Inet6Address IPV6_DNS_SERVER =
-            (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:4860:4860::8888"));
-
-    private static final Inet4Address IPV4_DHCP_SERVER =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private ChildSaProposal mSaProposal;
-
-    @Before
-    public void setup() {
-        mSaProposal =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12,
-                                SaProposal.KEY_LEN_AES_128)
-                        .build();
-    }
-
-    private void verifyCommon(TunnelModeChildSessionOptions childOptions) {
-        assertArrayEquals(new SaProposal[] {mSaProposal}, childOptions.getSaProposals());
-        assertEquals(NUM_TS, childOptions.getLocalTrafficSelectors().length);
-        assertEquals(NUM_TS, childOptions.getRemoteTrafficSelectors().length);
-        assertFalse(childOptions.isTransportMode());
-    }
-
-    private void verifyAttrTypes(
-            SparseArray expectedAttrCntMap, TunnelModeChildSessionOptions childOptions) {
-        ConfigAttribute[] configAttributes = childOptions.getConfigurationRequests();
-
-        SparseArray<Integer> atrrCntMap = expectedAttrCntMap.clone();
-
-        for (int i = 0; i < configAttributes.length; i++) {
-            int attType = configAttributes[i].attributeType;
-            assertNotNull(atrrCntMap.get(attType));
-
-            atrrCntMap.put(attType, atrrCntMap.get(attType) - 1);
-            if (atrrCntMap.get(attType) == 0) atrrCntMap.remove(attType);
-        }
-
-        assertEquals(0, atrrCntMap.size());
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithoutConfigReq() {
-        TunnelModeChildSessionOptions childOptions =
-                new TunnelModeChildSessionOptions.Builder().addSaProposal(mSaProposal).build();
-
-        verifyCommon(childOptions);
-        assertEquals(0, childOptions.getConfigurationRequests().length);
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithAddressReq() {
-        TunnelModeChildSessionOptions childOptions =
-                new TunnelModeChildSessionOptions.Builder()
-                        .addSaProposal(mSaProposal)
-                        .addInternalAddressRequest(AF_INET, 1)
-                        .addInternalAddressRequest(AF_INET6, 2)
-                        .addInternalAddressRequest(IPV4_ADDRESS, IP4_PREFIX_LEN)
-                        .addInternalAddressRequest(IPV6_ADDRESS, IP6_PREFIX_LEN)
-                        .build();
-
-        verifyCommon(childOptions);
-
-        SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, 2);
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, 3);
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_NETMASK, 1);
-
-        verifyAttrTypes(expectedAttrCntMap, childOptions);
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithInvalidAddressReq() {
-        try {
-            new TunnelModeChildSessionOptions.Builder()
-                    .addSaProposal(mSaProposal)
-                    .addInternalAddressRequest(IPV4_ADDRESS, 31)
-                    .build();
-            fail("Expected to fail due to invalid IPv4 prefix length.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithDnsServerReq() {
-        TunnelModeChildSessionOptions childOptions =
-                new TunnelModeChildSessionOptions.Builder()
-                        .addSaProposal(mSaProposal)
-                        .addInternalDnsServerRequest(AF_INET, 1)
-                        .addInternalDnsServerRequest(AF_INET6, 1)
-                        .addInternalDnsServerRequest(IPV4_DNS_SERVER)
-                        .addInternalDnsServerRequest(IPV6_DNS_SERVER)
-                        .build();
-
-        verifyCommon(childOptions);
-
-        SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_DNS, 2);
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_DNS, 2);
-
-        verifyAttrTypes(expectedAttrCntMap, childOptions);
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithSubnetReq() {
-        TunnelModeChildSessionOptions childOptions =
-                new TunnelModeChildSessionOptions.Builder()
-                        .addSaProposal(mSaProposal)
-                        .addInternalSubnetRequest(AF_INET, 1)
-                        .addInternalSubnetRequest(AF_INET6, 1)
-                        .build();
-
-        verifyCommon(childOptions);
-
-        SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_SUBNET, 1);
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP6_SUBNET, 1);
-
-        verifyAttrTypes(expectedAttrCntMap, childOptions);
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithDhcpServerReq() {
-        TunnelModeChildSessionOptions childOptions =
-                new TunnelModeChildSessionOptions.Builder()
-                        .addSaProposal(mSaProposal)
-                        .addInternalDhcpServerRequest(AF_INET, 3)
-                        .addInternalDhcpServerRequest(IPV4_DHCP_SERVER)
-                        .build();
-
-        verifyCommon(childOptions);
-
-        SparseArray<Integer> expectedAttrCntMap = new SparseArray<>();
-        expectedAttrCntMap.put(CONFIG_ATTR_INTERNAL_IP4_DHCP, 4);
-
-        verifyAttrTypes(expectedAttrCntMap, childOptions);
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithDhcp6SeverReq() {
-        try {
-            new TunnelModeChildSessionOptions.Builder()
-                    .addSaProposal(mSaProposal)
-                    .addInternalDhcpServerRequest(AF_INET6, 3)
-                    .build();
-            fail("Expected to fail because DHCP6 is not supported.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildChildSessionOptionsWithInvalidDhcpReq() {
-        try {
-            new TunnelModeChildSessionOptions.Builder()
-                    .addSaProposal(mSaProposal)
-                    .addInternalDhcpServerRequest(INVALID_ADDR_FAMILY, 3)
-                    .build();
-            fail("Expected to fail due to invalid address family value");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-}
-
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java b/tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java
deleted file mode 100644
index 8c3b16d..0000000
--- a/tests/iketests/src/java/android/net/ipsec/ike/exceptions/IkeProtocolExceptionTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2018 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.ipsec.ike.exceptions;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException;
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
-
-import org.junit.Test;
-
-import java.util.LinkedList;
-import java.util.List;
-
-public final class IkeProtocolExceptionTest {
-    @Test
-    public void buildNotifyPayloadWithData() throws Exception {
-        List<Integer> unsupportedTypes = new LinkedList<>();
-        unsupportedTypes.add(55); // 0x37 in hex
-        unsupportedTypes.add(56);
-        unsupportedTypes.add(57);
-        UnsupportedCriticalPayloadException exception =
-                new UnsupportedCriticalPayloadException(unsupportedTypes);
-
-        IkeNotifyPayload payload = exception.buildNotifyPayload();
-        assertEquals(ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, payload.notifyType);
-        assertArrayEquals(new byte[] {(byte) 0x37}, payload.notifyData);
-    }
-
-    @Test
-    public void buildNotifyPayloadWithoutData() throws Exception {
-        NoValidProposalChosenException exception =
-                new NoValidProposalChosenException("IkeProtocolExceptionTest");
-
-        IkeNotifyPayload payload = exception.buildNotifyPayload();
-        assertEquals(ERROR_TYPE_NO_PROPOSAL_CHOSEN, payload.notifyType);
-        assertArrayEquals(new byte[0], payload.notifyData);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/ChildSessionStateMachineTest.java b/tests/iketests/src/java/com/android/ike/ikev2/ChildSessionStateMachineTest.java
new file mode 100644
index 0000000..1d760b7
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/ChildSessionStateMachineTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.test.TestLooper;
+
+import com.android.ike.ikev2.IkeSessionStateMachine.IChildSessionCallback;
+import com.android.ike.ikev2.SaRecord.ChildSaRecord;
+import com.android.ike.ikev2.SaRecord.ISaRecordHelper;
+import com.android.ike.ikev2.SaRecord.SaRecordHelper;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.message.IkePayload;
+import com.android.ike.ikev2.message.TestUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+import java.util.LinkedList;
+import java.util.List;
+
+public final class ChildSessionStateMachineTest {
+    private static final String IKE_AUTH_REQ_SA_PAYLOAD =
+            "2c00002c00000028010304032ad4c0a20300000c0100000c800e0080"
+                    + "03000008030000020000000805000000";
+    private static final String IKE_AUTH_RESP_SA_PAYLOAD =
+            "2c00002c0000002801030403cae7019f0300000c0100000c800e0080"
+                    + "03000008030000020000000805000000";
+
+    private static final String CURRENT_CHILD_SA_SPI_IN = "2ad4c0a2";
+    private static final String CURRENT_CHILD_SA_SPI_OUT = "cae7019f";
+
+    private TestLooper mLooper;
+    private ChildSessionStateMachine mChildSessionStateMachine;
+
+    private List<IkePayload> mAuthReqSaNegoPayloads = new LinkedList<>();
+    private List<IkePayload> mAuthRespSaNegoPayloads = new LinkedList<>();
+
+    private ChildSaRecord mSpyCurrentChildSaRecord;
+
+    private ISaRecordHelper mMockSaRecordHelper;
+    private IChildSessionCallback mMockChildSessionCallback;
+    private ChildSessionOptions mChildSessionOptions;
+
+    public ChildSessionStateMachineTest() {
+        mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class);
+        mMockChildSessionCallback = mock(IChildSessionCallback.class);
+
+        mChildSessionOptions = new ChildSessionOptions();
+    }
+
+    @Before
+    public void setup() throws Exception {
+        // Setup thread and looper
+        mLooper = new TestLooper();
+        mChildSessionStateMachine =
+                new ChildSessionStateMachine(
+                        "ChildSessionStateMachine", mLooper.getLooper(), mChildSessionOptions);
+        mChildSessionStateMachine.setDbg(true);
+        SaRecord.setSaRecordHelper(mMockSaRecordHelper);
+
+        setUpPayloadLists();
+        setUpChildSaRecords();
+
+        mChildSessionStateMachine.start();
+    }
+
+    private void setUpPayloadLists() throws IkeException {
+        mAuthReqSaNegoPayloads.add(
+                TestUtils.hexStringToIkePayload(
+                        IkePayload.PAYLOAD_TYPE_SA, false, IKE_AUTH_REQ_SA_PAYLOAD));
+        mAuthRespSaNegoPayloads.add(
+                TestUtils.hexStringToIkePayload(
+                        IkePayload.PAYLOAD_TYPE_SA, true, IKE_AUTH_RESP_SA_PAYLOAD));
+        // TODO: Build and add Traffic Selector Payloads to two payload lists.
+    }
+
+    private void setUpChildSaRecords() {
+        mSpyCurrentChildSaRecord =
+                spy(makeDummyChildSaRecord(CURRENT_CHILD_SA_SPI_IN, CURRENT_CHILD_SA_SPI_OUT));
+    }
+
+    private ChildSaRecord makeDummyChildSaRecord(String inboundSpiHex, String outboundSpiHex) {
+        byte[] spiInBytes = TestUtils.hexStringToByteArray(CURRENT_CHILD_SA_SPI_IN);
+        int spiIn = ByteBuffer.wrap(spiInBytes).getInt();
+
+        byte[] spiOutBytes = TestUtils.hexStringToByteArray(CURRENT_CHILD_SA_SPI_OUT);
+        int spiOut = ByteBuffer.wrap(spiOutBytes).getInt();
+
+        return new ChildSaRecord(spiIn, spiOut, null, null);
+    }
+
+    @After
+    public void tearDown() {
+        mChildSessionStateMachine.quit();
+        mChildSessionStateMachine.setDbg(false);
+
+        SaRecord.setSaRecordHelper(new SaRecordHelper());
+    }
+
+    @Test
+    public void testCreateFirstChild() throws Exception {
+        when(mMockSaRecordHelper.makeChildSaRecord(any(), any()))
+                .thenReturn(mSpyCurrentChildSaRecord);
+        mChildSessionStateMachine.handleFirstChildExchange(
+                mAuthReqSaNegoPayloads, mAuthRespSaNegoPayloads, mMockChildSessionCallback);
+
+        mLooper.dispatchAll();
+        verify(mMockChildSessionCallback)
+                .onCreateChildSa(mSpyCurrentChildSaRecord.outboundSpi, mChildSessionStateMachine);
+        assertTrue(
+                mChildSessionStateMachine.getCurrentState()
+                        instanceof ChildSessionStateMachine.Idle);
+        assertEquals(mSpyCurrentChildSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord);
+    }
+}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java b/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java
new file mode 100644
index 0000000..bdaf135
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionOptionsTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.fail;
+
+import android.content.Context;
+import android.net.IpSecManager;
+import android.net.IpSecManager.UdpEncapsulationSocket;
+
+import androidx.test.InstrumentationRegistry;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.net.Inet4Address;
+
+public final class IkeSessionOptionsTest {
+    private static final Inet4Address IPV4_ADDRESS =
+            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+
+    private UdpEncapsulationSocket mUdpEncapSocket;
+
+    @Before
+    public void setUp() throws Exception {
+        Context context = InstrumentationRegistry.getContext();
+        IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE);
+        mUdpEncapSocket = ipSecManager.openUdpEncapsulationSocket();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mUdpEncapSocket.close();
+    }
+
+    @Test
+    public void testBuild() throws Exception {
+        SaProposal saProposal =
+                SaProposal.Builder.newIkeSaProposalBuilder()
+                        .addEncryptionAlgorithm(
+                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+                                SaProposal.KEY_LEN_AES_128)
+                        .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
+                        .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+                        .build();
+
+        IkeSessionOptions sessionOptions =
+                new IkeSessionOptions.Builder(IPV4_ADDRESS, mUdpEncapSocket)
+                        .addSaProposal(saProposal)
+                        .build();
+
+        assertEquals(IPV4_ADDRESS, sessionOptions.getServerAddress());
+        assertEquals(mUdpEncapSocket, sessionOptions.getUdpEncapsulationSocket());
+        assertArrayEquals(new SaProposal[] {saProposal}, sessionOptions.getSaProposals());
+        assertFalse(sessionOptions.isIkeFragmentationSupported());
+    }
+
+    @Test
+    public void testBuildWithoutSaProposal() throws Exception {
+        try {
+            new IkeSessionOptions.Builder(IPV4_ADDRESS, mUdpEncapSocket).build();
+            fail("Expected to fail due to absence of SA proposal.");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    @Test
+    public void testBuildWithChildSaProposal() throws Exception {
+        SaProposal saProposal =
+                SaProposal.Builder.newChildSaProposalBuilder(true)
+                        .addEncryptionAlgorithm(
+                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+                                SaProposal.KEY_LEN_AES_128)
+                        .build();
+        try {
+            new IkeSessionOptions.Builder(IPV4_ADDRESS, mUdpEncapSocket)
+                    .addSaProposal(saProposal)
+                    .build();
+            fail("Expected to fail due to wrong type of SA proposal.");
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionStateMachineTest.java
new file mode 100644
index 0000000..1dcf5b8
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/IkeSessionStateMachineTest.java
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.net.IpSecManager;
+import android.net.IpSecManager.UdpEncapsulationSocket;
+import android.os.Looper;
+import android.os.test.TestLooper;
+
+import androidx.test.InstrumentationRegistry;
+
+import com.android.ike.ikev2.ChildSessionStateMachineFactory.ChildSessionFactoryHelper;
+import com.android.ike.ikev2.ChildSessionStateMachineFactory.IChildSessionFactoryHelper;
+import com.android.ike.ikev2.IkeSessionStateMachine.ReceivedIkePacket;
+import com.android.ike.ikev2.SaRecord.ISaRecordHelper;
+import com.android.ike.ikev2.SaRecord.IkeSaRecord;
+import com.android.ike.ikev2.SaRecord.SaRecordHelper;
+import com.android.ike.ikev2.message.IkeHeader;
+import com.android.ike.ikev2.message.IkeMessage;
+import com.android.ike.ikev2.message.IkeMessage.IIkeMessageHelper;
+import com.android.ike.ikev2.message.IkeMessage.IkeMessageHelper;
+import com.android.ike.ikev2.message.IkePayload;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.net.InetAddress;
+import java.util.LinkedList;
+import java.util.List;
+
+public final class IkeSessionStateMachineTest {
+
+    private static final String SERVER_ADDRESS = "192.0.2.100";
+
+    private UdpEncapsulationSocket mUdpEncapSocket;
+
+    private TestLooper mLooper;
+    private IkeSessionStateMachine mIkeSessionStateMachine;
+
+    private IkeSessionOptions mIkeSessionOptions;
+    private ChildSessionOptions mChildSessionOptions;
+
+    private IIkeMessageHelper mMockIkeMessageHelper;
+    private ISaRecordHelper mMockSaRecordHelper;
+
+    private ChildSessionStateMachine mMockChildSessionStateMachine;
+    private IChildSessionFactoryHelper mMockChildSessionFactoryHelper;
+
+    private IkeSaRecord mSpyCurrentIkeSaRecord;
+    private IkeSaRecord mSpyLocalInitIkeSaRecord;
+    private IkeSaRecord mSpyRemoteInitIkeSaRecord;
+
+    private ArgumentCaptor<IkeMessage> mIkeMessageCaptor =
+            ArgumentCaptor.forClass(IkeMessage.class);
+
+    private ReceivedIkePacket makeDummyUnencryptedReceivedIkePacket(int packetType)
+            throws Exception {
+        IkeMessage dummyIkeMessage = makeDummyIkeMessageForTest(0, 0, false, false);
+        byte[] dummyIkePacketBytes = new byte[0];
+
+        when(mMockIkeMessageHelper.decode(dummyIkeMessage.ikeHeader, dummyIkePacketBytes))
+                .thenReturn(dummyIkeMessage);
+        when(mMockIkeMessageHelper.getMessageType(dummyIkeMessage)).thenReturn(packetType);
+        return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes);
+    }
+
+    private ReceivedIkePacket makeDummyEncryptedReceivedIkePacket(
+            int packetType, IkeSaRecord ikeSaRecord) throws Exception {
+        boolean fromIkeInit = !ikeSaRecord.isLocalInit;
+        IkeMessage dummyIkeMessage =
+                makeDummyIkeMessageForTest(
+                        ikeSaRecord.initiatorSpi, ikeSaRecord.responderSpi, fromIkeInit, true);
+        byte[] dummyIkePacketBytes = new byte[0];
+
+        when(mMockIkeMessageHelper.decode(
+                        mIkeSessionOptions,
+                        ikeSaRecord,
+                        dummyIkeMessage.ikeHeader,
+                        dummyIkePacketBytes))
+                .thenReturn(dummyIkeMessage);
+        when(mMockIkeMessageHelper.getMessageType(dummyIkeMessage)).thenReturn(packetType);
+        return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes);
+    }
+
+    private IkeMessage makeDummyIkeMessageForTest(
+            long initSpi, long respSpi, boolean fromikeInit, boolean isEncrypted) {
+        int firstPayloadType =
+                isEncrypted ? IkePayload.PAYLOAD_TYPE_SK : IkePayload.PAYLOAD_TYPE_NO_NEXT;
+        IkeHeader header =
+                new IkeHeader(initSpi, respSpi, firstPayloadType, 0, true, fromikeInit, 0);
+        return new IkeMessage(header, new LinkedList<IkePayload>());
+    }
+
+    private void verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket)
+            throws Exception {
+        verify(mMockIkeMessageHelper)
+                .decode(mIkeSessionOptions, record, rcvPacket.ikeHeader, rcvPacket.ikePacketBytes);
+    }
+
+    public IkeSessionStateMachineTest() {
+        mMockIkeMessageHelper = mock(IkeMessage.IIkeMessageHelper.class);
+        mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class);
+
+        mMockChildSessionStateMachine = mock(ChildSessionStateMachine.class);
+        mMockChildSessionFactoryHelper = mock(IChildSessionFactoryHelper.class);
+
+        mSpyCurrentIkeSaRecord = spy(new IkeSaRecord(11, 12, true, null, null));
+        mSpyLocalInitIkeSaRecord = spy(new IkeSaRecord(21, 22, true, null, null));
+        mSpyRemoteInitIkeSaRecord = spy(new IkeSaRecord(31, 32, false, null, null));
+
+        when(mMockIkeMessageHelper.encode(any())).thenReturn(new byte[0]);
+        when(mMockIkeMessageHelper.encode(any(), any(), any())).thenReturn(new byte[0]);
+        when(mMockChildSessionFactoryHelper.makeChildSessionStateMachine(any(), any(), any()))
+                .thenReturn(mMockChildSessionStateMachine);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        Context context = InstrumentationRegistry.getContext();
+        IpSecManager ipSecManager = (IpSecManager) context.getSystemService(Context.IPSEC_SERVICE);
+        mUdpEncapSocket = ipSecManager.openUdpEncapsulationSocket();
+
+        mIkeSessionOptions = buildIkeSessionOptions();
+        mChildSessionOptions = new ChildSessionOptions();
+
+        // Setup thread and looper
+        mLooper = new TestLooper();
+        mIkeSessionStateMachine =
+                new IkeSessionStateMachine(
+                        "IkeSessionStateMachine",
+                        mLooper.getLooper(),
+                        mIkeSessionOptions,
+                        mChildSessionOptions);
+        mIkeSessionStateMachine.setDbg(true);
+        mIkeSessionStateMachine.start();
+
+        IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper);
+        SaRecord.setSaRecordHelper(mMockSaRecordHelper);
+        ChildSessionStateMachineFactory.setChildSessionFactoryHelper(
+                mMockChildSessionFactoryHelper);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        mIkeSessionStateMachine.quit();
+        mIkeSessionStateMachine.setDbg(false);
+        mUdpEncapSocket.close();
+
+        IkeMessage.setIkeMessageHelper(new IkeMessageHelper());
+        SaRecord.setSaRecordHelper(new SaRecordHelper());
+        ChildSessionStateMachineFactory.setChildSessionFactoryHelper(
+                new ChildSessionFactoryHelper());
+    }
+
+    private IkeSessionOptions buildIkeSessionOptions() throws Exception {
+        SaProposal saProposal =
+                SaProposal.Builder.newIkeSaProposalBuilder()
+                        .addEncryptionAlgorithm(
+                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
+                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+                        .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
+                        .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+                        .build();
+
+        InetAddress serveAddress = InetAddress.getByName(SERVER_ADDRESS);
+        IkeSessionOptions sessionOptions =
+                new IkeSessionOptions.Builder(serveAddress, mUdpEncapSocket)
+                        .addSaProposal(saProposal)
+                        .build();
+        return sessionOptions;
+    }
+
+    private static boolean isIkePayloadExist(
+            List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType) {
+        for (IkePayload payload : payloadList) {
+            if (payload.payloadType == payloadType) return true;
+        }
+        return false;
+    }
+
+    @Test
+    public void testCreateIkeLocalIkeInit() throws Exception {
+        if (Looper.myLooper() == null) Looper.myLooper().prepare();
+        // Mock IKE_INIT response.
+        ReceivedIkePacket dummyReceivedIkePacket =
+                makeDummyUnencryptedReceivedIkePacket(IkeMessage.MESSAGE_TYPE_IKE_INIT_RESP);
+        when(mMockSaRecordHelper.makeFirstIkeSaRecord(any(), any()))
+                .thenReturn(mSpyCurrentIkeSaRecord);
+
+        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket);
+
+        mLooper.dispatchAll();
+
+        // Validate outbound IKE INIT request
+        verify(mMockIkeMessageHelper).encode(mIkeMessageCaptor.capture());
+        IkeMessage ikeInitReqMessage = mIkeMessageCaptor.getValue();
+
+        IkeHeader ikeHeader = ikeInitReqMessage.ikeHeader;
+        assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, ikeHeader.exchangeType);
+        assertFalse(ikeHeader.isResponseMsg);
+        assertTrue(ikeHeader.fromIkeInitiator);
+
+        List<IkePayload> payloadList = ikeInitReqMessage.ikePayloadList;
+        assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_SA));
+        assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_KE));
+        assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_NONCE));
+
+        IkeSocket ikeSocket = mIkeSessionStateMachine.mIkeSocket;
+        assertNotNull(ikeSocket);
+        assertNotEquals(
+                -1 /*not found*/, ikeSocket.mSpiToIkeSession.indexOfValue(mIkeSessionStateMachine));
+
+        verify(mMockIkeMessageHelper)
+                .decode(dummyReceivedIkePacket.ikeHeader, dummyReceivedIkePacket.ikePacketBytes);
+        verify(mMockIkeMessageHelper).getMessageType(any());
+
+        assertTrue(
+                mIkeSessionStateMachine.getCurrentState()
+                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth);
+    }
+
+    private void mockIkeSetup() throws Exception {
+        if (Looper.myLooper() == null) Looper.myLooper().prepare();
+        // Mock IKE_INIT response
+        ReceivedIkePacket dummyIkeInitRespReceivedPacket =
+                makeDummyUnencryptedReceivedIkePacket(IkeMessage.MESSAGE_TYPE_IKE_INIT_RESP);
+        when(mMockSaRecordHelper.makeFirstIkeSaRecord(any(), any()))
+                .thenReturn(mSpyCurrentIkeSaRecord);
+
+        // Mock IKE_AUTH response
+        ReceivedIkePacket dummyIkeAuthRespReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_IKE_AUTH_RESP, mSpyCurrentIkeSaRecord);
+
+        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyIkeInitRespReceivedPacket);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyIkeAuthRespReceivedPacket);
+    }
+
+    @Test
+    public void testCreateIkeLocalIkeAuth() throws Exception {
+        mockIkeSetup();
+
+        mLooper.dispatchAll();
+        verify(mMockIkeMessageHelper).decode(any(), any(), any(), any());
+        verify(mMockIkeMessageHelper, times(2)).getMessageType(any());
+        verify(mMockChildSessionStateMachine).handleFirstChildExchange(any(), any(), any());
+        assertTrue(
+                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
+    }
+
+    @Test
+    public void testRekeyIkeLocal() throws Exception {
+        // Mock Rekey IKE response
+        ReceivedIkePacket dummyRekeyIkeRespReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_REKEY_IKE_RESP, mSpyCurrentIkeSaRecord);
+        when(mMockSaRecordHelper.makeNewIkeSaRecord(eq(mSpyCurrentIkeSaRecord), any(), any()))
+                .thenReturn(mSpyLocalInitIkeSaRecord);
+        // Mock Delete old IKE response;
+        ReceivedIkePacket dummyDeleteIkeRespReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_DELETE_IKE_RESP, mSpyCurrentIkeSaRecord);
+
+        mockIkeSetup();
+
+        // Testing creating new IKE
+        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket);
+        // Testing deleting old IKE
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket);
+
+        mLooper.dispatchAll();
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket);
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket);
+        assertTrue(
+                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
+        assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, mSpyLocalInitIkeSaRecord);
+    }
+
+    @Test
+    public void testRekeyIkeRemote() throws Exception {
+        // Mock Rekey IKE request
+        ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_REKEY_IKE_REQ, mSpyCurrentIkeSaRecord);
+        when(mMockSaRecordHelper.makeNewIkeSaRecord(eq(mSpyCurrentIkeSaRecord), any(), any()))
+                .thenReturn(mSpyRemoteInitIkeSaRecord);
+
+        // Mock Delete IKE request
+        ReceivedIkePacket dummyDeleteIkeRequestReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_DELETE_IKE_REQ, mSpyCurrentIkeSaRecord);
+        mockIkeSetup();
+
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRequestReceivedPacket);
+
+        mLooper.dispatchAll();
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket);
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket);
+        assertTrue(
+                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
+        assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, mSpyRemoteInitIkeSaRecord);
+    }
+
+    @Test
+    public void testSimulRekey() throws Exception {
+        // Mock Rekey IKE response
+        ReceivedIkePacket dummyRekeyIkeRespReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_REKEY_IKE_RESP, mSpyCurrentIkeSaRecord);
+        when(mMockSaRecordHelper.makeNewIkeSaRecord(eq(mSpyCurrentIkeSaRecord), any(), any()))
+                .thenReturn(mSpyLocalInitIkeSaRecord);
+
+        // Mock Rekey IKE request
+        ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_REKEY_IKE_REQ, mSpyCurrentIkeSaRecord);
+
+        when(mMockSaRecordHelper.makeNewIkeSaRecord(eq(mSpyCurrentIkeSaRecord), any(), any()))
+                .thenReturn(mSpyRemoteInitIkeSaRecord)
+                .thenReturn(mSpyLocalInitIkeSaRecord);
+
+        // Mock nonce comparison
+        when(mSpyLocalInitIkeSaRecord.compareTo(mSpyRemoteInitIkeSaRecord)).thenReturn(1);
+
+        // Mock Delete old IKE response;
+        ReceivedIkePacket dummyDeleteIkeRespReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_DELETE_IKE_RESP, mSpyCurrentIkeSaRecord);
+
+        // Mock Delete IKE request on remotely initiated IKE SA
+        ReceivedIkePacket dummyDeleteIkeRequestReceivedPacket =
+                makeDummyEncryptedReceivedIkePacket(
+                        IkeMessage.MESSAGE_TYPE_DELETE_IKE_REQ, mSpyRemoteInitIkeSaRecord);
+
+        mockIkeSetup();
+
+        // Testing creating new IKE
+        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket);
+
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket);
+        // Testing deleting old IKE and losing new IKE
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket);
+        mIkeSessionStateMachine.sendMessage(
+                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRequestReceivedPacket);
+
+        mLooper.dispatchAll();
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket);
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket);
+        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket);
+        verifyDecodeEncryptedMessage(
+                mSpyRemoteInitIkeSaRecord, dummyDeleteIkeRequestReceivedPacket);
+        assertTrue(
+                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
+        assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, mSpyLocalInitIkeSaRecord);
+    }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTest.java b/tests/iketests/src/java/com/android/ike/ikev2/IkeSocketTest.java
similarity index 88%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/IkeSocketTest.java
index 1b8761f..5f15f55 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSocketTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/IkeSocketTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike;
+package com.android.ike.ikev2;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -39,9 +39,9 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.IkeSocket.PacketReceiver;
-import com.android.internal.net.ipsec.ike.message.IkeHeader;
+import com.android.ike.ikev2.IkeSocket.PacketReceiver;
+import com.android.ike.ikev2.message.IkeHeader;
+import com.android.ike.ikev2.message.TestUtils;
 
 import org.junit.After;
 import org.junit.Before;
@@ -141,35 +141,28 @@
 
     @Test
     public void testGetAndCloseIkeSocket() throws Exception {
-        // Must be prepared here; AndroidJUnitRunner runs tests on different threads from the
-        // setUp() call. Since the new Handler() call is run in getIkeSocket, the Looper must be
-        // prepared here.
-        if (Looper.myLooper() == null) Looper.prepare();
+        if (Looper.myLooper() == null) Looper.myLooper().prepare();
 
-        IkeSessionStateMachine mMockIkeSessionOne = mock(IkeSessionStateMachine.class);
-        IkeSessionStateMachine mMockIkeSessionTwo = mock(IkeSessionStateMachine.class);
+        IkeSocket ikeSocketOne = IkeSocket.getIkeSocket(mClientUdpEncapSocket);
+        assertEquals(1, ikeSocketOne.mRefCount);
 
-        IkeSocket ikeSocketOne = IkeSocket.getIkeSocket(mClientUdpEncapSocket, mMockIkeSessionOne);
-        assertEquals(1, ikeSocketOne.mAliveIkeSessions.size());
-
-        IkeSocket ikeSocketTwo = IkeSocket.getIkeSocket(mClientUdpEncapSocket, mMockIkeSessionTwo);
+        IkeSocket ikeSocketTwo = IkeSocket.getIkeSocket(mClientUdpEncapSocket);
         assertEquals(ikeSocketOne, ikeSocketTwo);
-        assertEquals(2, ikeSocketTwo.mAliveIkeSessions.size());
+        assertEquals(2, ikeSocketTwo.mRefCount);
 
-        ikeSocketOne.releaseReference(mMockIkeSessionOne);
-        assertEquals(1, ikeSocketOne.mAliveIkeSessions.size());
+        ikeSocketOne.releaseReference();
+        assertEquals(1, ikeSocketOne.mRefCount);
 
-        ikeSocketTwo.releaseReference(mMockIkeSessionTwo);
-        assertEquals(0, ikeSocketTwo.mAliveIkeSessions.size());
+        ikeSocketTwo.releaseReference();
+        assertEquals(0, ikeSocketTwo.mRefCount);
     }
 
     @Test
     public void testSendIkePacket() throws Exception {
-        if (Looper.myLooper() == null) Looper.prepare();
+        if (Looper.myLooper() == null) Looper.myLooper().prepare();
 
         // Send IKE packet
-        IkeSocket ikeSocket =
-                IkeSocket.getIkeSocket(mClientUdpEncapSocket, mMockIkeSessionStateMachine);
+        IkeSocket ikeSocket = IkeSocket.getIkeSocket(mClientUdpEncapSocket);
         ikeSocket.sendIkePacket(mDataOne, mLocalAddress);
 
         byte[] receivedData = receive(mDummyRemoteServerFd);
@@ -181,7 +174,7 @@
 
         assertArrayEquals(expectedBuffer.array(), receivedData);
 
-        ikeSocket.releaseReference(mMockIkeSessionStateMachine);
+        ikeSocket.releaseReference();
     }
 
     @Test
@@ -199,9 +192,7 @@
                         () -> {
                             try {
                                 socketReceiver.setIkeSocket(
-                                        IkeSocket.getIkeSocket(
-                                                mClientUdpEncapSocket,
-                                                mMockIkeSessionStateMachine));
+                                        IkeSocket.getIkeSocket(mClientUdpEncapSocket));
                                 createLatch.countDown();
                                 Log.d("IkeSocketTest", "IkeSocket created.");
                             } catch (ErrnoException e) {
@@ -238,7 +229,7 @@
                 .getHandler()
                 .post(
                         () -> {
-                            ikeSocket.releaseReference(mMockIkeSessionStateMachine);
+                            ikeSocket.releaseReference();
                             closeLatch.countDown();
                         });
         closeLatch.await();
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/IkeTrafficSelectorTest.java b/tests/iketests/src/java/com/android/ike/ikev2/IkeTrafficSelectorTest.java
new file mode 100644
index 0000000..1982e62
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/IkeTrafficSelectorTest.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.message.TestUtils;
+
+import libcore.net.InetAddressUtils;
+
+import org.junit.Test;
+
+import java.net.Inet4Address;
+
+public final class IkeTrafficSelectorTest {
+    private static final String TS_IPV4_ONE_HEX_STRING = "070000100010fff0c0000264c0000365";
+    private static final int TS_ONE_START_PORT = 16;
+    private static final int TS_ONE_END_PORT = 65520;
+    private static final Inet4Address TS_ONE_START_ADDRESS =
+            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
+    private static final Inet4Address TS_ONE_END_ADDRESS =
+            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.3.101"));
+
+    private static final String TS_IPV4_TWO_HEX_STRING = "070000100000ffffc0000464c0000466";
+    private static final int TS_TWO_START_PORT = 0;
+    private static final int TS_TWO_END_PORT = 65535;
+    private static final Inet4Address TS_TWO_START_ADDRESS =
+            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.100"));
+    private static final Inet4Address TS_TWO_END_ADDRESS =
+            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.102"));
+
+    private static final String TX_IPV4_INVALID_PORT_RANGE_HEX_STRING =
+            "0700001022221111c0000464c0000466";
+    private static final String TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING =
+            "070000100000ffffc0000466c0000366";
+
+    private static final int TS_TYPE_OFFSET = 0;
+    private static final int PROTOCOL_ID_OFFSET = 1;
+    private static final int TS_LENGTH_OFFSET = 2;
+
+    @Test
+    public void testDecodeIkeTrafficSelectors() throws Exception {
+        int numTs = 2;
+
+        byte[] tsBytes =
+                TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + TS_IPV4_TWO_HEX_STRING);
+        IkeTrafficSelector[] selectors =
+                IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+
+        assertEquals(numTs, selectors.length);
+
+        // Verify first traffic selector
+        IkeTrafficSelector tsOne = selectors[0];
+
+        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsOne.tsType);
+        assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsOne.ipProtocolId);
+        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsOne.selectorLength);
+        assertEquals(TS_ONE_START_PORT, tsOne.startPort);
+        assertEquals(TS_ONE_END_PORT, tsOne.endPort);
+        assertEquals(TS_ONE_START_ADDRESS, tsOne.startingAddress);
+        assertEquals(TS_ONE_END_ADDRESS, tsOne.endingAddress);
+
+        // Verify second traffic selector
+        IkeTrafficSelector tsTwo = selectors[1];
+
+        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE, tsTwo.tsType);
+        assertEquals(IkeTrafficSelector.IP_PROTOCOL_ID_UNSPEC, tsTwo.ipProtocolId);
+        assertEquals(IkeTrafficSelector.TRAFFIC_SELECTOR_IPV4_LEN, tsTwo.selectorLength);
+        assertEquals(TS_TWO_START_PORT, tsTwo.startPort);
+        assertEquals(TS_TWO_END_PORT, tsTwo.endPort);
+        assertEquals(TS_TWO_START_ADDRESS, tsTwo.startingAddress);
+        assertEquals(TS_TWO_END_ADDRESS, tsTwo.endingAddress);
+    }
+
+    @Test
+    public void testDecodeIkeTrafficSelectorWithInvalidTsType() throws Exception {
+        int numTs = 1;
+        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+        tsBytes[TS_TYPE_OFFSET] = -1;
+
+        try {
+            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+            fail("Expected to fail due to invalid Traffic Selector Type.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeIkeTrafficSelectorWithInvalidIpProtocol() throws Exception {
+        int numTs = 1;
+        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+        tsBytes[PROTOCOL_ID_OFFSET] = -1;
+
+        try {
+            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+            fail("Expected to fail due to invalid IP Protocol ID.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeIkeTrafficSelectorWithExpectedTrailing() throws Exception {
+        int numTs = 1;
+        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING + "FFFF");
+
+        try {
+            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+            fail("Expected to fail due to unexpected trailing characters.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeIkeTrafficSelectorWithInvalidTsLength() throws Exception {
+        int numTs = 1;
+        byte[] tsBytes = TestUtils.hexStringToByteArray(TS_IPV4_ONE_HEX_STRING);
+
+        // Traffic Selector field is two octets
+        tsBytes[TS_LENGTH_OFFSET] = 0;
+        tsBytes[TS_LENGTH_OFFSET + 1] = 0;
+
+        try {
+            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+            fail("Expected to fail due to invalid Traffic Selector length.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeIkeTrafficSelectorWithInvalidPortRange() throws Exception {
+        int numTs = 1;
+        byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_PORT_RANGE_HEX_STRING);
+
+        try {
+            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+            fail("Expected to fail when start port is larger than end port.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeIkeTrafficSelectorWithInvalidAddressRange() throws Exception {
+        int numTs = 1;
+        byte[] tsBytes = TestUtils.hexStringToByteArray(TX_IPV4_INVALID_ADDRESS_RANGE_HEX_STRING);
+
+        try {
+            IkeTrafficSelector.decodeIkeTrafficSelectors(numTs, tsBytes);
+            fail("Expected to fail when starting address is larger than ending address.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+}
diff --git a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java b/tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java
similarity index 71%
rename from tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java
index d4efb0c..7f40d72 100644
--- a/tests/iketests/src/java/android/net/ipsec/ike/SaProposalTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/SaProposalTest.java
@@ -14,10 +14,7 @@
  * limitations under the License.
  */
 
-package android.net.ipsec.ike;
-
-import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_128;
-import static android.net.ipsec.ike.SaProposal.KEY_LEN_UNUSED;
+package com.android.ike.ikev2;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -25,12 +22,13 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
+import com.android.ike.ikev2.SaProposal.Builder;
+import com.android.ike.ikev2.message.IkePayload;
+import com.android.ike.ikev2.message.IkeSaPayload.DhGroupTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.EncryptionTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.IntegrityTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.PrfTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.Transform;
 
 import org.junit.Test;
 
@@ -44,8 +42,7 @@
     private final DhGroupTransform mDhGroup1024Transform;
 
     public SaProposalTest() {
-        mEncryption3DesTransform =
-                new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED);
+        mEncryption3DesTransform = new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES);
         mEncryptionAesGcm8Transform =
                 new EncryptionTransform(
                         SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8, SaProposal.KEY_LEN_AES_128);
@@ -61,10 +58,9 @@
 
     @Test
     public void testBuildIkeSaProposalWithNormalModeCipher() throws Exception {
-        IkeSaProposal proposal =
-                new IkeSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+        Builder builder = Builder.newIkeSaProposalBuilder();
+        SaProposal proposal =
+                builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
                         .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
                         .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
                         .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
@@ -85,9 +81,9 @@
 
     @Test
     public void testBuildIkeSaProposalWithCombinedModeCipher() throws Exception {
-        IkeSaProposal proposal =
-                new IkeSaProposal.Builder()
-                        .addEncryptionAlgorithm(
+        Builder builder = Builder.newIkeSaProposalBuilder();
+        SaProposal proposal =
+                builder.addEncryptionAlgorithm(
                                 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
                                 SaProposal.KEY_LEN_AES_128)
                         .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
@@ -106,11 +102,32 @@
     }
 
     @Test
-    public void testBuildChildSaProposalWithNormalCipher() throws Exception {
-        ChildSaProposal proposal =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+    public void testBuildFirstChildSaProposalWithCombinedCipher() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(true);
+        SaProposal proposal =
+                builder.addEncryptionAlgorithm(
+                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
+                                SaProposal.KEY_LEN_AES_128)
+                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
+                        .build();
+
+        assertEquals(IkePayload.PROTOCOL_ID_ESP, proposal.getProtocolId());
+        assertArrayEquals(
+                new EncryptionTransform[] {mEncryptionAesGcm8Transform},
+                proposal.getEncryptionTransforms());
+        assertArrayEquals(
+                new IntegrityTransform[] {mIntegrityNoneTransform},
+                proposal.getIntegrityTransforms());
+        assertTrue(proposal.getPrfTransforms().length == 0);
+        assertTrue(proposal.getDhGroupTransforms().length == 0);
+    }
+
+    @Test
+    public void testBuildAdditionalChildSaProposalWithNormalCipher() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(false);
+
+        SaProposal proposal =
+                builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
                         .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
                         .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
                         .build();
@@ -124,31 +141,14 @@
                 proposal.getIntegrityTransforms());
         assertArrayEquals(
                 new DhGroupTransform[] {mDhGroup1024Transform}, proposal.getDhGroupTransforms());
-    }
-
-    @Test
-    public void testGetCopyWithoutDhGroup() throws Exception {
-        ChildSaProposal proposal =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
-                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
-                        .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
-                        .build();
-        ChildSaProposal proposalWithoutDh = proposal.getCopyWithoutDhTransform();
-
-        assertArrayEquals(
-                proposal.getEncryptionTransforms(), proposalWithoutDh.getEncryptionTransforms());
-        assertArrayEquals(
-                proposal.getIntegrityTransforms(), proposalWithoutDh.getIntegrityTransforms());
-        assertTrue(proposal.getDhGroupTransforms().length == 1);
-        assertTrue(proposalWithoutDh.getDhGroupTransforms().length == 0);
+        assertTrue(proposal.getPrfTransforms().length == 0);
     }
 
     @Test
     public void testBuildEncryptAlgosWithNoAlgorithm() throws Exception {
+        Builder builder = Builder.newIkeSaProposalBuilder();
         try {
-            new IkeSaProposal.Builder().build();
+            builder.build();
             fail("Expected to fail when no encryption algorithm is proposed.");
         } catch (IllegalArgumentException expected) {
 
@@ -157,8 +157,9 @@
 
     @Test
     public void testBuildEncryptAlgosWithUnrecognizedAlgorithm() throws Exception {
+        Builder builder = Builder.newIkeSaProposalBuilder();
         try {
-            new IkeSaProposal.Builder().addEncryptionAlgorithm(-1, KEY_LEN_UNUSED);
+            builder.addEncryptionAlgorithm(-1);
             fail("Expected to fail when unrecognized encryption algorithm is proposed.");
         } catch (IllegalArgumentException expected) {
 
@@ -167,11 +168,10 @@
 
     @Test
     public void testBuildEncryptAlgosWithTwoModes() throws Exception {
+        Builder builder = Builder.newIkeSaProposalBuilder();
         try {
-            new IkeSaProposal.Builder()
-                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
-                    .addEncryptionAlgorithm(
-                            SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128);
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
+                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12);
             fail(
                     "Expected to fail when "
                             + "normal and combined-mode ciphers are proposed together.");
@@ -182,24 +182,36 @@
 
     @Test
     public void testBuildIkeProposalWithoutPrf() throws Exception {
+        Builder builder = Builder.newIkeSaProposalBuilder();
         try {
-            new IkeSaProposal.Builder()
-                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
-                    .build();
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES).build();
             fail("Expected to fail when PRF is not provided in IKE SA proposal.");
         } catch (IllegalArgumentException expected) {
 
         }
     }
 
+    @Test
+    public void testBuildChildProposalWithPrf() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(false);
+        try {
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
+                    .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
+                    .build();
+
+            fail("Expected to fail when PRF is provided in Child SA proposal.");
+        } catch (IllegalArgumentException expected) {
+
+        }
+    }
+
     // Test throwing exception when building IKE SA Proposal with AEAD and not-none integrity
     // algorithm.
     @Test
     public void testBuildAeadWithIntegrityAlgo() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(false);
         try {
-            new ChildSaProposal.Builder()
-                    .addEncryptionAlgorithm(
-                            SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_128)
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12)
                     .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
                     .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
                     .build();
@@ -214,9 +226,9 @@
     // integrity algorithm.
     @Test
     public void testBuildIkeProposalNormalCipherWithoutIntegrityAlgo() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(false);
         try {
-            new IkeSaProposal.Builder()
-                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
                     .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
                     .build();
 
@@ -232,9 +244,9 @@
     // integrity algorithm.
     @Test
     public void testBuildIkeProposalNormalCipherWithNoneValueIntegrityAlgo() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(false);
         try {
-            new IkeSaProposal.Builder()
-                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
                     .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
                     .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_NONE)
                     .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
@@ -250,9 +262,9 @@
 
     @Test
     public void testBuildIkeProposalWithoutDhGroup() throws Exception {
+        Builder builder = Builder.newIkeSaProposalBuilder();
         try {
-            new IkeSaProposal.Builder()
-                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
                     .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
                     .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
                     .build();
@@ -265,9 +277,9 @@
 
     @Test
     public void testBuildIkeProposalWithNoneValueDhGroup() throws Exception {
+        Builder builder = Builder.newIkeSaProposalBuilder();
         try {
-            new IkeSaProposal.Builder()
-                    .addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES, KEY_LEN_UNUSED)
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
                     .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
                     .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_AES128_XCBC)
                     .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
@@ -280,6 +292,24 @@
         }
     }
 
+    // Test throwing exception when building first Child SA Proposal with not-none-value DH Group.
+    @Test
+    public void testBuildFirstChildProposalWithNotNoneValueDhGroup() throws Exception {
+        Builder builder = Builder.newChildSaProposalBuilder(true);
+        try {
+            builder.addEncryptionAlgorithm(SaProposal.ENCRYPTION_ALGORITHM_3DES)
+                    .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
+                    .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
+                    .build();
+
+            fail(
+                    "Expected to fail when"
+                            + " not-none-value DH Group is proposed in first Child SA proposal.");
+        } catch (IllegalArgumentException expected) {
+
+        }
+    }
+
     @Test
     public void testIsTransformSelectedFrom() throws Exception {
         assertTrue(SaProposal.isTransformSelectedFrom(new Transform[0], new Transform[0]));
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrfTest.java b/tests/iketests/src/java/com/android/ike/ikev2/SaRecordTest.java
similarity index 66%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrfTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/SaRecordTest.java
index 717886f..5c61105 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacPrfTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/SaRecordTest.java
@@ -14,32 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.crypto;
+package com.android.ike.ikev2;
 
 import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
 
-import android.net.ipsec.ike.SaProposal;
+import com.android.ike.ikev2.message.TestUtils;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-
-import org.junit.Before;
 import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
 
-import java.util.Arrays;
-
-@RunWith(JUnit4.class)
-public final class IkeMacPrfTest {
-
-    private static final String PRF_KEY_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485";
-    private static final String DATA_TO_SIGN_HEX_STRING = "010000000a50500d";
-    private static final String CALCULATED_MAC_HEX_STRING =
-            "D83B20CC6A0932B2A7CEF26E4020ABAAB64F0C6A";
-
+public final class SaRecordTest {
     private static final String IKE_INIT_SPI = "5F54BF6D8B48E6E1";
     private static final String IKE_RESP_SPI = "909232B3D1EDCB5C";
 
@@ -100,58 +83,24 @@
     private static final int FIRST_CHILD_AUTH_ALGO_KEY_LEN = 20;
     private static final int FIRST_CHILD_ENCR_ALGO_KEY_LEN = 16;
 
-    private IkeMacPrf mIkeHmacSha1Prf;
-
-    @Before
-    public void setUp() throws Exception {
-        mIkeHmacSha1Prf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-    }
+    private static final String PRF_HMAC_SHA1_ALGO_NAME = "HmacSHA1";
 
     @Test
-    public void testsignBytes() throws Exception {
-        byte[] skpBytes = TestUtils.hexStringToByteArray(PRF_KEY_HEX_STRING);
-        byte[] dataBytes = TestUtils.hexStringToByteArray(DATA_TO_SIGN_HEX_STRING);
-
-        byte[] calculatedBytes = mIkeHmacSha1Prf.signBytes(skpBytes, dataBytes);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(CALCULATED_MAC_HEX_STRING);
-        assertArrayEquals(expectedBytes, calculatedBytes);
-    }
-
-    @Test
-    public void testGenerateSKeySeed() throws Exception {
+    public void testCalculateSKeySeed() throws Exception {
         byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING);
         byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING);
         byte[] sharedDhKey = TestUtils.hexStringToByteArray(IKE_SHARED_DH_KEY_HEX_STRING);
 
         byte[] calculatedSKeySeed =
-                mIkeHmacSha1Prf.generateSKeySeed(nonceInit, nonceResp, sharedDhKey);
+                SaRecord.generateSKeySeed(
+                        PRF_HMAC_SHA1_ALGO_NAME, nonceInit, nonceResp, sharedDhKey);
 
         byte[] expectedSKeySeed = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING);
         assertArrayEquals(expectedSKeySeed, calculatedSKeySeed);
     }
 
     @Test
-    public void testGenerateRekeyedSKeySeed() throws Exception {
-        byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING);
-        byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING);
-        byte[] sharedDhKey = TestUtils.hexStringToByteArray(IKE_SHARED_DH_KEY_HEX_STRING);
-        byte[] old_skd = TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING);
-
-        byte[] calculatedSKeySeed =
-                mIkeHmacSha1Prf.generateRekeyedSKeySeed(old_skd, nonceInit, nonceResp, sharedDhKey);
-
-        // Verify that the new sKeySeed is different.
-        // TODO: Find actual test vectors to test positive case.
-        byte[] oldSKeySeed = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING);
-        assertFalse(Arrays.equals(oldSKeySeed, calculatedSKeySeed));
-    }
-
-    @Test
-    public void testGenerateKeyMatForIke() throws Exception {
+    public void testSignWithPrfPlusForIke() throws Exception {
         byte[] prfKey = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING);
         byte[] prfData =
                 TestUtils.hexStringToByteArray(
@@ -165,21 +114,23 @@
                         + IKE_ENCR_ALGO_KEY_LEN * 2
                         + IKE_PRF_KEY_LEN * 2;
 
-        byte[] calculatedKeyMat = mIkeHmacSha1Prf.generateKeyMat(prfKey, prfData, keyMaterialLen);
+        byte[] calculatedKeyMat =
+                SaRecord.generateKeyMat(PRF_HMAC_SHA1_ALGO_NAME, prfKey, prfData, keyMaterialLen);
 
         byte[] expectedKeyMat = TestUtils.hexStringToByteArray(IKE_KEY_MAT);
         assertArrayEquals(expectedKeyMat, calculatedKeyMat);
     }
 
     @Test
-    public void testGenerateKeyMatForFirstChild() throws Exception {
+    public void testSignWithPrfPlusForFirstChild() throws Exception {
         byte[] prfKey = TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING);
         byte[] prfData =
                 TestUtils.hexStringToByteArray(
                         IKE_NONCE_INIT_HEX_STRING + IKE_NONCE_RESP_HEX_STRING);
         int keyMaterialLen = FIRST_CHILD_AUTH_ALGO_KEY_LEN * 2 + FIRST_CHILD_ENCR_ALGO_KEY_LEN * 2;
 
-        byte[] calculatedKeyMat = mIkeHmacSha1Prf.generateKeyMat(prfKey, prfData, keyMaterialLen);
+        byte[] calculatedKeyMat =
+                SaRecord.generateKeyMat(PRF_HMAC_SHA1_ALGO_NAME, prfKey, prfData, keyMaterialLen);
 
         byte[] expectedKeyMat = TestUtils.hexStringToByteArray(FIRST_CHILD_KEY_MAT);
         assertArrayEquals(expectedKeyMat, calculatedKeyMat);
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java
new file mode 100644
index 0000000..a2c4d1f
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthDigitalSignPayloadTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public final class IkeAuthDigitalSignPayloadTest {
+
+    private static final String AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING =
+            "0e0000000f300d06092a864886f70d01010b05007b2f4456878b1344e803f094"
+                    + "159a59361bc639071b69de41915452c478b77a46ce4a2c96ddc7ba2c18d08406"
+                    + "50ce51c77124605423a2f75d8ed4b5a1ec5944c3396221a39e25def09abe5c9f"
+                    + "6d9cd70e8f6254d4c835015256c9d6c26f0c6d31ac96a2ed802ccb16e48e7ff3"
+                    + "daf736221b18c2a972130a69edb197a505a312882baed95d38a47bf6784533f2"
+                    + "ffee671d742b5ae463216e46ef970ee6a335ffb3fc9c170a680fb802bb950cb0"
+                    + "5601339be8869a73f8f85254d792b6e91697d8893ccd34b5fb6aad6268c4ab0f"
+                    + "9ead7b3f8a4a255e1b2eabfa3da0de284f3954cf49271918dd2d2db95c8e7812"
+                    + "9aea77e5761ac5683a0b5af300ceb52f5e8d8168";
+    // TODO: Build a RSA_SHA1 signature and add tests for it.
+
+    @Test
+    public void testDecodeGenericDigitalSignPayload() throws Exception {
+        byte[] inputPacket =
+                TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING);
+        IkeAuthPayload payload = IkeAuthPayload.getIkeAuthPayload(false, inputPacket);
+
+        assertTrue(payload instanceof IkeAuthDigitalSignPayload);
+        IkeAuthDigitalSignPayload dsPayload = (IkeAuthDigitalSignPayload) payload;
+        assertEquals(
+                IkeAuthDigitalSignPayload.SIGNATURE_ALGO_RSA_SHA2_256,
+                dsPayload.signatureAlgoAndHash);
+    }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthPayloadTest.java
similarity index 84%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthPayloadTest.java
index 989b468..7c630b7 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthPayloadTest.java
@@ -14,23 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-
-import org.junit.Before;
 import org.junit.Test;
 
+import javax.crypto.Mac;
+
 public final class IkeAuthPayloadTest {
     private static final String PSK_AUTH_PAYLOAD_HEX_STRING =
             "02000000df7c038aefaaa32d3f44b228b52a332744dfb2c1";
@@ -84,15 +78,7 @@
 
     private static final int AUTH_METHOD_POSITION = 0;
 
-    private IkeMacPrf mIkeHmacSha1Prf;
-
-    @Before
-    public void setUp() throws Exception {
-        mIkeHmacSha1Prf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-    }
+    private static final String PRF_HMAC_SHA1_ALGO_NAME = "HmacSHA1";
 
     @Test
     public void testDecodeIkeAuthPayload() throws Exception {
@@ -114,12 +100,26 @@
         try {
             IkeAuthPayload payload = IkeAuthPayload.getIkeAuthPayload(false, inputPacket);
             fail("Expected Exception: authentication method is not supported");
-        } catch (AuthenticationFailedException e) {
+        } catch (UnsupportedOperationException e) {
+            // TODO: Catch AuthenticationFailedException after it is implemented.
         }
     }
 
     @Test
+    public void testSignWithPrf() throws Exception {
+        Mac prfMac = Mac.getInstance(PRF_HMAC_SHA1_ALGO_NAME, IkeMessage.getSecurityProvider());
+        byte[] skpBytes = TestUtils.hexStringToByteArray(PSK_SKP_HEX_STRING);
+        byte[] idBytes = TestUtils.hexStringToByteArray(PSK_ID_PAYLOAD_HEX_STRING);
+        byte[] calculatedBytes = IkeAuthPayload.signWithPrf(prfMac, skpBytes, idBytes);
+
+        byte[] expectedBytes =
+                TestUtils.hexStringToByteArray(PSK_SIGNED_OCTETS_APPENDIX_HEX_STRING);
+        assertArrayEquals(expectedBytes, calculatedBytes);
+    }
+
+    @Test
     public void testGetSignedOctets() throws Exception {
+        Mac prfMac = Mac.getInstance(PRF_HMAC_SHA1_ALGO_NAME, IkeMessage.getSecurityProvider());
         byte[] skpBytes = TestUtils.hexStringToByteArray(PSK_SKP_HEX_STRING);
         byte[] idBytes = TestUtils.hexStringToByteArray(PSK_ID_PAYLOAD_HEX_STRING);
         byte[] ikeInitRequest = TestUtils.hexStringToByteArray(PSK_IKE_INIT_REQUEST_HEX_STRING);
@@ -127,7 +127,7 @@
 
         byte[] calculatedBytes =
                 IkeAuthPayload.getSignedOctets(
-                        ikeInitRequest, nonceResp, idBytes, mIkeHmacSha1Prf, skpBytes);
+                        ikeInitRequest, nonceResp, idBytes, prfMac, skpBytes);
         byte[] expectedBytes = TestUtils.hexStringToByteArray(PSK_INIT_SIGNED_OCTETS);
     }
 }
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthPskPayloadTest.java
similarity index 86%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthPskPayloadTest.java
index cad6052..baa8059 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthPskPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeAuthPskPayloadTest.java
@@ -14,25 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
-import android.net.ipsec.ike.SaProposal;
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-
-import org.junit.Before;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 
+import javax.crypto.Mac;
+
 public final class IkeAuthPskPayloadTest {
     private static final String PSK_AUTH_PAYLOAD_HEX_STRING =
             "2100001c02000000df7c038aefaaa32d3f44b228b52a332744dfb2c1";
@@ -66,6 +62,8 @@
     private static final String PSK_HEX_STRING = "6A756E69706572313233";
     private static final String PSK_SKP_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485";
 
+    private static final String PRF_HMAC_SHA1_ALGO_NAME = "HmacSHA1";
+
     private static final byte[] PSK = TestUtils.hexStringToByteArray(PSK_HEX_STRING);
     private static final byte[] IKE_INIT_REQUEST =
             TestUtils.hexStringToByteArray(PSK_IKE_INIT_REQUEST_HEX_STRING);
@@ -76,21 +74,13 @@
     private static final byte[] SIGNATURE =
             TestUtils.hexStringToByteArray(PSK_AUTH_PAYLOAD_SIGNATURE_HEX_STRING);
 
-    private IkeMacPrf mIkeHmacSha1Prf;
-
-    @Before
-    public void setUp() throws Exception {
-        mIkeHmacSha1Prf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-    }
-
     @Test
     public void testBuildOutboundIkeAuthPskPayload() throws Exception {
+        Mac prfMac = Mac.getInstance(PRF_HMAC_SHA1_ALGO_NAME, IkeMessage.getSecurityProvider());
+
         IkeAuthPskPayload payload =
                 new IkeAuthPskPayload(
-                        PSK, IKE_INIT_REQUEST, NONCE, ID_PAYLOAD_BODY, mIkeHmacSha1Prf, PRF_KEY);
+                        PSK, IKE_INIT_REQUEST, NONCE, ID_PAYLOAD_BODY, prfMac, PRF_KEY);
 
         assertEquals(IkeAuthPayload.AUTH_METHOD_PRE_SHARED_KEY, payload.authMethod);
         assertArrayEquals(SIGNATURE, payload.signature);
@@ -122,21 +112,23 @@
 
     @Test
     public void testVerifyReceivedSignature() throws Exception {
+        Mac prfMac = Mac.getInstance(PRF_HMAC_SHA1_ALGO_NAME, IkeMessage.getSecurityProvider());
         IkeAuthPskPayload pskPayload = buildPskPayload();
 
         pskPayload.verifyInboundSignature(
-                PSK, IKE_INIT_REQUEST, NONCE, ID_PAYLOAD_BODY, mIkeHmacSha1Prf, PRF_KEY);
+                PSK, IKE_INIT_REQUEST, NONCE, ID_PAYLOAD_BODY, prfMac, PRF_KEY);
     }
 
     @Test
     public void testVerifyReceivedSignatureFailure() throws Exception {
+        Mac prfMac = Mac.getInstance(PRF_HMAC_SHA1_ALGO_NAME, IkeMessage.getSecurityProvider());
         IkeAuthPskPayload pskPayload = buildPskPayload();
         byte[] nonce = Arrays.copyOf(NONCE, NONCE.length);
         nonce[0]++;
 
         try {
             pskPayload.verifyInboundSignature(
-                    PSK, IKE_INIT_REQUEST, nonce, ID_PAYLOAD_BODY, mIkeHmacSha1Prf, PRF_KEY);
+                    PSK, IKE_INIT_REQUEST, nonce, ID_PAYLOAD_BODY, prfMac, PRF_KEY);
             fail("Expected signature verification to have failed due to mismatched signatures.");
         } catch (AuthenticationFailedException expected) {
         }
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeCertX509CertPayloadTest.java
similarity index 97%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeCertX509CertPayloadTest.java
index ef6ec28..fcf5f55 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertX509CertPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeCertX509CertPayloadTest.java
@@ -14,14 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
 
 import org.junit.Test;
 
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeDeletePayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeDeletePayloadTest.java
new file mode 100644
index 0000000..1a7b9a2
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeDeletePayloadTest.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public final class IkeDeletePayloadTest {
+    private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000";
+    private static final String DELETE_CHILD_PAYLOAD_HEX_STRING = "0000000c030400012ad4c0a2";
+    private static final String CHILD_SPI = "2ad4c0a2";
+
+    private static final int NUM_CHILD_SPI = 1;
+
+    private static final int PROTOCOL_ID_OFFSET = 4;
+    private static final int SPI_SIZE_OFFSET = 5;
+    private static final int NUM_OF_SPI_OFFSET = 6;
+
+    @Test
+    public void testDecodeDeleteIkePayload() throws Exception {
+        ByteBuffer inputBuffer =
+                ByteBuffer.wrap(TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING));
+
+        IkePayload payload =
+                IkePayloadFactory.getIkePayload(
+                                IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer)
+                        .first;
+
+        assertTrue(payload instanceof IkeDeletePayload);
+
+        IkeDeletePayload deletePayload = (IkeDeletePayload) payload;
+        assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId);
+        assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, deletePayload.spiSize);
+        assertEquals(0, deletePayload.numSpi);
+        assertArrayEquals(new int[0], deletePayload.spisToDelete);
+    }
+
+    @Test
+    public void testDecodeDeleteChildPayload() throws Exception {
+        ByteBuffer inputBuffer =
+                ByteBuffer.wrap(TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING));
+
+        IkePayload payload =
+                IkePayloadFactory.getIkePayload(
+                                IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer)
+                        .first;
+
+        assertTrue(payload instanceof IkeDeletePayload);
+
+        IkeDeletePayload deletePayload = (IkeDeletePayload) payload;
+        assertEquals(IkePayload.PROTOCOL_ID_ESP, deletePayload.protocolId);
+        assertEquals(IkePayload.SPI_LEN_IPSEC, deletePayload.spiSize);
+        assertEquals(NUM_CHILD_SPI, deletePayload.numSpi);
+
+        byte[] childSpiBytes = TestUtils.hexStringToByteArray(CHILD_SPI);
+        ByteBuffer buffer = ByteBuffer.wrap(childSpiBytes);
+        int expectedChildSpi = buffer.getInt();
+
+        assertArrayEquals(new int[] {expectedChildSpi}, deletePayload.spisToDelete);
+    }
+
+    @Test
+    public void testDecodeWithInvalidProtocol() throws Exception {
+        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
+        deletePayloadBytes[PROTOCOL_ID_OFFSET] = -1;
+        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
+
+        try {
+            IkePayloadFactory.getIkePayload(
+                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
+            fail("Expected to fail due to unrecognized protocol ID.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeWithInvalidSpiSize() throws Exception {
+        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
+        deletePayloadBytes[SPI_SIZE_OFFSET] = IkePayload.SPI_LEN_IPSEC;
+        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
+
+        try {
+            IkePayloadFactory.getIkePayload(
+                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
+            fail("Expected to fail due to invalid SPI size in Delete IKE Payload.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeWithInvalidNumSpi() throws Exception {
+        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
+        deletePayloadBytes[NUM_OF_SPI_OFFSET] = 1;
+        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
+
+        try {
+            IkePayloadFactory.getIkePayload(
+                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
+            fail("Expected to fail because number of SPI is not zero in Delete IKE Payload.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+
+    @Test
+    public void testDecodeWithInvalidNumSpiAndSpiSize() throws Exception {
+        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
+        deletePayloadBytes[SPI_SIZE_OFFSET] = 1;
+        deletePayloadBytes[NUM_CHILD_SPI] = 4;
+        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
+
+        try {
+            IkePayloadFactory.getIkePayload(
+                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
+            fail("Expected to fail due to invalid SPI size in Delete IKE Payload.");
+        } catch (InvalidSyntaxException expected) {
+
+        }
+    }
+}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java
new file mode 100644
index 0000000..fcb3eff
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeEncryptedPayloadBodyTest.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.GeneralSecurityException;
+import java.util.Arrays;
+
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+public final class IkeEncryptedPayloadBodyTest {
+
+    private static final String IKE_AUTH_INIT_REQUEST_HEADER =
+            "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec";
+    private static final String IKE_AUTH_INIT_REQUEST_SK_HEADER = "230000d0";
+    private static final String IKE_AUTH_INIT_REQUEST_IV = "b9132b7bb9f658dfdc648e5017a6322a";
+    private static final String IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA =
+            "030c316ce55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58"
+                    + "46de333ecd3ea2b705d18293b130395300ba92a351041345"
+                    + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f"
+                    + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60"
+                    + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b"
+                    + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423"
+                    + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3"
+                    + "59eb4e81";
+    private static final String IKE_AUTH_INIT_REQUEST_CHECKSUM = "ae6e0f22abdad69ba8007d50";
+
+    private static final String IKE_AUTH_INIT_REQUEST_UNENCRYPTED_DATA =
+            "2400000c010000000a50500d2700000c010000000a505050"
+                    + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327"
+                    + "44dfb2c12c00002c00000028010304032ad4c0a20300000c"
+                    + "0100000c800e008003000008030000020000000805000000"
+                    + "2d00001801000000070000100000ffff00000000ffffffff"
+                    + "2900001801000000070000100000ffff00000000ffffffff"
+                    + "29000008000040000000000c0000400100000001";
+    private static final String IKE_AUTH_INIT_REQUEST_PADDING = "0000000000000000000000";
+    private static final int HMAC_SHA1_CHECKSUM_LEN = 12;
+
+    private static final String ENCR_KEY_FROM_INIT_TO_RESP = "5cbfd33f75796c0188c4a3a546aec4a1";
+    private static final String INTE_KEY_FROM_INIT_TO_RESP =
+            "554fbf5a05b7f511e05a30ce23d874db9ef55e51";
+
+    private static final String ENCR_ALGO_AES_CBC = "AES/CBC/NoPadding";
+    private static final String INTE_ALGO_HMAC_SHA1 = "HmacSHA1";
+
+    private Cipher mAesCbcCipher;
+    private SecretKey mAesCbcKey;
+    private Mac mHmacSha1IntegrityMac;
+
+    private byte[] mDataToPadAndEncrypt;
+    private byte[] mDataToAuthenticate;
+    private byte[] mEncryptedPaddedData;
+    private byte[] mIkeMessage;
+
+    private byte[] mChecksum;
+    private byte[] mIv;
+    private byte[] mPadding;
+
+    // TODO: Add tests for authenticating and decrypting received message.
+    @Before
+    public void setUp() throws Exception {
+        mDataToPadAndEncrypt =
+                TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_UNENCRYPTED_DATA);
+        String hexStringToAuthenticate =
+                IKE_AUTH_INIT_REQUEST_HEADER
+                        + IKE_AUTH_INIT_REQUEST_SK_HEADER
+                        + IKE_AUTH_INIT_REQUEST_IV
+                        + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA;
+        mDataToAuthenticate = TestUtils.hexStringToByteArray(hexStringToAuthenticate);
+        mEncryptedPaddedData =
+                TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA);
+        mIkeMessage =
+                TestUtils.hexStringToByteArray(
+                        IKE_AUTH_INIT_REQUEST_HEADER
+                                + IKE_AUTH_INIT_REQUEST_SK_HEADER
+                                + IKE_AUTH_INIT_REQUEST_IV
+                                + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA
+                                + IKE_AUTH_INIT_REQUEST_CHECKSUM);
+
+        mChecksum = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_CHECKSUM);
+        mIv = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_IV);
+        mPadding = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_PADDING);
+
+        mAesCbcCipher = Cipher.getInstance(ENCR_ALGO_AES_CBC, IkeMessage.getSecurityProvider());
+        byte[] encryptKeyBytes = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP);
+        mAesCbcKey = new SecretKeySpec(encryptKeyBytes, ENCR_ALGO_AES_CBC);
+
+        mHmacSha1IntegrityMac =
+                Mac.getInstance(INTE_ALGO_HMAC_SHA1, IkeMessage.getSecurityProvider());
+        byte[] integrityKeyBytes = TestUtils.hexStringToByteArray(INTE_KEY_FROM_INIT_TO_RESP);
+        SecretKeySpec integrityKey = new SecretKeySpec(integrityKeyBytes, INTE_ALGO_HMAC_SHA1);
+        mHmacSha1IntegrityMac.init(integrityKey);
+    }
+
+    @Test
+    public void testCalculateChecksum() throws Exception {
+        byte[] calculatedChecksum =
+                IkeEncryptedPayloadBody.calculateChecksum(
+                        mDataToAuthenticate, mHmacSha1IntegrityMac, HMAC_SHA1_CHECKSUM_LEN);
+
+        assertArrayEquals(mChecksum, calculatedChecksum);
+    }
+
+    @Test
+    public void testValidateChecksum() throws Exception {
+        IkeEncryptedPayloadBody.validateChecksumOrThrow(
+                mDataToAuthenticate, mHmacSha1IntegrityMac, mChecksum);
+    }
+
+    @Test
+    public void testThrowForInvalidChecksum() throws Exception {
+        byte[] dataToAuthenticate = Arrays.copyOf(mDataToAuthenticate, mDataToAuthenticate.length);
+        dataToAuthenticate[0]++;
+
+        try {
+            IkeEncryptedPayloadBody.validateChecksumOrThrow(
+                    dataToAuthenticate, mHmacSha1IntegrityMac, mChecksum);
+            fail("Expected GeneralSecurityException due to mismatched checksum.");
+        } catch (GeneralSecurityException expected) {
+        }
+    }
+
+    @Test
+    public void testCalculatePaddingPlaintextShorterThanBlockSize() throws Exception {
+        int blockSize = 16;
+        int plainTextLength = 15;
+        int expectedPadLength = 0;
+
+        byte[] calculatedPadding =
+                IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize);
+        assertEquals(expectedPadLength, calculatedPadding.length);
+    }
+
+    @Test
+    public void testCalculatePaddingPlaintextInBlockSize() throws Exception {
+        int blockSize = 16;
+        int plainTextLength = 16;
+        int expectedPadLength = 15;
+
+        byte[] calculatedPadding =
+                IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize);
+        assertEquals(expectedPadLength, calculatedPadding.length);
+    }
+
+    @Test
+    public void testCalculatePaddingPlaintextLongerThanBlockSize() throws Exception {
+        int blockSize = 16;
+        int plainTextLength = 17;
+        int expectedPadLength = 14;
+
+        byte[] calculatedPadding =
+                IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize);
+        assertEquals(expectedPadLength, calculatedPadding.length);
+    }
+
+    @Test
+    public void testEncrypt() throws Exception {
+        byte[] calculatedData =
+                IkeEncryptedPayloadBody.encrypt(
+                        mDataToPadAndEncrypt, mAesCbcCipher, mAesCbcKey, mIv, mPadding);
+
+        assertArrayEquals(mEncryptedPaddedData, calculatedData);
+    }
+
+    @Test
+    public void testDecrypt() throws Exception {
+        byte[] calculatedPlainText =
+                IkeEncryptedPayloadBody.decrypt(
+                        mEncryptedPaddedData, mAesCbcCipher, mAesCbcKey, mIv);
+
+        assertArrayEquals(mDataToPadAndEncrypt, calculatedPlainText);
+    }
+
+    @Test
+    public void testBuildAndEncodeOutboundIkeEncryptedPayloadBody() throws Exception {
+        IkeHeader ikeHeader = new IkeHeader(mIkeMessage);
+
+        IkeEncryptedPayloadBody paylaodBody =
+                new IkeEncryptedPayloadBody(
+                        ikeHeader,
+                        IkePayload.PAYLOAD_TYPE_ID_INITIATOR,
+                        mDataToPadAndEncrypt,
+                        mHmacSha1IntegrityMac,
+                        HMAC_SHA1_CHECKSUM_LEN,
+                        mAesCbcCipher,
+                        mAesCbcKey,
+                        mIv,
+                        mPadding);
+
+        byte[] expectedEncodedData =
+                TestUtils.hexStringToByteArray(
+                        IKE_AUTH_INIT_REQUEST_IV
+                                + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA
+                                + IKE_AUTH_INIT_REQUEST_CHECKSUM);
+        assertArrayEquals(expectedEncodedData, paylaodBody.encode());
+    }
+
+    @Test
+    public void testAuthenticateAndDecryptInboundIkeEncryptedPayloadBody() throws Exception {
+        IkeEncryptedPayloadBody paylaodBody =
+                new IkeEncryptedPayloadBody(
+                        mIkeMessage,
+                        mHmacSha1IntegrityMac,
+                        HMAC_SHA1_CHECKSUM_LEN,
+                        mAesCbcCipher,
+                        mAesCbcKey);
+
+        assertArrayEquals(mDataToPadAndEncrypt, paylaodBody.getUnencryptedData());
+    }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeHeaderTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeHeaderTest.java
similarity index 82%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeHeaderTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeHeaderTest.java
index 4592815..08b1612 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeHeaderTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeHeaderTest.java
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidMajorVersionException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.exceptions.InvalidMajorVersionException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
 
 import org.junit.Test;
 
@@ -100,12 +100,15 @@
         inputPacket[VERSION_OFFSET] = (byte) 0x30;
         // Set Exchange type 0
         inputPacket[EXCHANGE_TYPE_OFFSET] = (byte) 0x00;
-
-        InvalidMajorVersionException exception =
-                IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(
-                        inputPacket, InvalidMajorVersionException.class);
-
-        assertEquals(3, exception.getMajorVerion());
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage.decode(header, inputPacket);
+            fail(
+                    "Expected InvalidMajorVersionException: major version is 3"
+                            + "and exchange type is 0");
+        } catch (InvalidMajorVersionException expected) {
+            assertEquals(3, expected.receivedMajorVersion);
+        }
     }
 
     @Test
@@ -113,8 +116,12 @@
         byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
         // Set Exchange type 0
         inputPacket[EXCHANGE_TYPE_OFFSET] = (byte) 0x00;
-
-        IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class);
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage.decode(header, inputPacket);
+            fail("Expected InvalidSyntaxException: exchange type is 0");
+        } catch (InvalidSyntaxException expected) {
+        }
     }
 
     @Test
@@ -122,8 +129,12 @@
         byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
         // Set Exchange type 0
         inputPacket[MESSAGE_LENGTH_OFFSET] = (byte) 0x01;
-
-        IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class);
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage.decode(header, inputPacket);
+            fail("Expected InvalidSyntaxException: IKE message length.");
+        } catch (InvalidSyntaxException expected) {
+        }
     }
 
     @Test
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeIdPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeIdPayloadTest.java
new file mode 100644
index 0000000..893857a
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeIdPayloadTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.ike.ikev2.IkeIdentification;
+import com.android.ike.ikev2.IkeIdentification.IkeIpv4AddrIdentification;
+import com.android.ike.ikev2.IkeIdentification.IkeIpv6AddrIdentification;
+import com.android.ike.ikev2.exceptions.AuthenticationFailedException;
+
+import org.junit.Test;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.nio.ByteBuffer;
+
+public final class IkeIdPayloadTest {
+
+    private static final String IPV4_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING =
+            "2700000c01000000c0000264";
+    private static final String IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING = "01000000c0000264";
+    private static final String IPV4_ADDR_STRING = "192.0.2.100";
+
+    private static final String IPV6_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING =
+            "27000018050000000000200100000db80000000000000001";
+    private static final String IPV6_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING =
+            "050000000000200100000db80000000000000001";
+    private static final String IPV6_ADDR_STRING = "0:2001:0:db8::1";
+
+    private static final int ID_TYPE_OFFSET = 0;
+
+    @Test
+    public void testDecodeIpv4AddrIdPayload() throws Exception {
+        byte[] inputPacket =
+                TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING);
+        IkeIdPayload payload = new IkeIdPayload(false, inputPacket, false);
+
+        assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType);
+        assertEquals(IkeIdentification.ID_TYPE_IPV4_ADDR, payload.ikeId.idType);
+        IkeIpv4AddrIdentification ikeId = (IkeIpv4AddrIdentification) payload.ikeId;
+        Inet4Address expectedAddr = (Inet4Address) Inet4Address.getByName(IPV4_ADDR_STRING);
+        assertEquals(expectedAddr, ikeId.ipv4Address);
+    }
+
+    @Test
+    public void testDecodeIpv6AddrIdPayload() throws Exception {
+        byte[] inputPacket =
+                TestUtils.hexStringToByteArray(IPV6_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING);
+        IkeIdPayload payload = new IkeIdPayload(false, inputPacket, false);
+
+        assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType);
+        assertEquals(IkeIdentification.ID_TYPE_IPV6_ADDR, payload.ikeId.idType);
+        IkeIpv6AddrIdentification ikeId = (IkeIpv6AddrIdentification) payload.ikeId;
+        Inet6Address expectedAddr = (Inet6Address) Inet6Address.getByName(IPV6_ADDR_STRING);
+        assertEquals(expectedAddr, ikeId.ipv6Address);
+    }
+
+    @Test
+    public void testDecodeUnsupportedIdType() throws Exception {
+        byte[] inputPacket =
+                TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING);
+        inputPacket[ID_TYPE_OFFSET] = 0;
+
+        try {
+            new IkeIdPayload(false, inputPacket, true);
+            fail("Expected AuthenticationFailedException: ID Type is unsupported.");
+        } catch (AuthenticationFailedException expected) {
+        }
+    }
+
+    @Test
+    public void testConstructAndEncodeIpv4AddrIdPayload() throws Exception {
+        Inet4Address ipv4Address = (Inet4Address) Inet4Address.getByName(IPV4_ADDR_STRING);
+        IkeIdPayload payload = new IkeIdPayload(false, new IkeIpv4AddrIdentification(ipv4Address));
+
+        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
+        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_AUTH, inputBuffer);
+
+        byte[] expectedBytes =
+                TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING);
+        assertArrayEquals(expectedBytes, inputBuffer.array());
+    }
+
+    @Test
+    public void testConstructAndEncodeIpv6AddrIdPayload() throws Exception {
+        Inet6Address ipv6Address = (Inet6Address) Inet6Address.getByName(IPV6_ADDR_STRING);
+        IkeIdPayload payload = new IkeIdPayload(false, new IkeIpv6AddrIdentification(ipv6Address));
+
+        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
+        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_AUTH, inputBuffer);
+
+        byte[] expectedBytes =
+                TestUtils.hexStringToByteArray(IPV6_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING);
+        assertArrayEquals(expectedBytes, inputBuffer.array());
+    }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java
similarity index 87%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java
index f5046dc..1bb0b70 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeKePayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeKePayloadTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -22,19 +22,15 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.net.ipsec.ike.SaProposal;
+import com.android.ike.ikev2.IkeDhParams;
+import com.android.ike.ikev2.SaProposal;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.utils.BigIntegerUtils;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.IkeDhParams;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.utils.BigIntegerUtils;
-
-import org.junit.Before;
 import org.junit.Test;
 
 import java.math.BigInteger;
 import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
 import java.util.Arrays;
 
 import javax.crypto.spec.DHPrivateKeySpec;
@@ -97,19 +93,6 @@
                     + "F408ED31B63C6E6D";
     private static final String KEY_EXCHANGE_ALGORITHM = "DH";
 
-    private DHPrivateKeySpec mPrivateKeySpec;
-
-    @Before
-    public void setUp() throws Exception {
-        BigInteger primeValue =
-                BigIntegerUtils.unsignedHexStringToBigInteger(PRIME_1024_BIT_MODP_160_SUBGROUP);
-        BigInteger baseGenValue =
-                BigIntegerUtils.unsignedHexStringToBigInteger(GENERATOR_1024_BIT_MODP_160_SUBGROUP);
-        BigInteger privateKeyValue =
-                BigIntegerUtils.unsignedHexStringToBigInteger(PRIVATE_KEY_LOCAL);
-        mPrivateKeySpec = new DHPrivateKeySpec(privateKeyValue, primeValue, baseGenValue);
-    }
-
     @Test
     public void testDecodeIkeKePayload() throws Exception {
         byte[] inputPacket = TestUtils.hexStringToByteArray(KE_PAYLOAD_RAW_PACKET);
@@ -180,21 +163,19 @@
     // recipient test in real Key Exchange process. But it is suitable for testing.
     @Test
     public void testGetSharedkey() throws Exception {
+        BigInteger primeValue =
+                BigIntegerUtils.unsignedHexStringToBigInteger(PRIME_1024_BIT_MODP_160_SUBGROUP);
+        BigInteger baseGenValue =
+                BigIntegerUtils.unsignedHexStringToBigInteger(GENERATOR_1024_BIT_MODP_160_SUBGROUP);
+        BigInteger privateKeyValue =
+                BigIntegerUtils.unsignedHexStringToBigInteger(PRIVATE_KEY_LOCAL);
         byte[] remotePublicKey = TestUtils.hexStringToByteArray(PUBLIC_KEY_REMOTE);
-        byte[] sharedKeyBytes = IkeKePayload.getSharedKey(mPrivateKeySpec, remotePublicKey);
+
+        DHPrivateKeySpec privateKeySpec =
+                new DHPrivateKeySpec(privateKeyValue, primeValue, baseGenValue);
+        byte[] sharedKeyBytes = IkeKePayload.getSharedKey(privateKeySpec, remotePublicKey);
 
         byte[] expectedSharedKeyBytes = TestUtils.hexStringToByteArray(EXPECTED_SHARED_KEY);
         assertTrue(Arrays.equals(expectedSharedKeyBytes, sharedKeyBytes));
     }
-
-    @Test
-    public void testGetSharedkeyWithInvalidRemoteKey() throws Exception {
-        byte[] remotePublicKey = TestUtils.hexStringToByteArray(PRIME_1024_BIT_MODP_160_SUBGROUP);
-
-        try {
-            byte[] sharedKeyBytes = IkeKePayload.getSharedKey(mPrivateKeySpec, remotePublicKey);
-            fail("Expected to fail because of invalid remote public key.");
-        } catch (GeneralSecurityException expected) {
-        }
-    }
 }
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeMessageTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeMessageTest.java
new file mode 100644
index 0000000..961abb3
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeMessageTest.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.exceptions.UnsupportedCriticalPayloadException;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public final class IkeMessageTest {
+    private static final String IKE_SA_INIT_HEADER_RAW_PACKET =
+            "8f54bf6d8b48e6e10000000000000000212022080000000000000150";
+    private static final String IKE_SA_INIT_BODY_RAW_PACKET =
+            "220000300000002c010100040300000c0100000c"
+                    + "800e00800300000803000002030000080400000200000008"
+                    + "020000022800008800020000b4a2faf4bb54878ae21d6385"
+                    + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656"
+                    + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37"
+                    + "534036040610ebdd92f46bef84f0be7db860351843858f8a"
+                    + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb"
+                    + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024"
+                    + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7"
+                    + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb"
+                    + "881eab2051d8663f421d10b02b00001c00004005d915368c"
+                    + "a036004cb578ae3e3fb268509aeab1900000002069936922"
+                    + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500";
+    private static final String IKE_SA_INIT_RAW_PACKET =
+            IKE_SA_INIT_HEADER_RAW_PACKET + IKE_SA_INIT_BODY_RAW_PACKET;
+
+    // Byte offsets of first payload type in IKE message header.
+    private static final int FIRST_PAYLOAD_TYPE_OFFSET = 16;
+    // Byte offsets of first payload's critical bit in IKE message body.
+    private static final int PAYLOAD_CRITICAL_BIT_OFFSET = 1;
+    // Byte offsets of first payload length in IKE message body.
+    private static final int FIRST_PAYLOAD_LENGTH_OFFSET = 2;
+    // Byte offsets of last payload length in IKE message body.
+    private static final int LAST_PAYLOAD_LENGTH_OFFSET = 278;
+
+    private static final int[] SUPPORTED_PAYLOAD_LIST = {
+        IkePayload.PAYLOAD_TYPE_SA,
+        IkePayload.PAYLOAD_TYPE_KE,
+        IkePayload.PAYLOAD_TYPE_NONCE,
+        IkePayload.PAYLOAD_TYPE_NOTIFY,
+        IkePayload.PAYLOAD_TYPE_NOTIFY,
+        IkePayload.PAYLOAD_TYPE_VENDOR
+    };
+
+    class TestIkeSupportedPayload extends IkePayload {
+        TestIkeSupportedPayload(int payload, boolean critical) {
+            super(payload, critical);
+        }
+
+        @Override
+        protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
+            throw new UnsupportedOperationException(
+                    "It is not supported to encode " + getTypeString());
+        }
+
+        @Override
+        protected int getPayloadLength() {
+            throw new UnsupportedOperationException(
+                    "It is not supported to get payload length of " + getTypeString());
+        }
+
+        @Override
+        public String getTypeString() {
+            return "Test Payload";
+        }
+    }
+
+    @Before
+    public void setUp() {
+        IkePayloadFactory.sDecoderInstance =
+                new IkePayloadFactory.IIkePayloadDecoder() {
+
+                    @Override
+                    public IkePayload decodeIkePayload(
+                            int payloadType, boolean isCritical, boolean isResp, byte[] payloadBody)
+                            throws IkeException {
+                        if (support(payloadType)) {
+                            return new TestIkeSupportedPayload(payloadType, isCritical);
+                        } else {
+                            return new IkeUnsupportedPayload(payloadType, isCritical);
+                        }
+                    }
+                };
+    }
+
+    @After
+    public void tearDown() {
+        IkePayloadFactory.sDecoderInstance = new IkePayloadFactory.IkePayloadDecoder();
+    }
+
+    @Test
+    public void testDecodeIkeMessage() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
+        IkeHeader header = new IkeHeader(inputPacket);
+        IkeMessage message = IkeMessage.decode(header, inputPacket);
+        assertEquals(SUPPORTED_PAYLOAD_LIST.length, message.ikePayloadList.size());
+        for (int i = 0; i < SUPPORTED_PAYLOAD_LIST.length; i++) {
+            assertEquals(SUPPORTED_PAYLOAD_LIST[i], message.ikePayloadList.get(i).payloadType);
+        }
+    }
+
+    @Test
+    public void testDecodeMessageWithUnsupportedUncriticalPayload() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
+        // Set first payload unsupported uncritical
+        inputPacket[FIRST_PAYLOAD_TYPE_OFFSET] = (byte) 0xff;
+        IkeHeader header = new IkeHeader(inputPacket);
+        IkeMessage message = IkeMessage.decode(header, inputPacket);
+        assertEquals(SUPPORTED_PAYLOAD_LIST.length - 1, message.ikePayloadList.size());
+        for (int i = 0; i < SUPPORTED_PAYLOAD_LIST.length - 1; i++) {
+            assertEquals(SUPPORTED_PAYLOAD_LIST[i + 1], message.ikePayloadList.get(i).payloadType);
+        }
+    }
+
+    @Test
+    public void testThrowUnsupportedCriticalPayloadException() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
+        // Set first payload unsupported critical
+        inputPacket[FIRST_PAYLOAD_TYPE_OFFSET] = (byte) 0xff;
+        inputPacket[IkeHeader.IKE_HEADER_LENGTH + PAYLOAD_CRITICAL_BIT_OFFSET] = (byte) 0x80;
+
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage.decode(header, inputPacket);
+            fail(
+                    "Expected UnsupportedCriticalPayloadException: first"
+                            + "payload is unsupported critical.");
+        } catch (UnsupportedCriticalPayloadException expected) {
+            assertEquals(1, expected.payloadTypeList.size());
+        }
+    }
+
+    @Test
+    public void testDecodeMessageWithTooShortPayloadLength() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
+        // Set first payload length to 0
+        inputPacket[IkeHeader.IKE_HEADER_LENGTH + FIRST_PAYLOAD_LENGTH_OFFSET] = (byte) 0;
+        inputPacket[IkeHeader.IKE_HEADER_LENGTH + FIRST_PAYLOAD_LENGTH_OFFSET + 1] = (byte) 0;
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage message = IkeMessage.decode(header, inputPacket);
+            fail("Expected InvalidSyntaxException: Payload length is too short.");
+        } catch (InvalidSyntaxException expected) {
+        }
+    }
+
+    @Test
+    public void testDecodeMessageWithTooLongPayloadLength() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
+        // Increase last payload length by one byte
+        inputPacket[IkeHeader.IKE_HEADER_LENGTH + LAST_PAYLOAD_LENGTH_OFFSET]++;
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage message = IkeMessage.decode(header, inputPacket);
+            fail("Expected InvalidSyntaxException: Payload length is too long.");
+        } catch (InvalidSyntaxException expected) {
+        }
+    }
+
+    @Test
+    public void testDecodeMessageWithExpectedBytesInTheEnd() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET + "0000");
+        IkeHeader header = new IkeHeader(inputPacket);
+        try {
+            IkeMessage message = IkeMessage.decode(header, inputPacket);
+            fail("Expected InvalidSyntaxException: Unexpected bytes in the end of packet.");
+        } catch (InvalidSyntaxException expected) {
+        }
+    }
+
+    private boolean support(int payloadType) {
+        return (payloadType == IkePayload.PAYLOAD_TYPE_SA
+                || payloadType == IkePayload.PAYLOAD_TYPE_KE
+                || payloadType == IkePayload.PAYLOAD_TYPE_NONCE
+                || payloadType == IkePayload.PAYLOAD_TYPE_NOTIFY
+                || payloadType == IkePayload.PAYLOAD_TYPE_VENDOR
+                || payloadType == IkePayload.PAYLOAD_TYPE_SK);
+    }
+
+    @Test
+    public void testAttachEncodedHeader() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
+        byte[] ikeBodyBytes = TestUtils.hexStringToByteArray(IKE_SA_INIT_BODY_RAW_PACKET);
+        IkeHeader header = new IkeHeader(inputPacket);
+        IkeMessage message = IkeMessage.decode(header, inputPacket);
+
+        byte[] encodedIkeMessage = message.attachEncodedHeader(ikeBodyBytes);
+        assertArrayEquals(inputPacket, encodedIkeMessage);
+    }
+
+    // TODO: Implement encodeToByteBuffer() of each payload and add test for encoding message
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeNoncePayloadTest.java
similarity index 94%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeNoncePayloadTest.java
index dd92a45..f4e4a98 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNoncePayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeNoncePayloadTest.java
@@ -14,12 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 
-import com.android.internal.net.TestUtils;
-
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeNotifyPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeNotifyPayloadTest.java
new file mode 100644
index 0000000..3e9ba80
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeNotifyPayloadTest.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+
+import org.junit.Test;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+
+public final class IkeNotifyPayloadTest {
+    private static final String NOTIFY_PAYLOAD_GENERIC_HEADER = "2900001c";
+    private static final String NOTIFY_PAYLOAD_BODY_RAW_PACKET =
+            "00004004e54f73b7d83f6beb881eab2051d8663f421d10b0";
+
+    private static final String NAT_DETECTION_SOURCE_IP_DATA_HEX_STRING =
+            "e54f73b7d83f6beb881eab2051d8663f421d10b0";
+    private static final String IKE_INITIATOR_SPI_HEX_STRING = "5f54bf6d8b48e6e1";
+    private static final String IKE_RESPODNER_SPI_HEX_STRING = "0000000000000000";
+    private static final String IP_ADDR = "10.80.80.13";
+    private static final int PORT = 500;
+
+    private static final int EXPECTED_PROTOCOL_ID = IkePayload.PROTOCOL_ID_UNSET;
+    private static final int EXPECTED_SPI_SIZE = IkePayload.SPI_LEN_NOT_INCLUDED;
+
+    @IkePayload.PayloadType
+    private static final int NEXT_PAYLOAD_TYPE = IkePayload.PAYLOAD_TYPE_NOTIFY;
+
+    @IkeNotifyPayload.NotifyType
+    private static final int EXPECTED_NOTIFY_TYPE =
+            IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP;
+
+    private static final int EXPECTED_NOTIFY_DATA_LEN = 20;
+
+    private static final int POS_PROTOCOL_ID = 0;
+
+    @Test
+    public void testDecodeNotifyPayload() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_PAYLOAD_BODY_RAW_PACKET);
+        IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
+        assertEquals(EXPECTED_PROTOCOL_ID, payload.protocolId);
+        assertEquals(EXPECTED_SPI_SIZE, payload.spiSize);
+        assertEquals(EXPECTED_NOTIFY_TYPE, payload.notifyType);
+        assertEquals(EXPECTED_SPI_SIZE, payload.spi);
+        assertEquals(EXPECTED_NOTIFY_DATA_LEN, payload.notifyData.length);
+    }
+
+    @Test
+    public void testDecodeNotifyPayloadThrowException() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_PAYLOAD_BODY_RAW_PACKET);
+        // Change Protocol ID to ESP
+        inputPacket[POS_PROTOCOL_ID] = (byte) (IkePayload.PROTOCOL_ID_ESP & 0xFF);
+        try {
+            IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
+            fail("Expected InvalidSyntaxException: Protocol ID should not be ESP");
+        } catch (InvalidSyntaxException expected) {
+        }
+    }
+
+    @Test
+    public void testGenerateNatDetectionData() throws Exception {
+        long initiatorIkeSpi = Long.parseLong(IKE_INITIATOR_SPI_HEX_STRING, 16);
+        long responderIkespi = Long.parseLong(IKE_RESPODNER_SPI_HEX_STRING, 16);
+        InetAddress inetAddress = InetAddress.getByName(IP_ADDR);
+
+        byte[] netDetectionData =
+                IkeNotifyPayload.generateNatDetectionData(
+                        initiatorIkeSpi, responderIkespi, inetAddress, PORT);
+
+        byte[] expectedBytes =
+                TestUtils.hexStringToByteArray(NAT_DETECTION_SOURCE_IP_DATA_HEX_STRING);
+        assertArrayEquals(expectedBytes, netDetectionData);
+    }
+
+    @Test
+    public void testEncodeNotifyPayload() throws Exception {
+        byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_PAYLOAD_BODY_RAW_PACKET);
+        IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
+
+        ByteBuffer byteBuffer = ByteBuffer.allocate(payload.getPayloadLength());
+        payload.encodeToByteBuffer(NEXT_PAYLOAD_TYPE, byteBuffer);
+
+        byte[] expectedNoncePayload =
+                TestUtils.hexStringToByteArray(
+                        NOTIFY_PAYLOAD_GENERIC_HEADER + NOTIFY_PAYLOAD_BODY_RAW_PACKET);
+        assertArrayEquals(expectedNoncePayload, byteBuffer.array());
+    }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java
similarity index 69%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java
index 750ff46..afb3a81 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSaPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSaPayloadTest.java
@@ -14,69 +14,54 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
-import android.net.IpSecManager;
-import android.net.IpSecSpiResponse;
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.IkeSaProposal;
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
 import android.util.Pair;
 
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Attribute;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.AttributeDecoder;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.ChildProposal;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EsnTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IkeProposal;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.KeyLengthAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Proposal;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.Transform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.TransformDecoder;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.UnrecognizedAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.UnrecognizedTransform;
-import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
-import com.android.server.IpSecService;
-
-import libcore.net.InetAddressUtils;
+import com.android.ike.ikev2.SaProposal;
+import com.android.ike.ikev2.exceptions.IkeException;
+import com.android.ike.ikev2.exceptions.InvalidSyntaxException;
+import com.android.ike.ikev2.exceptions.NoValidProposalChosenException;
+import com.android.ike.ikev2.message.IkeSaPayload.Attribute;
+import com.android.ike.ikev2.message.IkeSaPayload.AttributeDecoder;
+import com.android.ike.ikev2.message.IkeSaPayload.DhGroupTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.EncryptionTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.EsnTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.IntegrityTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.KeyLengthAttribute;
+import com.android.ike.ikev2.message.IkeSaPayload.PrfTransform;
+import com.android.ike.ikev2.message.IkeSaPayload.Proposal;
+import com.android.ike.ikev2.message.IkeSaPayload.Transform;
+import com.android.ike.ikev2.message.IkeSaPayload.TransformDecoder;
+import com.android.ike.ikev2.message.IkeSaPayload.UnrecognizedAttribute;
+import com.android.ike.ikev2.message.IkeSaPayload.UnrecognizedTransform;
 
 import org.junit.Before;
 import org.junit.Test;
 
-import java.net.Inet4Address;
-import java.net.InetAddress;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Random;
 
 public final class IkeSaPayloadTest {
     private static final String OUTBOUND_SA_PAYLOAD_HEADER = "22000030";
     private static final String OUTBOUND_PROPOSAL_RAW_PACKET =
-            "0000002C010100040300000C0100000C800E0080030000080300000203000008040"
-                    + "000020000000802000002";
+            "0000002C010100040300000C0100000C800E0080030000080200000203000008030"
+                    + "000020000000804000002";
     private static final String INBOUND_PROPOSAL_RAW_PACKET =
             "0000002c010100040300000c0100000c800e0080030000080300000203000008040"
                     + "000020000000802000002";
@@ -98,12 +83,6 @@
                     + "0300000804000015030000080400001c030000080400001d030000080"
                     + "400001e030000080400001f030000080400000f030000080400001003"
                     + "00000804000012000000080400000e";
-    private static final String INBOUND_CHILD_PROPOSAL_RAW_PACKET =
-            "0000002801030403cae7019f0300000c0100000c800e00800300000803000002000" + "0000805000000";
-    private static final String INBOUND_CHILD_TWO_PROPOSAL_RAW_PACKET =
-            "0200002801030403cae7019f0300000c0100000c800e00800300000803000002000"
-                    + "00008050000000000001802030401cae7019e0000000c01000012800e"
-                    + "0080";
     private static final String ENCR_TRANSFORM_RAW_PACKET = "0300000c0100000c800e0080";
     private static final String PRF_TRANSFORM_RAW_PACKET = "0000000802000002";
     private static final String INTEG_TRANSFORM_RAW_PACKET = "0300000803000002";
@@ -123,19 +102,6 @@
     // Constants for multiple proposals test
     private static final byte[] PROPOSAL_NUMBER_LIST = {1, 2};
 
-    private static final Inet4Address LOCAL_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.4.4"));
-    private static final Inet4Address REMOTE_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.8.8"));
-
-    private static final int DUMMY_CHILD_SPI_RESOURCE_ID_LOCAL_ONE = 0x1234;
-    private static final int DUMMY_CHILD_SPI_RESOURCE_ID_LOCAL_TWO = 0x1235;
-    private static final int DUMMY_CHILD_SPI_RESOURCE_ID_REMOTE = 0x2234;
-
-    private static final int CHILD_SPI_LOCAL_ONE = 0x2ad4c0a2;
-    private static final int CHILD_SPI_LOCAL_TWO = 0x2ad4c0a3;
-    private static final int CHILD_SPI_REMOTE = 0xcae70197;
-
     private AttributeDecoder mMockedAttributeDecoder;
     private KeyLengthAttribute mAttributeKeyLength128;
     private List<Attribute> mAttributeListWithKeyLength128;
@@ -148,21 +114,9 @@
 
     private Transform[] mValidNegotiatedTransformSet;
 
-    private IkeSaProposal mIkeSaProposalOne;
-    private IkeSaProposal mIkeSaProposalTwo;
-    private IkeSaProposal[] mTwoIkeSaProposalsArray;
-
-    private ChildSaProposal mChildSaProposalOne;
-    private ChildSaProposal mChildSaProposalTwo;
-    private ChildSaProposal[] mTwoChildSaProposalsArray;
-
-    private MockIpSecTestUtils mMockIpSecTestUtils;
-    private IpSecService mMockIpSecService;
-    private IpSecManager mIpSecManager;
-
-    private IpSecSpiResponse mDummyIpSecSpiResponseLocalOne;
-    private IpSecSpiResponse mDummyIpSecSpiResponseLocalTwo;
-    private IpSecSpiResponse mDummyIpSecSpiResponseRemote;
+    private SaProposal mSaProposalOne;
+    private SaProposal mSaProposalTwo;
+    private SaProposal[] mTwoSaProposalsArray;
 
     @Before
     public void setUp() throws Exception {
@@ -190,8 +144,8 @@
                     mDhGroup1024Transform
                 };
 
-        mIkeSaProposalOne =
-                new IkeSaProposal.Builder()
+        mSaProposalOne =
+                SaProposal.Builder.newIkeSaProposalBuilder()
                         .addEncryptionAlgorithm(
                                 SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
                         .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
@@ -199,8 +153,8 @@
                         .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
                         .build();
 
-        mIkeSaProposalTwo =
-                new IkeSaProposal.Builder()
+        mSaProposalTwo =
+                SaProposal.Builder.newIkeSaProposalBuilder()
                         .addEncryptionAlgorithm(
                                 SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
                                 SaProposal.KEY_LEN_AES_128)
@@ -211,35 +165,7 @@
                         .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
                         .addDhGroup(SaProposal.DH_GROUP_2048_BIT_MODP)
                         .build();
-        mTwoIkeSaProposalsArray = new IkeSaProposal[] {mIkeSaProposalOne, mIkeSaProposalTwo};
-
-        mChildSaProposalOne =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
-                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
-                        .build();
-        mChildSaProposalTwo =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8,
-                                SaProposal.KEY_LEN_AES_128)
-                        .build();
-        mTwoChildSaProposalsArray =
-                new ChildSaProposal[] {mChildSaProposalOne, mChildSaProposalTwo};
-
-        mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec();
-        mIpSecManager = mMockIpSecTestUtils.getIpSecManager();
-
-        IpSecService mMockIpSecService = mMockIpSecTestUtils.getIpSecService();
-        when(mMockIpSecService.allocateSecurityParameterIndex(
-                        eq(LOCAL_ADDRESS.getHostAddress()), anyInt(), anyObject()))
-                .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(CHILD_SPI_LOCAL_ONE))
-                .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(CHILD_SPI_LOCAL_TWO));
-
-        when(mMockIpSecService.allocateSecurityParameterIndex(
-                        eq(REMOTE_ADDRESS.getHostAddress()), anyInt(), anyObject()))
-                .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(CHILD_SPI_REMOTE));
+        mTwoSaProposalsArray = new SaProposal[] {mSaProposalOne, mSaProposalTwo};
     }
 
     // TODO: Add tearDown() to reset Proposal.sTransformDecoder and Transform.sAttributeDecoder.
@@ -602,7 +528,7 @@
         return new TransformDecoder() {
             @Override
             public Transform[] decodeTransforms(int count, ByteBuffer inputBuffer)
-                    throws IkeProtocolException {
+                    throws IkeException {
                 for (int i = 0; i < count; i++) {
                     // Read length field and move position
                     inputBuffer.getShort();
@@ -628,7 +554,7 @@
         assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, proposal.spiSize);
         assertEquals(IkePayload.SPI_NOT_INCLUDED, proposal.spi);
         assertFalse(proposal.hasUnrecognizedTransform);
-        assertNotNull(proposal.getSaProposal());
+        assertNotNull(proposal.saProposal);
     }
 
     @Test
@@ -649,13 +575,14 @@
 
     @Test
     public void testEncodeProposal() throws Exception {
-        // Construct Proposal for IKE INIT exchange.
-        IkeProposal proposal =
-                IkeProposal.createIkeProposal(
+        Proposal proposal =
+                new Proposal(
                         (byte) PROPOSAL_NUMBER,
+                        IkePayload.PROTOCOL_ID_IKE,
                         IkePayload.SPI_LEN_NOT_INCLUDED,
-                        mIkeSaProposalOne,
-                        LOCAL_ADDRESS);
+                        IkePayload.SPI_NOT_INCLUDED,
+                        mSaProposalOne,
+                        false /*has no unrecognized Tramsform*/);
 
         ByteBuffer byteBuffer = ByteBuffer.allocate(proposal.getProposalLength());
         proposal.encodeToByteBuffer(true /*is the last*/, byteBuffer);
@@ -678,66 +605,42 @@
     }
 
     @Test
-    public void testBuildOutboundIkeRekeySaResponsePayload() throws Exception {
+    public void testBuildIkeSaResponsePayload() throws Exception {
+        final long ikeSpi = new Random().nextLong();
+        final SaProposal[] saProposals = new SaProposal[] {mSaProposalOne};
         IkeSaPayload saPayload =
-                IkeSaPayload.createRekeyIkeSaResponsePayload(
-                        (byte) 1, mIkeSaProposalOne, LOCAL_ADDRESS);
+                new IkeSaPayload(
+                        true, true, IkePayload.SPI_LEN_IKE, new long[] {ikeSpi}, saProposals);
 
         assertTrue(saPayload.isSaResponse);
-        assertEquals(1, saPayload.proposalList.size());
+        assertEquals(saProposals.length, saPayload.proposalList.size());
 
-        IkeProposal proposal = (IkeProposal) saPayload.proposalList.get(0);
+        Proposal proposal = saPayload.proposalList.get(0);
         assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId);
         assertEquals(IkePayload.SPI_LEN_IKE, proposal.spiSize);
-        assertEquals(mIkeSaProposalOne, proposal.saProposal);
-
-        assertNotNull(proposal.getIkeSpiResource());
+        assertEquals(ikeSpi, proposal.spi);
+        assertEquals(mSaProposalOne, proposal.saProposal);
     }
 
     @Test
-    public void testBuildOutboundInitialIkeSaRequestPayload() throws Exception {
-        IkeSaPayload saPayload = IkeSaPayload.createInitialIkeSaPayload(mTwoIkeSaProposalsArray);
+    public void testBuildInitialIkeSaRequestPayload() throws Exception {
+        IkeSaPayload saPayload = new IkeSaPayload(mTwoSaProposalsArray);
 
         assertFalse(saPayload.isSaResponse);
         assertEquals(PROPOSAL_NUMBER_LIST.length, saPayload.proposalList.size());
 
         for (int i = 0; i < saPayload.proposalList.size(); i++) {
-            IkeProposal proposal = (IkeProposal) saPayload.proposalList.get(i);
+            Proposal proposal = saPayload.proposalList.get(i);
             assertEquals(PROPOSAL_NUMBER_LIST[i], proposal.number);
             assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId);
             assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, proposal.spiSize);
-            assertEquals(mTwoIkeSaProposalsArray[i], proposal.saProposal);
-
-            // SA Payload for IKE INIT exchange does not include IKE SPIs.
-            assertNull(proposal.getIkeSpiResource());
-        }
-    }
-
-    @Test
-    public void testBuildOutboundChildSaRequest() throws Exception {
-        IkeSaPayload saPayload =
-                IkeSaPayload.createChildSaRequestPayload(
-                        mTwoChildSaProposalsArray, mIpSecManager, LOCAL_ADDRESS);
-
-        assertFalse(saPayload.isSaResponse);
-        assertEquals(PROPOSAL_NUMBER_LIST.length, saPayload.proposalList.size());
-
-        int[] expectedSpis = new int[] {CHILD_SPI_LOCAL_ONE, CHILD_SPI_LOCAL_TWO};
-        for (int i = 0; i < saPayload.proposalList.size(); i++) {
-            ChildProposal proposal = (ChildProposal) saPayload.proposalList.get(i);
-            assertEquals(PROPOSAL_NUMBER_LIST[i], proposal.number);
-            assertEquals(IkePayload.PROTOCOL_ID_ESP, proposal.protocolId);
-            assertEquals(IkePayload.SPI_LEN_IPSEC, proposal.spiSize);
-            assertEquals(mTwoChildSaProposalsArray[i], proposal.saProposal);
-
-            assertEquals(expectedSpis[i], proposal.getChildSpiResource().getSpi());
+            assertEquals(mTwoSaProposalsArray[i], proposal.saProposal);
         }
     }
 
     @Test
     public void testEncodeIkeSaPayload() throws Exception {
-        IkeSaPayload saPayload =
-                IkeSaPayload.createInitialIkeSaPayload(new IkeSaProposal[] {mIkeSaProposalOne});
+        IkeSaPayload saPayload = new IkeSaPayload(new SaProposal[] {mSaProposalOne});
 
         ByteBuffer byteBuffer = ByteBuffer.allocate(saPayload.getPayloadLength());
         saPayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_KE, byteBuffer);
@@ -748,109 +651,25 @@
         assertArrayEquals(expectedBytes, byteBuffer.array());
     }
 
-    private void buildAndVerifyIkeSaRespProposal(
-            byte[] saResponseBytes, Transform[] decodedTransforms) throws Exception {
+    private void buildAndVerifySaRespProposal(byte[] saResponseBytes, Transform[] decodedTransforms)
+            throws Exception {
         // Build response SA payload from decoding bytes.
         Proposal.sTransformDecoder = getDummyTransformDecoder(decodedTransforms);
         IkeSaPayload respPayload = new IkeSaPayload(false, true, saResponseBytes);
 
-        // Build request SA payload for IKE INIT exchange from SaProposal.
-        IkeSaPayload reqPayload = IkeSaPayload.createInitialIkeSaPayload(mTwoIkeSaProposalsArray);
+        // Build request SA payload from SaProposal.
+        IkeSaPayload reqPayload = new IkeSaPayload(mTwoSaProposalsArray);
 
-        Pair<IkeProposal, IkeProposal> negotiatedProposalPair =
-                IkeSaPayload.getVerifiedNegotiatedIkeProposalPair(
-                        reqPayload, respPayload, REMOTE_ADDRESS);
-        IkeProposal reqProposal = negotiatedProposalPair.first;
-        IkeProposal respProposal = negotiatedProposalPair.second;
+        SaProposal saProposal = respPayload.getVerifiedNegotiatedProposal(reqPayload);
 
-        assertEquals(respPayload.proposalList.get(0).getSaProposal(), respProposal.getSaProposal());
-
-        // SA Payload for IKE INIT exchange does not include IKE SPIs.
-        assertNull(reqProposal.getIkeSpiResource());
-        assertNull(respProposal.getIkeSpiResource());
+        assertEquals(respPayload.proposalList.get(0).saProposal, saProposal);
     }
 
     @Test
-    public void testGetVerifiedNegotiatedIkeProposal() throws Exception {
+    public void testGetVerifiedNegotiatedProposal() throws Exception {
         byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET);
 
-        buildAndVerifyIkeSaRespProposal(inputPacket, mValidNegotiatedTransformSet);
-    }
-
-    private void verifyChildSaNegotiation(
-            IkeSaPayload reqPayload,
-            IkeSaPayload respPayload,
-            IpSecManager ipSecManager,
-            InetAddress remoteAddress,
-            boolean isLocalInit)
-            throws Exception {
-        // SA negotiation
-        Pair<ChildProposal, ChildProposal> negotiatedProposalPair =
-                IkeSaPayload.getVerifiedNegotiatedChildProposalPair(
-                        reqPayload, respPayload, ipSecManager, remoteAddress);
-        ChildProposal reqProposal = negotiatedProposalPair.first;
-        ChildProposal respProposal = negotiatedProposalPair.second;
-
-        // Verify results
-        assertEquals(respPayload.proposalList.get(0).getSaProposal(), respProposal.getSaProposal());
-
-        int initSpi = isLocalInit ? CHILD_SPI_LOCAL_ONE : CHILD_SPI_REMOTE;
-        int respSpi = isLocalInit ? CHILD_SPI_REMOTE : CHILD_SPI_LOCAL_ONE;
-        assertEquals(initSpi, reqProposal.getChildSpiResource().getSpi());
-        assertEquals(respSpi, respProposal.getChildSpiResource().getSpi());
-
-        // Verify SPIs in unselected Proposals have been released.
-        for (Proposal proposal : reqPayload.proposalList) {
-            if (proposal != reqProposal) {
-                assertNull(((ChildProposal) proposal).getChildSpiResource());
-            }
-        }
-    }
-
-    @Test
-    public void testGetVerifiedNegotiatedChildProposalForLocalCreate() throws Exception {
-        // Build local request
-        IkeSaPayload reqPayload =
-                IkeSaPayload.createChildSaRequestPayload(
-                        mTwoChildSaProposalsArray, mIpSecManager, LOCAL_ADDRESS);
-
-        // Build remote response
-        Proposal.sTransformDecoder =
-                getDummyTransformDecoder(mChildSaProposalOne.getAllTransforms());
-        IkeSaPayload respPayload =
-                new IkeSaPayload(
-                        false /*critical*/,
-                        true /*isResp*/,
-                        TestUtils.hexStringToByteArray(INBOUND_CHILD_PROPOSAL_RAW_PACKET));
-
-        verifyChildSaNegotiation(
-                reqPayload, respPayload, mIpSecManager, REMOTE_ADDRESS, true /*isLocalInit*/);
-    }
-
-    @Test
-    public void testGetVerifiedNegotiatedChildProposalForRemoteCreate() throws Exception {
-        Transform[] transformsOne = mChildSaProposalOne.getAllTransforms();
-        Transform[] transformsTwo = mChildSaProposalTwo.getAllTransforms();
-        Transform[] decodedTransforms = new Transform[transformsOne.length + transformsTwo.length];
-        System.arraycopy(transformsOne, 0, decodedTransforms, 0, transformsOne.length);
-        System.arraycopy(
-                transformsTwo, 0, decodedTransforms, transformsOne.length, transformsTwo.length);
-
-        // Build remote request
-        Proposal.sTransformDecoder = getDummyTransformDecoder(decodedTransforms);
-        IkeSaPayload reqPayload =
-                new IkeSaPayload(
-                        false /*critical*/,
-                        false /*isResp*/,
-                        TestUtils.hexStringToByteArray(INBOUND_CHILD_TWO_PROPOSAL_RAW_PACKET));
-
-        // Build local response
-        IkeSaPayload respPayload =
-                IkeSaPayload.createChildSaResponsePayload(
-                        (byte) 1, mChildSaProposalOne, mIpSecManager, LOCAL_ADDRESS);
-
-        verifyChildSaNegotiation(
-                reqPayload, respPayload, mIpSecManager, REMOTE_ADDRESS, false /*isLocalInit*/);
+        buildAndVerifySaRespProposal(inputPacket, mValidNegotiatedTransformSet);
     }
 
     // Test throwing when negotiated proposal in SA response payload has unrecognized Transform.
@@ -864,7 +683,7 @@
         negotiatedTransformSet[0] = new UnrecognizedTransform(-1, 1, new LinkedList<>());
 
         try {
-            buildAndVerifyIkeSaRespProposal(inputPacket, negotiatedTransformSet);
+            buildAndVerifySaRespProposal(inputPacket, negotiatedTransformSet);
             fail("Expected to fail because negotiated proposal has unrecognized Transform.");
         } catch (NoValidProposalChosenException expected) {
         }
@@ -877,7 +696,7 @@
         inputPacket[PROPOSAL_NUMBER_OFFSET] = (byte) 10;
 
         try {
-            buildAndVerifyIkeSaRespProposal(inputPacket, mValidNegotiatedTransformSet);
+            buildAndVerifySaRespProposal(inputPacket, mValidNegotiatedTransformSet);
             fail("Expected to fail due to invalid proposal number.");
         } catch (NoValidProposalChosenException expected) {
         }
@@ -890,7 +709,7 @@
         inputPacket[PROTOCOL_ID_OFFSET] = IkePayload.PROTOCOL_ID_ESP;
 
         try {
-            buildAndVerifyIkeSaRespProposal(inputPacket, mValidNegotiatedTransformSet);
+            buildAndVerifySaRespProposal(inputPacket, mValidNegotiatedTransformSet);
             fail("Expected to fail due to mismatched protocol ID.");
         } catch (NoValidProposalChosenException expected) {
         }
@@ -907,7 +726,7 @@
         negotiatedTransformSet[0] = mEncrAesGcm8Key128Transform;
 
         try {
-            buildAndVerifyIkeSaRespProposal(inputPacket, negotiatedTransformSet);
+            buildAndVerifySaRespProposal(inputPacket, negotiatedTransformSet);
             fail("Expected to fail due to mismatched Transform.");
         } catch (NoValidProposalChosenException expected) {
         }
@@ -919,7 +738,7 @@
         byte[] inputPacket = TestUtils.hexStringToByteArray(INBOUND_PROPOSAL_RAW_PACKET);
 
         try {
-            buildAndVerifyIkeSaRespProposal(inputPacket, new Transform[0]);
+            buildAndVerifySaRespProposal(inputPacket, new Transform[0]);
             fail("Expected to fail due to absence of Transform.");
         } catch (NoValidProposalChosenException expected) {
         }
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSkPayloadTest.java
similarity index 70%
rename from tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayloadTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/message/IkeSkPayloadTest.java
index 898db30..13866fb 100644
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkPayloadTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeSkPayloadTest.java
@@ -14,24 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.ipsec.ike.message;
+package com.android.ike.ikev2.message;
 
 import static org.junit.Assert.assertArrayEquals;
 
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-
 import org.junit.Before;
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
 
+import javax.crypto.Cipher;
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
 public final class IkeSkPayloadTest {
 
     private static final String IKE_AUTH_INIT_REQUEST_HEX_STRING =
@@ -60,29 +57,26 @@
             "554fbf5a05b7f511e05a30ce23d874db9ef55e51";
 
     private static final String ENCR_ALGO_AES_CBC = "AES/CBC/NoPadding";
+    private static final String INTE_ALGO_HMAC_SHA1 = "HmacSHA1";
 
     private static final int CHECKSUM_LEN = 12;
 
-    private IkeCipher mAesCbcDecryptCipher;
-    private byte[] mAesCbcDecryptionKey;
-
-    private IkeMacIntegrity mHmacSha1IntegrityMac;
-    private byte[] mHmacSha1IntegrityKey;
+    private Cipher mAesCbcDecryptCipher;
+    private SecretKey mAesCbcDecryptKey;
+    private Mac mHmacSha1IntegrityMac;
 
     @Before
     public void setUp() throws Exception {
         mAesCbcDecryptCipher =
-                IkeCipher.create(
-                        new EncryptionTransform(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
-                                SaProposal.KEY_LEN_AES_128),
-                        IkeMessage.getSecurityProvider());
-        mAesCbcDecryptionKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP);
+                Cipher.getInstance(ENCR_ALGO_AES_CBC, IkeMessage.getSecurityProvider());
+        byte[] decryptKeyBytes = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP);
+        mAesCbcDecryptKey = new SecretKeySpec(decryptKeyBytes, ENCR_ALGO_AES_CBC);
+
         mHmacSha1IntegrityMac =
-                IkeMacIntegrity.create(
-                        new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96),
-                        IkeMessage.getSecurityProvider());
-        mHmacSha1IntegrityKey = TestUtils.hexStringToByteArray(INTE_KEY_FROM_INIT_TO_RESP);
+                Mac.getInstance(INTE_ALGO_HMAC_SHA1, IkeMessage.getSecurityProvider());
+        byte[] integrityKeyBytes = TestUtils.hexStringToByteArray(INTE_KEY_FROM_INIT_TO_RESP);
+        SecretKeySpec integrityKey = new SecretKeySpec(integrityKeyBytes, INTE_ALGO_HMAC_SHA1);
+        mHmacSha1IntegrityMac.init(integrityKey);
     }
 
     @Test
@@ -93,12 +87,11 @@
 
         IkeSkPayload payload =
                 IkePayloadFactory.getIkeSkPayload(
-                                false /*isSkf*/,
                                 message,
                                 mHmacSha1IntegrityMac,
+                                CHECKSUM_LEN,
                                 mAesCbcDecryptCipher,
-                                mHmacSha1IntegrityKey,
-                                mAesCbcDecryptionKey)
+                                mAesCbcDecryptKey)
                         .first;
         int payloadLength = payload.getPayloadLength();
         ByteBuffer buffer = ByteBuffer.allocate(payloadLength);
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/IkeTsPayloadTest.java b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeTsPayloadTest.java
new file mode 100644
index 0000000..f547526
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/IkeTsPayloadTest.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import java.nio.ByteBuffer;
+
+public final class IkeTsPayloadTest {
+    private static final String TS_INITIATOR_PAYLOAD_HEX_STRING =
+            "2d00002802000000070000100000ffff00000000ffffffff070000100000ffff00000001fffffffe";
+    private static final int NUMBER_OF_TS = 2;
+
+    @Test
+    public void testDecodeTsInitiatorPayload() throws Exception {
+        ByteBuffer inputBuffer =
+                ByteBuffer.wrap(TestUtils.hexStringToByteArray(TS_INITIATOR_PAYLOAD_HEX_STRING));
+
+        IkePayload payload =
+                IkePayloadFactory.getIkePayload(
+                                IkePayload.PAYLOAD_TYPE_TS_INITIATOR, false, inputBuffer)
+                        .first;
+        assertTrue(payload instanceof IkeTsPayload);
+
+        IkeTsPayload tsPayload = (IkeTsPayload) payload;
+        assertEquals(IkePayload.PAYLOAD_TYPE_TS_INITIATOR, tsPayload.payloadType);
+        assertEquals(NUMBER_OF_TS, tsPayload.numTs);
+    }
+}
diff --git a/tests/iketests/src/java/com/android/ike/ikev2/message/TestUtils.java b/tests/iketests/src/java/com/android/ike/ikev2/message/TestUtils.java
new file mode 100644
index 0000000..1fcdac0
--- /dev/null
+++ b/tests/iketests/src/java/com/android/ike/ikev2/message/TestUtils.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.ike.ikev2.message;
+
+import android.util.Pair;
+
+import com.android.ike.ikev2.exceptions.IkeException;
+
+import java.nio.ByteBuffer;
+
+/** TestUtils provides utility methods for parsing Hex String */
+public final class TestUtils {
+
+    public static byte[] hexStringToByteArray(String hexString) throws IllegalArgumentException {
+        int len = hexString.length();
+        if (len % 2 != 0) {
+            throw new IllegalArgumentException("Invalid Hex String");
+        }
+        byte[] data = new byte[len / 2];
+        for (int i = 0; i < len; i += 2) {
+            data[i / 2] =
+                    (byte)
+                            ((Character.digit(hexString.charAt(i), 16) << 4)
+                                    + Character.digit(hexString.charAt(i + 1), 16));
+        }
+        return data;
+    }
+
+    public static IkePayload hexStringToIkePayload(
+            @IkePayload.PayloadType int payloadType, boolean isResp, String payloadHexString)
+            throws IkeException {
+        byte[] payloadBytes = hexStringToByteArray(payloadHexString);
+        // Returned Pair consists of the IkePayload and the following IkePayload's type.
+        Pair<IkePayload, Integer> pair =
+                IkePayloadFactory.getIkePayload(payloadType, isResp, ByteBuffer.wrap(payloadBytes));
+        return pair.first;
+    }
+}
diff --git a/tests/iketests/src/java/com/android/internal/net/utils/BigIntegerUtilsTest.java b/tests/iketests/src/java/com/android/ike/ikev2/utils/BigIntegerUtilsTest.java
similarity index 97%
rename from tests/iketests/src/java/com/android/internal/net/utils/BigIntegerUtilsTest.java
rename to tests/iketests/src/java/com/android/ike/ikev2/utils/BigIntegerUtilsTest.java
index 29bb313..e3d06ce 100644
--- a/tests/iketests/src/java/com/android/internal/net/utils/BigIntegerUtilsTest.java
+++ b/tests/iketests/src/java/com/android/ike/ikev2/utils/BigIntegerUtilsTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.net.utils;
+package com.android.ike.ikev2.utils;
 
 import static org.junit.Assert.assertArrayEquals;
 
diff --git a/tests/iketests/src/java/com/android/internal/net/TestUtils.java b/tests/iketests/src/java/com/android/internal/net/TestUtils.java
deleted file mode 100644
index 6dd5ce5..0000000
--- a/tests/iketests/src/java/com/android/internal/net/TestUtils.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net;
-
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.spy;
-
-import com.android.internal.net.utils.Log;
-
-import java.nio.ByteBuffer;
-
-/** TestUtils provides utility methods for parsing Hex String and constructing testing Logger. */
-public class TestUtils {
-    public static byte[] hexStringToByteArray(String hexString) {
-        int len = hexString.length();
-        if (len % 2 != 0) {
-            throw new IllegalArgumentException("Invalid Hex String");
-        }
-        byte[] data = new byte[len / 2];
-        for (int i = 0; i < len; i += 2) {
-            data[i / 2] =
-                    (byte)
-                            ((Character.digit(hexString.charAt(i), 16) << 4)
-                                    + Character.digit(hexString.charAt(i + 1), 16));
-        }
-        return data;
-    }
-
-    public static int hexStringToInt(String hexString) {
-        if (hexString.length() > 8) {
-            throw new IllegalArgumentException("Invalid hex string length for integer type");
-        }
-
-        for (int i = hexString.length(); i < 8; i++) {
-            hexString = "0" + hexString;
-        }
-
-        return ByteBuffer.wrap(hexStringToByteArray(hexString)).getInt();
-    }
-
-    public static String stringToHexString(String s) {
-        // two hex characters for each char in s
-        StringBuilder sb = new StringBuilder(s.length() * 2);
-        char[] chars = s.toCharArray();
-        for (char c : chars) {
-            sb.append(Integer.toHexString(c));
-        }
-        return sb.toString();
-    }
-
-    public static Log makeSpyLogThrowExceptionForWtf(String tag) {
-        Log spyLog = spy(new Log(tag, true /*logSensitive*/));
-
-        doAnswer(
-                (invocation) -> {
-                    throw new IllegalStateException((String) invocation.getArguments()[1]);
-                })
-                .when(spyLog)
-                .wtf(anyString(), anyString());
-
-        doAnswer(
-                (invocation) -> {
-                    throw (Throwable) invocation.getArguments()[2];
-                })
-                .when(spyLog)
-                .wtf(anyString(), anyString(), anyObject());
-
-        return spyLog;
-    }
-
-    public static Log makeSpyLogDoLogErrorForWtf(String tag) {
-        Log spyLog = spy(new Log(tag, true /*logSensitive*/));
-
-        doAnswer(
-                (invocation) -> {
-                    spyLog.e(
-                            "Mock logging WTF: " + invocation.getArguments()[0],
-                            (String) invocation.getArguments()[1]);
-                    return null;
-                })
-                .when(spyLog)
-                .wtf(anyString(), anyString());
-
-        doAnswer(
-                (invocation) -> {
-                    spyLog.e(
-                            "Mock logging WTF: " + invocation.getArguments()[0],
-                            (String) invocation.getArguments()[1],
-                            (Throwable) invocation.getArguments()[2]);
-                    return null;
-                })
-                .when(spyLog)
-                .wtf(anyString(), anyString(), anyObject());
-
-        return spyLog;
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaPrimeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapAkaPrimeTest.java
deleted file mode 100644
index 0872b67..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaPrimeTest.java
+++ /dev/null
@@ -1,382 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class EapAkaPrimeTest extends EapMethodEndToEndTest {
-    private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L;
-
-    private static final int SUB_ID = 1;
-    private static final String UNFORMATTED_IDENTITY = "123456789ABCDEF"; // IMSI
-
-    // EAP_IDENTITY = hex("test@android.net")
-    private static final byte[] EAP_IDENTITY =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-    private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = false;
-    private static final String PEER_NETWORK_NAME_1 = "foo:bar";
-    private static final String PEER_NETWORK_NAME_2 = "bar";
-
-    // hex("foo:bar:buzz")
-    private static final String SERVER_NETWORK_NAME = "666F6F3A6261723A62757A7A";
-
-    // TODO(b/142667016): replace with externally generated test values
-
-    // IK: 7320EE404E055EF2B5AB0F86E96C48BE
-    // CK: E9D1707652E13BF3E05975F601678E5C
-    // Server Network Name: 666F6F3A6261723A62757A7A
-    // SQN ^ AK: 35A9143ED9E1
-    // IK': 79DC30692F3D2303D148549E5D50D0AA
-    // CK': BBD0A7AD3F14757BA604C4CBE70F9090
-    // K_encr: 4c22c289bcf40367cf2bdb6a6e3fe56b
-    // K_aut: c64abd508ab628f842e9fb40a14fea769d2ccc67a8412794fe3b4c2556431e78
-    // K_re: 5454ccf7ecc227f25c6cd1023e09394fa5cedc14a2f155e9d96a70dc404b4dca
-    private static final String RAND_1 = "D6A296F030A305601B311D38A004505C";
-    private static final String RAND_2 = "000102030405060708090A0B0C0D0E0F";
-    private static final String AUTN = "35A9143ED9E100011795E785DAFAAD9B";
-    private static final String RES = "E5167A255FDCDE9248AF6B50ADA0D944";
-    private static final String AUTS = "0102030405060708090A0B0C0D0E";
-    private static final byte[] MSK =
-            hexStringToByteArray(
-                    "695788d8f33af56b5b2fea065a0e8656"
-                            + "7dc48120d6070d96056f9668614ec3e7"
-                            + "feb4933a3aaab3587980a624998c8b5e"
-                            + "a69d7295b824ef4a2201720be89d04df");
-    private static final byte[] EMSK =
-            hexStringToByteArray(
-                    "2db1f574d6e92cec294779defef5a7f0"
-                            + "49319cc75367102815d0244087f23660"
-                            + "0986b47a862c1aeeca418c84a2f9581b"
-                            + "0738fdefd229a5f7a4ca76709379bf00");
-
-    // IK: 7320EE404E055EF2B5AB0F86E96C48BE
-    // CK: E9D1707652E13BF3E05975F601678E5C
-    // Server Network Name: 666F6F3A6261723A62757A7A
-    // SQN ^ AK: 35A9143ED9E1
-    // IK': 6C45FB0B12FF8172223B6D0E599EAE20
-    // CK': A01C894696BEB759ABE0340F71A20D7B
-    // K_encr: c039213c78fcf78a34bef30219a77822
-    // K_aut: 95b014e569144eba71a387f91fb6b72e06781df12d61bfe88e5149477cd232aa
-    // K_re: 1000c2e2f01766a4d2581ac454e41fce1ee17bcccbc32dfad78815075d884c5e
-    private static final byte[] MSK_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "ad75a86586773134dcd9e78e3f75b282"
-                            + "7a42435cb1be7235be58cddc60a0ba19"
-                            + "dd5c30accfdb0db5ef065f46c3c25d7b"
-                            + "9f8703d9493a2dc6fb6563dbdc854658");
-    private static final byte[] EMSK_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "31a3f2bb0e3e831d991dc8666438297f"
-                            + "4a5bc157fc1e31537e5a4927206d7b4b"
-                            + "db830761eea3441d9b90da48aebb9734"
-                            + "d3cbdec96072230a64043f54932a8841");
-
-    // Base 64 of: [Length][RAND_1][Length][AUTN]
-    private static final String BASE64_CHALLENGE_1 =
-            "ENailvAwowVgGzEdOKAEUFwQNakUPtnhAAEXleeF2vqtmw==";
-
-    // Base 64 of: ['DB'][Length][RES][Length][IK][Length][CK]
-    private static final String BASE_64_RESPONSE_SUCCESS =
-            "2xDlFnolX9zekkiva1CtoNlEEHMg7kBOBV7ytasPhulsSL4Q6dFwdlLhO/PgWXX2AWeOXA==";
-
-    // Base 64 of: [Length][RAND_2][Length][AUTN]
-    private static final String BASE64_CHALLENGE_2 =
-            "EAABAgMEBQYHCAkKCwwNDg8QNakUPtnhAAEXleeF2vqtmw==";
-
-    // Base 64 of: ['DC'][Length][AUTS]
-    private static final String BASE_64_RESPONSE_SYNC_FAIL = "3A4BAgMEBQYHCAkKCwwNDg==";
-
-    private static final String REQUEST_MAC = "9089f89b2f99bb85f2f2b529779f98db";
-    private static final String RESPONSE_MAC = "48d7d6a80e1e2ff26a1e4148e0a2303e";
-    private static final String REQUEST_MAC_WITHOUT_IDENTITY_REQ =
-            "59f680ede020a3d0156eef56affb6997";
-    private static final String RESPONSE_MAC_WITHOUT_IDENTITY_REQ =
-            "e15322ff4abe51479c0fa92d00e343d7";
-
-    private static final byte[] EAP_AKA_PRIME_IDENTITY_REQUEST =
-            hexStringToByteArray(
-                    "01CD000C" // EAP-Request | ID | length in bytes
-                            + "32050000" // EAP-AKA' | Identity | 2B padding
-                            + "0D010000"); // AT_ANY_ID_REQ attribute
-    private static final byte[] EAP_AKA_PRIME_IDENTITY_RESPONSE =
-            hexStringToByteArray(
-                    "02CD001C" // EAP-Response | ID | length in bytes
-                            + "32050000" // EAP-AKA' | Identity | 2B padding
-                            + "0E05001036313233343536373839414243444546"); // AT_IDENTITY attribute
-
-    private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST =
-            hexStringToByteArray(
-                    "01CE0044" // EAP-Request | ID | length in bytes
-                            + "32010000" // EAP-AKA' | Challenge | 2B padding
-                            + "01050000" + RAND_1 // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "1704000C" + SERVER_NETWORK_NAME // AT_KDF_INPUT attribute
-                            + "18010001" // AT_KDF attribute
-                            + "0B050000" + REQUEST_MAC); // AT_MAC attribute
-    private static final byte[] EAP_AKA_PRIME_CHALLENGE_RESPONSE =
-            hexStringToByteArray(
-                    "02CE0030" // EAP-Response | ID | length in bytes
-                            + "32010000" // EAP-AKA' | Challenge | 2B padding
-                            + "03050080" + RES // AT_RES attribute
-                            + "0B050000" + RESPONSE_MAC); // AT_MAC attribute
-
-    private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "01CE0044" // EAP-Request | ID | length in bytes
-                            + "32010000" // EAP-AKA' | Challenge | 2B padding
-                            + "01050000" + RAND_1 // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "1704000C" + SERVER_NETWORK_NAME // AT_KDF_INPUT attribute
-                            + "18010001" // AT_KDF attribute
-                            + "0B050000" + REQUEST_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute
-    private static final byte[] EAP_AKA_PRIME_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST =
-            hexStringToByteArray(
-                    "02CE0030" // EAP-Response | ID | length in bytes
-                            + "32010000" // EAP-AKA' | Challenge | 2B padding
-                            + "03050080" + RES // AT_RES attribute
-                            + "0B050000" + RESPONSE_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute
-
-    private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST_SYNC_FAIL =
-            hexStringToByteArray(
-                    "01CE0044" // EAP-Request | ID | length in bytes
-                            + "32010000" // EAP-AKA' | Challenge | 2B padding
-                            + "01050000" + RAND_2 // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "1704000C" + SERVER_NETWORK_NAME // AT_KDF_INPUT attribute
-                            + "18010001" // AT_KDF attribute
-                            + "0B050000" + REQUEST_MAC); // AT_MAC attribute
-    private static final byte[] EAP_AKA_PRIME_SYNC_FAIL_RESPONSE =
-            hexStringToByteArray(
-                    "02CE0018" // EAP-Response | ID | length in bytes
-                            + "32040000" // EAP-AKA' | Synchronization-Failure | 2B padding
-                            + "0404" + AUTS);  // AT_AUTS attribute
-
-    private static final byte[] EAP_AKA_PRIME_AUTHENTICATION_REJECT =
-            hexStringToByteArray(
-                    "02CE0008" // EAP-Response | ID | length in bytes
-                            + "32020000"); // EAP-AKA' | Authentication-Reject | 2B padding
-
-    private static final byte[] EAP_RESPONSE_NAK_PACKET =
-            hexStringToByteArray("021000060332"); // NAK with EAP-AKA' listed
-
-    private TelephonyManager mMockTelephonyManager;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        setUp(ALLOW_MISMATCHED_NETWORK_NAMES, PEER_NETWORK_NAME_1);
-    }
-
-    private void setUp(boolean allowMismatchedNetworkNames, String peerNetworkName) {
-        mMockTelephonyManager = mock(TelephonyManager.class);
-
-        mEapSessionConfig =
-                new EapSessionConfig.Builder()
-                        .setEapIdentity(EAP_IDENTITY)
-                        .setEapAkaPrimeConfig(
-                                SUB_ID, APPTYPE_USIM, peerNetworkName, allowMismatchedNetworkNames)
-                        .build();
-        mEapAuthenticator =
-                new EapAuthenticator(
-                        mTestLooper.getLooper(),
-                        mMockCallback,
-                        new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom),
-                        (runnable) -> runnable.run(),
-                        AUTHENTICATOR_TIMEOUT_MILLIS);
-
-        when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
-                .thenReturn(mMockTelephonyManager);
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testEapAkaPrimeEndToEnd() {
-        verifyEapPrimeAkaIdentity();
-        verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaPrimeEndToEndWithoutIdentityRequest() {
-        verifyEapAkaPrimeChallengeWithoutIdentityReq();
-        verifyEapSuccess(MSK_WITHOUT_IDENTITY_REQ, EMSK_WITHOUT_IDENTITY_REQ);
-    }
-
-    @Test
-    public void testEapAkaPrimeWithEapNotifications() {
-        verifyEapNotification(1);
-        verifyEapPrimeAkaIdentity();
-
-        verifyEapNotification(2);
-        verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE);
-
-        verifyEapNotification(3);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaPrimeUnsupportedType() {
-        verifyUnsupportedType(EAP_REQUEST_SIM_START_PACKET, EAP_RESPONSE_NAK_PACKET);
-
-        verifyEapPrimeAkaIdentity();
-        verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaPrimeSynchronizationFailure() {
-        verifyEapPrimeAkaIdentity();
-        verifyEapAkaPrimeSynchronizationFailure();
-        verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaPrimeAuthenticationReject() {
-        verifyEapPrimeAkaIdentity();
-
-        // return null from TelephonyManager to simluate rejection of AUTN
-        verifyEapAkaPrimeChallenge(null, EAP_AKA_PRIME_AUTHENTICATION_REJECT);
-        verifyEapFailure();
-    }
-
-    @Test
-    public void testEapAkaPrimeMismatchedNetworkNamesNotAllowed() {
-        // use mismatched peer network name
-        setUp(false, PEER_NETWORK_NAME_2);
-        verifyEapPrimeAkaIdentity();
-        verifyEapAkaPrimeChallengeMismatchedNetworkNames();
-        verifyEapFailure();
-    }
-
-    @Test
-    public void testEapAkaPrimeMismatchedNetworkNamesAllowed() {
-        setUp(true, PEER_NETWORK_NAME_2);
-        verifyEapPrimeAkaIdentity();
-        verifyEapAkaPrimeChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_PRIME_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    private void verifyEapPrimeAkaIdentity() {
-        // EAP-AKA'/Identity request
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(UNFORMATTED_IDENTITY);
-
-        mEapAuthenticator.processEapMessage(EAP_AKA_PRIME_IDENTITY_REQUEST);
-        mTestLooper.dispatchAll();
-
-        // verify EAP-AKA'/Identity response
-        verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE));
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-        verify(mMockTelephonyManager).getSubscriberId();
-        verify(mMockCallback).onResponse(eq(EAP_AKA_PRIME_IDENTITY_RESPONSE));
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaPrimeChallenge(
-            String challengeBase64,
-            String responseBase64,
-            byte[] incomingEapPacket,
-            byte[] outgoingEapPacket) {
-        // EAP-AKA'/Challenge request
-        when(mMockTelephonyManager.getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        challengeBase64))
-                .thenReturn(responseBase64);
-
-        mEapAuthenticator.processEapMessage(incomingEapPacket);
-        mTestLooper.dispatchAll();
-
-        // verify EAP-AKA'/Challenge response
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        challengeBase64);
-        verify(mMockCallback).onResponse(eq(outgoingEapPacket));
-    }
-
-    private void verifyEapAkaPrimeChallenge(String responseBase64, byte[] outgoingPacket) {
-        verifyEapAkaPrimeChallenge(
-                BASE64_CHALLENGE_1,
-                responseBase64,
-                EAP_AKA_PRIME_CHALLENGE_REQUEST,
-                outgoingPacket);
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaPrimeChallengeWithoutIdentityReq() {
-        verifyEapAkaPrimeChallenge(
-                BASE64_CHALLENGE_1,
-                BASE_64_RESPONSE_SUCCESS,
-                EAP_AKA_PRIME_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ,
-                EAP_AKA_PRIME_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST);
-
-        // also need to verify interactions with Context and TelephonyManager
-        verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE));
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaPrimeSynchronizationFailure() {
-        verifyEapAkaPrimeChallenge(
-                BASE64_CHALLENGE_2,
-                BASE_64_RESPONSE_SYNC_FAIL,
-                EAP_AKA_PRIME_CHALLENGE_REQUEST_SYNC_FAIL,
-                EAP_AKA_PRIME_SYNC_FAIL_RESPONSE);
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaPrimeChallengeMismatchedNetworkNames() {
-        // EAP-AKA'/Challenge request
-        mEapAuthenticator.processEapMessage(EAP_AKA_PRIME_CHALLENGE_REQUEST);
-        mTestLooper.dispatchAll();
-        verify(mMockCallback).onResponse(eq(EAP_AKA_PRIME_AUTHENTICATION_REJECT));
-    }
-
-    @Override
-    protected void verifyEapSuccess(byte[] msk, byte[] emsk) {
-        super.verifyEapSuccess(msk, emsk);
-
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapAkaTest.java
deleted file mode 100644
index e982a85..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapAkaTest.java
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * This test verifies that EAP-AKA is functional for an end-to-end implementation
- */
-public class EapAkaTest extends EapMethodEndToEndTest {
-    private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L;
-
-    private static final int SUB_ID = 1;
-    private static final String UNFORMATTED_IDENTITY = "123456789ABCDEF"; // IMSI
-
-    // EAP_IDENTITY = hex("test@android.net")
-    private static final byte[] EAP_IDENTITY =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    // TODO(b/140797965): find valid AUTN/RAND values for the CTS test sim
-    // IK: 7320EE404E055EF2B5AB0F86E96C48BE
-    // CK: E9D1707652E13BF3E05975F601678E5C
-    // MK: 2AE8AD50432246E6ACED9AA0FC794A22CE9CE4BB
-    // K_encr: DB6F06910D5D19CC9DA5F2687F5C5737
-    // K_aut: B20A586592796E08E7408FB53356E9B1
-    private static final String RAND_1 = "D6A296F030A305601B311D38A004505C";
-    private static final String RAND_2 = "000102030405060708090A0B0C0D0E0F";
-    private static final String AUTN = "35A9143ED9E100011795E785DAFAAD9B";
-    private static final String RES = "E5167A255FDCDE9248AF6B50ADA0D944";
-    private static final String AUTS = "0102030405060708090A0B0C0D0E";
-    private static final byte[] MSK =
-            hexStringToByteArray(
-                    "EFC4FB9F54D99A3F4A04B756993CA813"
-                            + "E463CA0ADBF3CB2A296519ED4C600FF5"
-                            + "81898B1C425C20FE7471FC43A4BB3C00"
-                            + "DDF80A7083972B660BC7153CBF2C9AA1");
-    private static final byte[] EMSK =
-            hexStringToByteArray(
-                    "5C95F3E2476ED4D6588CE6DE2618D808"
-                            + "9ECA12A4636C8A1B0C678562CBFC31D3"
-                            + "94B578DE0A3686E17F96F14D5341FE75"
-                            + "2012944CA394E5288BA1B2C70CB65063");
-
-    // IK: 7320EE404E055EF2B5AB0F86E96C48BE
-    // CK: E9D1707652E13BF3E05975F601678E5C
-    // MK: 8183017CD8ADDB4617F4A2274DD5BCEA99354FB7
-    // K_encr: 891D5DB8CACAF657D68BE72371F927A2
-    // K_aut: E042A1CC5672358685EC012881EA02DE
-    private static final byte[] MSK_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "629DE03704E15EF1B8BADFF7FA5D84D5"
-                            + "8574B6A3A46F274796346A86AE3455AC"
-                            + "711E2D4D3F96EE71E664B1B947D7E9E7"
-                            + "D227CBB6199A68BD7D43E6E4863D08D6");
-    private static final byte[] EMSK_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "30A6638AE3AB5C5D29554D8256C3A287"
-                            + "FDF6255E4D726C0622DDF89609C16A8D"
-                            + "563768166A8111A083547DE4C8E280D6"
-                            + "113A608DE9227FC7C02679A1E04DB3CF");
-
-    // Base 64 of: [Length][RAND_1][Length][AUTN]
-    private static final String BASE64_CHALLENGE_1 =
-            "ENailvAwowVgGzEdOKAEUFwQNakUPtnhAAEXleeF2vqtmw==";
-
-    // Base 64 of: ['DB'][Length][RES][Length][IK][Length][CK]
-    private static final String BASE_64_RESPONSE_SUCCESS =
-            "2xDlFnolX9zekkiva1CtoNlEEHMg7kBOBV7ytasPhulsSL4Q6dFwdlLhO/PgWXX2AWeOXA==";
-
-    // Base 64 of: [Length][RAND_2][Length][AUTN]
-    private static final String BASE64_CHALLENGE_2 =
-            "EAABAgMEBQYHCAkKCwwNDg8QNakUPtnhAAEXleeF2vqtmw==";
-
-    // Base 64 of: ['DC'][Length][AUTS]
-    private static final String BASE_64_RESPONSE_SYNC_FAIL = "3A4BAgMEBQYHCAkKCwwNDg==";
-
-    private static final String REQUEST_MAC = "90C3554783D49A18F9EAA231F3C261EC";
-    private static final String RESPONSE_MAC = "D085987D3D15FA50A80D0CECFA2412EB";
-    private static final String REQUEST_MAC_WITHOUT_IDENTITY_REQ =
-            "6AD7E3F43ED99384E751F55AB8EA48B4";
-    private static final String RESPONSE_MAC_WITHOUT_IDENTITY_REQ =
-            "83E9F5B8B44BDE39B50538BF49864209";
-
-    private static final byte[] EAP_AKA_IDENTITY_REQUEST =
-            hexStringToByteArray(
-                    "01CD000C" // EAP-Request | ID | length in bytes
-                            + "17050000" // EAP-AKA | Identity | 2B padding
-                            + "0D010000"); // AT_ANY_ID_REQ attribute
-    private static final byte[] EAP_AKA_IDENTITY_RESPONSE =
-            hexStringToByteArray(
-                    "02CD001C" // EAP-Response | ID | length in bytes
-                            + "17050000" // EAP-AKA | Identity | 2B padding
-                            + "0E05001030313233343536373839414243444546"); // AT_IDENTITY attribute
-
-    private static final byte[] EAP_AKA_CHALLENGE_REQUEST =
-            hexStringToByteArray(
-                    "01CE0044" // EAP-Request | ID | length in bytes
-                            + "17010000" // EAP-AKA | Challenge | 2B padding
-                            + "01050000" + RAND_1 // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "0B050000" + REQUEST_MAC); // AT_MAC attribute
-    private static final byte[] EAP_AKA_CHALLENGE_RESPONSE =
-            hexStringToByteArray(
-                    "02CE0030" // EAP-Response | ID | length in bytes
-                            + "17010000" // EAP-AKA | Challenge | 2B padding
-                            + "03050080" + RES // AT_RES attribute
-                            + "0B050000" + RESPONSE_MAC); // AT_MAC attribute
-
-    private static final byte[] EAP_AKA_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "01CE0044" // EAP-Request | ID | length in bytes
-                            + "17010000" // EAP-AKA | Challenge | 2B padding
-                            + "01050000" + RAND_1 // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "0B050000" + REQUEST_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute
-    private static final byte[] EAP_AKA_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST =
-            hexStringToByteArray(
-                    "02CE0030" // EAP-Response | ID | length in bytes
-                            + "17010000" // EAP-AKA | Challenge | 2B padding
-                            + "03050080" + RES // AT_RES attribute
-                            + "0B050000" + RESPONSE_MAC_WITHOUT_IDENTITY_REQ); // AT_MAC attribute
-
-    private static final byte[] EAP_AKA_CHALLENGE_REQUEST_SYNC_FAIL =
-            hexStringToByteArray(
-                    "01CE0044" // EAP-Request | ID | length in bytes
-                            + "17010000" // EAP-AKA | Challenge | 2B padding
-                            + "01050000" + RAND_2 // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "0B050000" + REQUEST_MAC); // AT_MAC attribute
-    private static final byte[] EAP_AKA_SYNC_FAIL_RESPONSE =
-            hexStringToByteArray(
-                    "02CE0018" // EAP-Response | ID | length in bytes
-                            + "17040000" // EAP-AKA | Synchronization-Failure | 2B padding
-                            + "0404" + AUTS);  // AT_AUTS attribute
-
-    private static final byte[] EAP_AKA_AUTHENTICATION_REJECT =
-            hexStringToByteArray(
-                    "02CE0008" // EAP-Response | ID | length in bytes
-                            + "17020000"); // EAP-AKA | Authentication-Reject | 2B padding
-
-    private static final byte[] EAP_RESPONSE_NAK_PACKET =
-            hexStringToByteArray("021000060317"); // NAK with EAP-AKA listed
-
-    private TelephonyManager mMockTelephonyManager;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mMockTelephonyManager = mock(TelephonyManager.class);
-
-        mEapSessionConfig =
-                new EapSessionConfig.Builder()
-                        .setEapIdentity(EAP_IDENTITY)
-                        .setEapAkaConfig(SUB_ID, APPTYPE_USIM)
-                        .build();
-        mEapAuthenticator =
-                new EapAuthenticator(
-                        mTestLooper.getLooper(),
-                        mMockCallback,
-                        new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom),
-                        (runnable) -> runnable.run(),
-                        AUTHENTICATOR_TIMEOUT_MILLIS);
-
-        when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
-                .thenReturn(mMockTelephonyManager);
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testEapAkaEndToEnd() {
-        verifyEapAkaIdentity();
-        verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaEndToEndWithoutIdentityRequest() {
-        verifyEapAkaChallengeWithoutIdentityReq();
-        verifyEapSuccess(MSK_WITHOUT_IDENTITY_REQ, EMSK_WITHOUT_IDENTITY_REQ);
-    }
-
-    @Test
-    public void testEapAkaWithEapNotifications() {
-        verifyEapNotification(1);
-        verifyEapAkaIdentity();
-
-        verifyEapNotification(2);
-        verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE);
-
-        verifyEapNotification(3);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaUnsupportedType() {
-        verifyUnsupportedType(EAP_REQUEST_SIM_START_PACKET, EAP_RESPONSE_NAK_PACKET);
-
-        verifyEapAkaIdentity();
-        verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaSynchronizationFailure() {
-        verifyEapAkaIdentity();
-        verifyEapAkaSynchronizationFailure();
-        verifyEapAkaChallenge(BASE_64_RESPONSE_SUCCESS, EAP_AKA_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapAkaAuthenticationReject() {
-        verifyEapAkaIdentity();
-
-        // return null from TelephonyManager to simluate rejection of AUTN
-        verifyEapAkaChallenge(null, EAP_AKA_AUTHENTICATION_REJECT);
-        verifyEapFailure();
-    }
-
-    private void verifyEapAkaIdentity() {
-        // EAP-AKA/Identity request
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(UNFORMATTED_IDENTITY);
-
-        mEapAuthenticator.processEapMessage(EAP_AKA_IDENTITY_REQUEST);
-        mTestLooper.dispatchAll();
-
-        // verify EAP-AKA/Identity response
-        verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE));
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-        verify(mMockTelephonyManager).getSubscriberId();
-        verify(mMockCallback).onResponse(eq(EAP_AKA_IDENTITY_RESPONSE));
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaChallenge(
-            String challengeBase64,
-            String responseBase64,
-            byte[] incomingEapPacket,
-            byte[] outgoingEapPacket) {
-        // EAP-AKA/Challenge request
-        when(mMockTelephonyManager.getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        challengeBase64))
-                .thenReturn(responseBase64);
-
-        mEapAuthenticator.processEapMessage(incomingEapPacket);
-        mTestLooper.dispatchAll();
-
-        // verify EAP-AKA/Challenge response
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        challengeBase64);
-        verify(mMockCallback).onResponse(eq(outgoingEapPacket));
-    }
-
-    private void verifyEapAkaChallenge(String responseBase64, byte[] outgoingPacket) {
-        verifyEapAkaChallenge(
-                BASE64_CHALLENGE_1, responseBase64, EAP_AKA_CHALLENGE_REQUEST, outgoingPacket);
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaChallengeWithoutIdentityReq() {
-        verifyEapAkaChallenge(
-                BASE64_CHALLENGE_1,
-                BASE_64_RESPONSE_SUCCESS,
-                EAP_AKA_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ,
-                EAP_AKA_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQUEST);
-
-        // also need to verify interactions with Context and TelephonyManager
-        verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE));
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    private void verifyEapAkaSynchronizationFailure() {
-        verifyEapAkaChallenge(
-                BASE64_CHALLENGE_2,
-                BASE_64_RESPONSE_SYNC_FAIL,
-                EAP_AKA_CHALLENGE_REQUEST_SYNC_FAIL,
-                EAP_AKA_SYNC_FAIL_RESPONSE);
-        verifyNoMoreInteractions(
-                mMockContext, mMockTelephonyManager, mMockSecureRandom, mMockCallback);
-    }
-
-    @Override
-    protected void verifyEapSuccess(byte[] msk, byte[] emsk) {
-        super.verifyEapSuccess(msk, emsk);
-
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapAuthenticatorTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapAuthenticatorTest.java
deleted file mode 100644
index 4c868a0..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapAuthenticatorTest.java
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_FAILURE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_RESPONSE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_UNSUPPORTED_TYPE_PACKET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.os.Looper;
-import android.os.test.TestLooper;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.concurrent.TimeoutException;
-
-public class EapAuthenticatorTest {
-    private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L;
-    private static final long TEST_TIMEOUT_MILLIS = 2 * AUTHENTICATOR_TIMEOUT_MILLIS;
-    private static final byte[] MSK = hexStringToByteArray(
-            "00112233445566778899AABBCCDDEEFF"
-            + "00112233445566778899AABBCCDDEEFF"
-            + "00112233445566778899AABBCCDDEEFF"
-            + "00112233445566778899AABBCCDDEEFF");
-    private static final byte[] EMSK = hexStringToByteArray(
-            "FFEEDDCCBBAA99887766554433221100"
-            + "FFEEDDCCBBAA99887766554433221100"
-            + "FFEEDDCCBBAA99887766554433221100"
-            + "FFEEDDCCBBAA99887766554433221100");
-
-    private EapStateMachine mMockEapStateMachine;
-
-    private TestLooper mTestLooper;
-    private boolean mCallbackFired;
-
-    @Before
-    public void setUp() {
-        if (Looper.myLooper() == null) Looper.prepare();
-
-        mMockEapStateMachine = mock(EapStateMachine.class);
-
-        mTestLooper = new TestLooper();
-        mCallbackFired = false;
-    }
-
-    @Test
-    public void testProcessEapMessageResponse() {
-        EapCallback eapCallback = new EapCallback() {
-            @Override
-            public void onResponse(byte[] eapMsg) {
-                assertArrayEquals(EAP_SIM_RESPONSE_PACKET, eapMsg);
-                assertFalse("Callback has already been fired", mCallbackFired);
-                mCallbackFired = true;
-            }
-        };
-
-        EapResponse eapResponse = new EapResponse(EAP_SIM_RESPONSE_PACKET);
-        when(mMockEapStateMachine.process(eq(EAP_REQUEST_SIM_START_PACKET)))
-                .thenReturn(eapResponse);
-
-        getEapAuthenticatorWithCallback(eapCallback)
-                .processEapMessage(EAP_REQUEST_SIM_START_PACKET);
-        mTestLooper.dispatchAll();
-
-        assertTrue("Callback didn't fire", mCallbackFired);
-        verify(mMockEapStateMachine).process(eq(EAP_REQUEST_SIM_START_PACKET));
-        verifyNoMoreInteractions(mMockEapStateMachine);
-    }
-
-    @Test
-    public void testProcessEapMessageError() {
-        EapCallback eapCallback = new EapCallback() {
-            @Override
-            public void onError(Throwable cause) {
-                assertTrue(cause instanceof EapInvalidRequestException);
-                assertFalse("Callback has already been fired", mCallbackFired);
-                mCallbackFired = true;
-            }
-        };
-        Exception cause = new EapInvalidRequestException("Error");
-        EapError eapError = new EapError(cause);
-        when(mMockEapStateMachine.process(eq(REQUEST_UNSUPPORTED_TYPE_PACKET)))
-                .thenReturn(eapError);
-
-        getEapAuthenticatorWithCallback(eapCallback)
-                .processEapMessage(REQUEST_UNSUPPORTED_TYPE_PACKET);
-        mTestLooper.dispatchAll();
-
-        assertTrue("Callback didn't fire", mCallbackFired);
-        verify(mMockEapStateMachine).process(eq(REQUEST_UNSUPPORTED_TYPE_PACKET));
-        verifyNoMoreInteractions(mMockEapStateMachine);
-    }
-
-    @Test
-    public void testProcessEapMessageSuccess() {
-        EapCallback eapCallback = new EapCallback() {
-            @Override
-            public void onSuccess(byte[] msk, byte[] emsk) {
-                assertArrayEquals(MSK, msk);
-                assertArrayEquals(EMSK, emsk);
-                assertFalse("Callback has already been fired", mCallbackFired);
-                mCallbackFired = true;
-            }
-        };
-        EapSuccess eapSuccess = new EapSuccess(MSK, EMSK);
-        when(mMockEapStateMachine.process(eq(EAP_SUCCESS_PACKET)))
-                .thenReturn(eapSuccess);
-
-        getEapAuthenticatorWithCallback(eapCallback)
-                .processEapMessage(EAP_SUCCESS_PACKET);
-        mTestLooper.dispatchAll();
-
-        assertTrue("Callback didn't fire", mCallbackFired);
-        verify(mMockEapStateMachine).process(eq(EAP_SUCCESS_PACKET));
-        verifyNoMoreInteractions(mMockEapStateMachine);
-    }
-
-    @Test
-    public void testProcessEapMessageFailure() {
-        EapCallback eapCallback = new EapCallback() {
-            @Override
-            public void onFail() {
-                // nothing to check here
-                assertFalse("Callback has already been fired", mCallbackFired);
-                mCallbackFired = true;
-            }
-        };
-        when(mMockEapStateMachine.process(eq(EAP_FAILURE_PACKET)))
-                .thenReturn(new EapFailure());
-
-        getEapAuthenticatorWithCallback(eapCallback)
-                .processEapMessage(EAP_FAILURE_PACKET);
-        mTestLooper.dispatchAll();
-
-        assertTrue("Callback didn't fire", mCallbackFired);
-        verify(mMockEapStateMachine).process(eq(EAP_FAILURE_PACKET));
-        verifyNoMoreInteractions(mMockEapStateMachine);
-    }
-
-    @Test
-    public void testProcessEapMessageExceptionThrown() {
-        EapCallback eapCallback = new EapCallback() {
-            @Override
-            public void onError(Throwable cause) {
-                assertTrue(cause instanceof NullPointerException);
-                assertFalse("Callback has already been fired", mCallbackFired);
-                mCallbackFired = true;
-            }
-        };
-        when(mMockEapStateMachine.process(EAP_REQUEST_SIM_START_PACKET))
-                .thenThrow(new NullPointerException());
-
-        getEapAuthenticatorWithCallback(eapCallback)
-                .processEapMessage(EAP_REQUEST_SIM_START_PACKET);
-        mTestLooper.dispatchAll();
-
-        assertTrue("Callback didn't fire", mCallbackFired);
-        verify(mMockEapStateMachine).process(eq(EAP_REQUEST_SIM_START_PACKET));
-        verifyNoMoreInteractions(mMockEapStateMachine);
-    }
-
-    @Test
-    public void testProcessEapMessageStateMachineTimeout() {
-        EapCallback eapCallback = new EapCallback() {
-            @Override
-            public void onError(Throwable cause) {
-                assertTrue(cause instanceof TimeoutException);
-                assertFalse("Callback has already been fired", mCallbackFired);
-                mCallbackFired = true;
-            }
-        };
-        EapResponse eapResponse = new EapResponse(EAP_SIM_RESPONSE_PACKET);
-        when(mMockEapStateMachine.process(eq(EAP_REQUEST_SIM_START_PACKET)))
-                .then((invocation) -> {
-                    // move time forward to trigger the timeout
-                    mTestLooper.moveTimeForward(TEST_TIMEOUT_MILLIS);
-                    return eapResponse;
-                });
-
-        getEapAuthenticatorWithCallback(eapCallback)
-                .processEapMessage(EAP_REQUEST_SIM_START_PACKET);
-        mTestLooper.dispatchAll();
-
-        assertTrue("Callback didn't fire", mCallbackFired);
-        verify(mMockEapStateMachine).process(eq(EAP_REQUEST_SIM_START_PACKET));
-        verifyNoMoreInteractions(mMockEapStateMachine);
-    }
-
-    private EapAuthenticator getEapAuthenticatorWithCallback(EapCallback eapCallback) {
-        return new EapAuthenticator(
-                mTestLooper.getLooper(),
-                eapCallback,
-                mMockEapStateMachine,
-                (runnable) -> runnable.run(),
-                AUTHENTICATOR_TIMEOUT_MILLIS);
-    }
-
-    /**
-     * Default {@link IEapCallback} implementation that throws {@link UnsupportedOperationException}
-     * for all calls.
-     */
-    private abstract static class EapCallback implements IEapCallback {
-        @Override
-        public void onSuccess(byte[] msk, byte[] emsk) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void onFail() {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void onResponse(byte[] eapMsg) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public void onError(Throwable cause) {
-            throw new UnsupportedOperationException();
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapErrorTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapErrorTest.java
deleted file mode 100644
index ce49763..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapErrorTest.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static org.junit.Assert.assertEquals;
-
-import com.android.internal.net.eap.EapResult.EapError;
-
-import org.junit.Test;
-
-public class EapErrorTest {
-    private static final RuntimeException EXPECTED_EXCEPTION = new RuntimeException("expected");
-
-    @Test
-    public void testEapErrorConstructor() {
-        EapError eapError = new EapError(EXPECTED_EXCEPTION);
-        assertEquals(EXPECTED_EXCEPTION, eapError.cause);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapMethodEndToEndTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapMethodEndToEndTest.java
deleted file mode 100644
index 412a4cf..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapMethodEndToEndTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_FAILURE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.os.test.TestLooper;
-
-import org.junit.Before;
-
-import java.security.SecureRandom;
-
-public class EapMethodEndToEndTest {
-    protected Context mMockContext;
-    protected SecureRandom mMockSecureRandom;
-    protected IEapCallback mMockCallback;
-
-    protected TestLooper mTestLooper;
-    protected EapSessionConfig mEapSessionConfig;
-    protected EapAuthenticator mEapAuthenticator;
-
-    @Before
-    public void setUp() {
-        mMockContext = mock(Context.class);
-        mMockSecureRandom = mock(SecureRandom.class);
-        mMockCallback = mock(IEapCallback.class);
-
-        mTestLooper = new TestLooper();
-    }
-
-    protected void verifyUnsupportedType(byte[] invalidMessageType, byte[] nakResponse) {
-        mEapAuthenticator.processEapMessage(invalidMessageType);
-        mTestLooper.dispatchAll();
-
-        // verify EAP-Response/Nak returned
-        verify(mMockCallback).onResponse(eq(nakResponse));
-        verifyNoMoreInteractions(mMockCallback);
-    }
-
-    protected void verifyEapNotification(int callsToVerify) {
-        mEapAuthenticator.processEapMessage(EAP_REQUEST_NOTIFICATION_PACKET);
-        mTestLooper.dispatchAll();
-
-        verify(mMockCallback, times(callsToVerify))
-                .onResponse(eq(EAP_RESPONSE_NOTIFICATION_PACKET));
-        verifyNoMoreInteractions(mMockCallback);
-    }
-
-    protected void verifyEapSuccess(byte[] msk, byte[] emsk) {
-        // EAP-Success
-        mEapAuthenticator.processEapMessage(EAP_SUCCESS);
-        mTestLooper.dispatchAll();
-
-        // verify that onSuccess callback made
-        verify(mMockCallback).onSuccess(eq(msk), eq(emsk));
-        verifyNoMoreInteractions(mMockContext, mMockSecureRandom, mMockCallback);
-    }
-
-    protected void verifyEapFailure() {
-        mEapAuthenticator.processEapMessage(EAP_FAILURE_PACKET);
-        mTestLooper.dispatchAll();
-
-        verify(mMockCallback).onFail();
-        verifyNoMoreInteractions(mMockCallback);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapMsChapV2Test.java b/tests/iketests/src/java/com/android/internal/net/eap/EapMsChapV2Test.java
deleted file mode 100644
index 01264f9..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapMsChapV2Test.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_AKA_IDENTITY_PACKET;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import android.net.eap.EapSessionConfig;
-
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class EapMsChapV2Test extends EapMethodEndToEndTest {
-    private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L;
-
-    private static final String USERNAME = "User";
-    private static final String PASSWORD = "clientPass";
-
-    private static final byte[] PEER_CHALLENGE =
-            hexStringToByteArray("21402324255E262A28295F2B3A337C7E");
-    private static final byte[] MSK =
-            hexStringToByteArray(
-                    "D5F0E9521E3EA9589645E86051C822268B7CDC149B993A1BA118CB153F56DCCB");
-
-    // Server-Name = hex("authenticator@android.net")
-    private static final byte[] EAP_MSCHAP_V2_CHALLENGE_REQUEST =
-            hexStringToByteArray("01110033" // EAP-Request | ID | length in bytes
-                    + "1A0142" // EAP-MSCHAPv2 | Request | MSCHAPv2 ID
-                    + "002E10" // MS length | Value Size (0x10)
-                    + "5B5D7C7D7B3F2F3E3C2C602132262628" // Authenticator-Challenge
-                    + "61757468656E74696361746F7240616E64726F69642E6E6574"); // Server-Name
-    private static final byte[] EAP_MSCHAP_V2_CHALLENGE_RESPONSE =
-            hexStringToByteArray("0211003F" // EAP-Response | ID | length in bytes
-                    + "1A0242" // EAP-MSCHAPv2 | Response | MSCHAPv2 ID
-                    + "003A31" // MS length | Value Size (0x31)
-                    + "21402324255E262A28295F2B3A337C7E" // Peer-Challenge
-                    + "0000000000000000" // 8B (reserved)
-                    + "82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF" // NT-Response
-                    + "00" // Flags
-                    + "55736572"); // hex(USERNAME)
-    private static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST =
-            hexStringToByteArray("01120047" // EAP-Request | ID | length in bytes
-                    + "1A03420042" // EAP-MSCHAPv2 | Success | MSCHAPv2 ID | MS length
-                    + "533D" // hex("S=")
-                    + "3430374135353839313135464430443632303946"
-                            + "3531304645394330343536363933324344413536" // hex("<auth_string>")
-                    + "204D3D" // hex(" M=")
-                            + "7465737420416E64726F69642031323334"); // hex("test Android 1234")
-    private static final byte[] EAP_MSCHAP_V2_SUCCESS_RESPONSE =
-            hexStringToByteArray("02120006" // EAP-Response | ID | length in bytes
-                    + "1A03"); // EAP-MSCHAPv2 | Success
-    private static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST =
-            hexStringToByteArray("01130049" // EAP-Request | ID | length in bytes
-                    + "1A04420044" // EAP-MSCHAPv2 | Failure | MSCHAPv2 ID | MS length
-                    + "453D363437" // hex("E=647")
-                    + "20523D31" // hex(" R=1")
-                    + "20433D" // hex(" C=")
-                            + "30303031303230333034303530363037"
-                            + "30383039304130423043304430453046" // hex("<authenticator challenge>")
-                    + "20563D33" // hex(" V=3")
-                    + "204D3D" // hex(" M=")
-                    + "7465737420416E64726F69642031323334"); // hex("test Android 1234")
-    private static final byte[] EAP_MSCHAP_V2_FAILURE_RESPONSE =
-            hexStringToByteArray("02130006" // EAP-Response | ID | length in bytes
-                    + "1A04"); // EAP-MSCHAPv2 | Failure
-
-    private static final byte[] EAP_RESPONSE_NAK_PACKET = hexStringToByteArray("02100006031A");
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mEapSessionConfig =
-                new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
-        mEapAuthenticator =
-                new EapAuthenticator(
-                        mTestLooper.getLooper(),
-                        mMockCallback,
-                        new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom),
-                        (runnable) -> runnable.run(),
-                        AUTHENTICATOR_TIMEOUT_MILLIS);
-    }
-
-    @Test
-    public void testEapMsChapV2EndToEndSuccess() {
-        verifyEapMsChapV2Challenge();
-        verifyEapMsChapV2SuccessRequest();
-        verifyEapSuccess(MSK, new byte[0]);
-    }
-
-    @Test
-    public void testEapMsChapV2EndToEndFailure() {
-        verifyEapMsChapV2Challenge();
-        verifyEapMsChapV2FailureRequest();
-        verifyEapFailure();
-    }
-
-    @Test
-    public void testEapMsChapV2UnsupportedType() {
-        verifyUnsupportedType(EAP_REQUEST_AKA_IDENTITY_PACKET, EAP_RESPONSE_NAK_PACKET);
-
-        verifyEapMsChapV2Challenge();
-        verifyEapMsChapV2SuccessRequest();
-        verifyEapSuccess(MSK, new byte[0]);
-    }
-
-    @Test
-    public void verifyEapMsChapV2WithEapNotifications() {
-        verifyEapNotification(1);
-
-        verifyEapMsChapV2Challenge();
-        verifyEapNotification(2);
-
-        verifyEapMsChapV2SuccessRequest();
-        verifyEapNotification(3);
-
-        verifyEapSuccess(MSK, new byte[0]);
-    }
-
-    private void verifyEapMsChapV2Challenge() {
-        doAnswer(invocation -> {
-            byte[] dst = invocation.getArgument(0);
-            System.arraycopy(PEER_CHALLENGE, 0, dst, 0, PEER_CHALLENGE.length);
-            return null;
-        }).when(mMockSecureRandom).nextBytes(eq(new byte[PEER_CHALLENGE.length]));
-
-        mEapAuthenticator.processEapMessage(EAP_MSCHAP_V2_CHALLENGE_REQUEST);
-        mTestLooper.dispatchAll();
-
-        verify(mMockCallback).onResponse(eq(EAP_MSCHAP_V2_CHALLENGE_RESPONSE));
-        verify(mMockSecureRandom).nextBytes(any(byte[].class));
-        verifyNoMoreInteractions(mMockCallback);
-    }
-
-    private void verifyEapMsChapV2SuccessRequest() {
-        mEapAuthenticator.processEapMessage(EAP_MSCHAP_V2_SUCCESS_REQUEST);
-        mTestLooper.dispatchAll();
-
-        verify(mMockCallback).onResponse(eq(EAP_MSCHAP_V2_SUCCESS_RESPONSE));
-        verifyNoMoreInteractions(mMockCallback);
-    }
-
-    private void verifyEapMsChapV2FailureRequest() {
-        mEapAuthenticator.processEapMessage(EAP_MSCHAP_V2_FAILURE_REQUEST);
-        mTestLooper.dispatchAll();
-
-        verify(mMockCallback).onResponse(eq(EAP_MSCHAP_V2_FAILURE_RESPONSE));
-        verifyNoMoreInteractions(mMockCallback);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapResponseTest.java
deleted file mode 100644
index 0c6dd52..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapResponseTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.InvalidEapResponseException;
-import com.android.internal.net.eap.message.EapMessage;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class EapResponseTest {
-    private EapMessage mEapResponse;
-    private EapMessage mEapSuccess;
-
-    @Before
-    public void setUp() throws Exception {
-        mEapResponse = EapMessage.decode(EAP_RESPONSE_NAK_PACKET);
-        mEapSuccess = EapMessage.decode(EAP_SUCCESS_PACKET);
-    }
-
-    @Test
-    public void testGetEapResponse() {
-        EapResult eapResult = EapResponse.getEapResponse(mEapResponse);
-        assertTrue(eapResult instanceof EapResponse);
-
-        EapResponse eapResponse = (EapResponse) eapResult;
-        assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testGetEapResponseNullMessage() {
-        try {
-            EapResponse.getEapResponse(null);
-            fail("Expected IllegalArgumentException for null EapMessage");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testGetEapResponseNonRequestMessage() {
-        EapResult eapResult = EapResponse.getEapResponse(mEapSuccess);
-        assertTrue(eapResult instanceof EapError);
-
-        EapError eapError = (EapError) eapResult;
-        assertTrue(eapError.cause instanceof InvalidEapResponseException);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapSimTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapSimTest.java
deleted file mode 100644
index 8b11d278..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapSimTest.java
+++ /dev/null
@@ -1,298 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_AKA_IDENTITY_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.statemachine.EapStateMachine;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * This test verifies that EAP-SIM is functional for an end-to-end implementation
- */
-public class EapSimTest extends EapMethodEndToEndTest {
-    private static final long AUTHENTICATOR_TIMEOUT_MILLIS = 250L;
-
-    private static final byte[] NONCE = hexStringToByteArray("37f3ddd3954c4831a5ee08c574844398");
-    private static final String UNFORMATTED_IDENTITY = "123456789ABCDEF"; // IMSI
-
-    // EAP_IDENTITY = hex("test@android.net")
-    private static final byte[] EAP_IDENTITY =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    private static final int SUB_ID = 1;
-
-    // Base 64 of: RAND
-    private static final String BASE64_RAND_1 = "EAEjRWeJq83vESNFZ4mrze8=";
-    private static final String BASE64_RAND_2 = "EBEjRWeJq83vESNFZ4mrze8=";
-    private static final String BASE64_RAND_3 = "ECEjRWeJq83vESNFZ4mrze8=";
-
-    // BASE 64 of: "04" + SRES + "08" + KC
-    // SRES 1: 0ABCDEF0      KC 1: FEDCBA9876543210
-    // SRES 2: 1ABCDEF1      KC 2: FEDCBA9876543211
-    // SRES 3: 2ABCDEF2      KC 3: FEDCBA9876543212
-    private static final String BASE64_RESP_1 = "BAq83vAI/ty6mHZUMhA=";
-    private static final String BASE64_RESP_2 = "BBq83vEI/ty6mHZUMhE=";
-    private static final String BASE64_RESP_3 = "BCq83vII/ty6mHZUMhI=";
-
-    // MK: 202FC68A3335E8A939A33BC0A0EA8C435DC10060
-    // K_encr: F63E152461391FF655C2632E35D076ED
-    // K_aut: 48E001C8DBA37120FD0465153A56F712
-    private static final byte[] MSK =
-            hexStringToByteArray(
-                    "9B1E2B6892BC113F6B6D0B5789DD8ADD"
-                            + "B83BE2A84AA50FCAECD0003F92D8DA16"
-                            + "4BF983C923695C309F1D7D68DB6992B0"
-                            + "76EA8CE7129647A6F198F3A6AA8ADED9");
-    private static final byte[] EMSK = hexStringToByteArray(
-            "88210b6724400313539c740f417076b0"
-                    + "41da7e64658ec365bd2901a7cd7c2763"
-                    + "dad1a0508b92a42fdf85ac53c6f7e756"
-                    + "7f99b62bcaf467441b567f19b58d86ae");
-
-    // MK: ED275A588A4C1AEC15C55261DCCD851189E5C5FD
-    // K_encr: FED573CFA6FC81267C08E264F50A0BB9
-    // K_aut: 277B5D6A68FE5156A387996510AC5D61
-    private static final byte[] MSK_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "8023A49840433464DA1A4F2457FAB3D6"
-                            + "B1A3CA6E5E1DB212FA1AEA17F0A5C933"
-                            + "5541DE7448FE448AC3F09DC25BBAE1EE"
-                            + "17DCE3D32099519CC75840F0E3FB612B");
-    private static final byte[] EMSK_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "F7E213F0E8F14A21C87F9B5DFADA9A75"
-                            + "A8EAF4AD718BF8C3ED6557BDB60E4671"
-                            + "E6AE109448B2F32F9B984667AE6C2B3F"
-                            + "2FDFE67F97AF4D4727A2EA37F06B7785");
-
-    private static final byte[] EAP_SIM_START_REQUEST = hexStringToByteArray(
-            "01850014120a0000" // EAP header
-                    + "0f02000200010000" // AT_VERSION_LIST attribute
-                    + "0d010000"); // AT_ANY_ID_REQ attribute
-    private static final byte[] EAP_SIM_START_RESPONSE = hexStringToByteArray(
-            "02850034120a0000" // EAP header
-                    + "0705000037f3ddd3954c4831a5ee08c574844398" // AT_NONCE_MT attribute
-                    + "10010001" // AT_SELECTED_VERSION attribute
-                    + "0e05001031313233343536373839414243444546"); // AT_IDENTITY attribute
-    private static final byte[] EAP_SIM_CHALLENGE_REQUEST = hexStringToByteArray(
-            "01860050120b0000" // EAP header
-                    + "010d0000" // AT_RAND attribute
-                    + "0123456789abcdef1123456789abcdef" // Rand 1
-                    + "1123456789abcdef1123456789abcdef" // Rand 2
-                    + "2123456789abcdef1123456789abcdef" // Rand 3
-                    + "0b050000e4675b17fa7ba4d93db48d1af9ecbb01"); // AT_MAC attribute
-    private static final byte[] EAP_SIM_CHALLENGE_RESPONSE =
-            hexStringToByteArray(
-                    "0286001c120b0000" // EAP header
-                            + "0b050000e5df9cb1d935ea5f54d449a038bed061"); // AT_MAC attribute
-
-    private static final byte[] EAP_SIM_START_REQUEST_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "01850010" // EAP-Request | ID | length in bytes
-                            + "120a0000" // EAP-SIM | Start| 2B padding
-                            + "0f02000200010000"); // AT_VERSION_LIST attribute
-    private static final byte[] EAP_SIM_START_RESPONSE_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "02850020" // EAP-Response | ID | length in bytes
-                            + "120a0000" // EAP-SIM | Start | 2B padding
-                            + "0705000037f3ddd3954c4831a5ee08c574844398" // AT_NONCE_MT attribute
-                            + "10010001"); // AT_SELECTED_VERSION attribute
-    private static final byte[] EAP_SIM_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "01860050" // EAP-Request | ID | length in bytes
-                            + "120b0000" // EAP-SIM | Challenge | 2B padding
-                            + "010d0000" // AT_RAND attribute
-                            + "0123456789abcdef1123456789abcdef" // Rand 1
-                            + "1123456789abcdef1123456789abcdef" // Rand 2
-                            + "2123456789abcdef1123456789abcdef" // Rand 3
-                            + "0b050000F2F8C10FCA946AAFE9555E2BD3693DF6"); // AT_MAC attribute
-    private static final byte[] EAP_SIM_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQ =
-            hexStringToByteArray(
-                    "0286001c" // EAP-Response | ID | length in bytes
-                            + "120b0000" // EAP-SIM | Challenge | 2B padding
-                            + "0b050000DAC3C1B7D9DBFBC923464A94F186E410"); // AT_MAC attribute
-
-    private TelephonyManager mMockTelephonyManager;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mMockTelephonyManager = mock(TelephonyManager.class);
-
-        mEapSessionConfig =
-                new EapSessionConfig.Builder()
-                        .setEapIdentity(EAP_IDENTITY)
-                        .setEapSimConfig(SUB_ID, APPTYPE_USIM)
-                        .build();
-        mEapAuthenticator =
-                new EapAuthenticator(
-                        mTestLooper.getLooper(),
-                        mMockCallback,
-                        new EapStateMachine(mMockContext, mEapSessionConfig, mMockSecureRandom),
-                        (runnable) -> runnable.run(),
-                        AUTHENTICATOR_TIMEOUT_MILLIS);
-    }
-
-    @Test
-    public void testEapSimEndToEnd() {
-        verifyEapSimStart(EAP_SIM_START_REQUEST, EAP_SIM_START_RESPONSE, true);
-        verifyEapSimChallenge(EAP_SIM_CHALLENGE_REQUEST, EAP_SIM_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void testEapSimEndToEndWithoutIdentityRequest() {
-        verifyEapSimStart(
-                EAP_SIM_START_REQUEST_WITHOUT_IDENTITY_REQ,
-                EAP_SIM_START_RESPONSE_WITHOUT_IDENTITY_REQ,
-                false);
-        verifyEapSimChallenge(
-                EAP_SIM_CHALLENGE_REQUEST_WITHOUT_IDENTITY_REQ,
-                EAP_SIM_CHALLENGE_RESPONSE_WITHOUT_IDENTITY_REQ);
-        verifyEapSuccess(MSK_WITHOUT_IDENTITY_REQ, EMSK_WITHOUT_IDENTITY_REQ);
-    }
-
-    @Test
-    public void testEapSimUnsupportedType() {
-        verifyUnsupportedType(EAP_REQUEST_AKA_IDENTITY_PACKET, EAP_RESPONSE_NAK_PACKET);
-
-        verifyEapSimStart(EAP_SIM_START_REQUEST, EAP_SIM_START_RESPONSE, true);
-        verifyEapSimChallenge(EAP_SIM_CHALLENGE_REQUEST, EAP_SIM_CHALLENGE_RESPONSE);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    @Test
-    public void verifyEapSimWithEapNotifications() {
-        verifyEapNotification(1);
-        verifyEapSimStart(EAP_SIM_START_REQUEST, EAP_SIM_START_RESPONSE, true);
-
-        verifyEapNotification(2);
-        verifyEapSimChallenge(EAP_SIM_CHALLENGE_REQUEST, EAP_SIM_CHALLENGE_RESPONSE);
-        verifyEapNotification(3);
-        verifyEapSuccess(MSK, EMSK);
-    }
-
-    private void verifyEapSimStart(
-            byte[] incomingEapPacket, byte[] outgoingEapPacket, boolean expectIdentityRequest) {
-        // EAP-SIM/Start request
-        when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE))
-                .thenReturn(mMockTelephonyManager);
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(UNFORMATTED_IDENTITY);
-        doAnswer(invocation -> {
-            byte[] dst = invocation.getArgument(0);
-            System.arraycopy(NONCE, 0, dst, 0, NONCE.length);
-            return null;
-        }).when(mMockSecureRandom).nextBytes(eq(new byte[NONCE.length]));
-
-        mEapAuthenticator.processEapMessage(incomingEapPacket);
-        mTestLooper.dispatchAll();
-        verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE));
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-
-        if (expectIdentityRequest) {
-            verify(mMockTelephonyManager).getSubscriberId();
-        }
-
-        verify(mMockSecureRandom).nextBytes(any(byte[].class));
-
-        // verify EAP-SIM/Start response
-        verify(mMockCallback).onResponse(eq(outgoingEapPacket));
-        verifyNoMoreInteractions(
-                mMockContext,
-                mMockTelephonyManager,
-                mMockSecureRandom,
-                mMockCallback);
-    }
-
-    private void verifyEapSimChallenge(byte[] incomingEapPacket, byte[] outgoingEapPacket) {
-        // EAP-SIM/Challenge request
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE64_RAND_1))
-                .thenReturn(BASE64_RESP_1);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE64_RAND_2))
-                .thenReturn(BASE64_RESP_2);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE64_RAND_3))
-                .thenReturn(BASE64_RESP_3);
-
-        mEapAuthenticator.processEapMessage(incomingEapPacket);
-        mTestLooper.dispatchAll();
-
-        // verify EAP-SIM/Challenge response
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        eq(TelephonyManager.APPTYPE_USIM),
-                        eq(TelephonyManager.AUTHTYPE_EAP_SIM),
-                        eq(BASE64_RAND_1));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        eq(TelephonyManager.APPTYPE_USIM),
-                        eq(TelephonyManager.AUTHTYPE_EAP_SIM),
-                        eq(BASE64_RAND_2));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        eq(TelephonyManager.APPTYPE_USIM),
-                        eq(TelephonyManager.AUTHTYPE_EAP_SIM),
-                        eq(BASE64_RAND_3));
-        verify(mMockCallback).onResponse(eq(outgoingEapPacket));
-        verifyNoMoreInteractions(
-                mMockContext,
-                mMockTelephonyManager,
-                mMockSecureRandom,
-                mMockCallback);
-    }
-
-    @Override
-    protected void verifyEapSuccess(byte[] msk, byte[] emsk) {
-        super.verifyEapSuccess(msk, emsk);
-
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapSuccessTest.java b/tests/iketests/src/java/com/android/internal/net/eap/EapSuccessTest.java
deleted file mode 100644
index d741054..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapSuccessTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.EapResult.EapSuccess;
-
-import org.junit.Test;
-
-public class EapSuccessTest {
-    public static final byte[] MSK = new byte[] {(byte) 1, (byte) 2, (byte) 3};
-    public static final byte[] EMSK = new byte[] {(byte) 4, (byte) 5, (byte) 6};
-
-    @Test
-    public void testEapSuccessConstructor() {
-        EapSuccess eapSuccess = new EapSuccess(MSK, EMSK);
-        assertArrayEquals(MSK, eapSuccess.msk);
-        assertArrayEquals(EMSK, eapSuccess.emsk);
-    }
-
-    @Test
-    public void testEapSuccessConstructorNullMsk() {
-        try {
-            new EapSuccess(null, EMSK);
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testEapSuccessConstructorNullEmsk() {
-        try {
-            new EapSuccess(MSK, null);
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/EapTestUtils.java b/tests/iketests/src/java/com/android/internal/net/eap/EapTestUtils.java
deleted file mode 100644
index de058d1..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/EapTestUtils.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import android.net.eap.EapSessionConfig;
-
-import java.util.HashMap;
-
-/**
- * EapTestUtils is a util class for providing test-values of EAP-related objects.
- */
-public class EapTestUtils {
-    /**
-     * Creates and returns a dummy EapSessionConfig instance.
-     *
-     * @return a new, empty EapSessionConfig instance
-     */
-    public static EapSessionConfig getDummyEapSessionConfig() {
-        return new EapSessionConfig(new HashMap<>(), new byte[0]);
-    }
-
-    /**
-     * Creates and returns a dummy EapSessionConfig instance with the given EAP-Identity.
-     *
-     * @param eapIdentity byte-array representing the EAP-Identity of the client
-     * @return a new, empty EapSessionConfig instance with the given EAP-Identity
-     */
-    public static EapSessionConfig getDummyEapSessionConfig(byte[] eapIdentity) {
-        return new EapSessionConfig(new HashMap<>(), eapIdentity);
-    }
-
-    /**
-     * Creates and returns a dummy EapSessionConfig instance with EAP-SIM configured.
-     *
-     * @return a new EapSessionConfig with EAP-SIM configs set
-     */
-    public static EapSessionConfig getDummyEapSimSessionConfig() {
-        return new EapSessionConfig.Builder().setEapSimConfig(0, APPTYPE_USIM).build();
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/crypto/Fips186_2PrfTest.java b/tests/iketests/src/java/com/android/internal/net/eap/crypto/Fips186_2PrfTest.java
deleted file mode 100644
index 978f070..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/crypto/Fips186_2PrfTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.crypto;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.TestUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * The test vectors in this file come directly from NIST:
- *
- * <p>The original link to the test vectors was here:
- * http://csrc.nist.gov/publications/fips/fips186-2/fips186-2-change1.pdf
- *
- * <p>But has since been removed. A cached copy was found here:
- * https://web.archive.org/web/20041031202951/http://www.csrc.nist.gov/CryptoToolkit/dss/Examples-
- * 1024bit.pdf
- */
-public final class Fips186_2PrfTest {
-    private static final String SEED = "bd029bbe7f51960bcf9edb2b61f06f0feb5a38b6";
-    private static final String EXPECTED_RESULT =
-            "2070b3223dba372fde1c0ffc7b2e3b498b2606143c6c18bacb0f6c55babb13788e20d737a3275116";
-
-    private Fips186_2Prf mFipsPrf;
-
-    @Before
-    public void setUp() {
-        mFipsPrf = new Fips186_2Prf();
-    }
-
-    @Test
-    public void testFips186_2Prf_Invalid_Seed() throws Exception {
-        try {
-            mFipsPrf.getRandom(new byte[0], 40);
-            fail("Expected exception for invalid length seed");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testFips186_2Prf() throws Exception {
-        byte[] seed = TestUtils.hexStringToByteArray(SEED);
-        byte[] actual = mFipsPrf.getRandom(seed, 40);
-
-        assertArrayEquals(TestUtils.hexStringToByteArray(EXPECTED_RESULT), actual);
-    }
-
-    // TODO: (b/136177143) Add more test vectors
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSignerTest.java b/tests/iketests/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSignerTest.java
deleted file mode 100644
index 355c1db..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/crypto/HmacSha256ByteSignerTest.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.crypto;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-
-import static org.junit.Assert.assertArrayEquals;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * HmacSha256ByteSignerTest tests that {@link HmacSha256ByteSigner} correctly signs data using the
- * HMAC-SHA-256 algorithm.
- *
- * <p>These test vectors are defined in RFC 4231#4.
- *
- * @see <a href="https://tools.ietf.org/html/rfc4231#section-4">Test Vectors</a>
- */
-public class HmacSha256ByteSignerTest {
-    private static final String[] KEYS = {
-        "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b",
-        "4a656665",
-        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
-        "0102030405060708090a0b0c0d0e0f10111213141516171819",
-        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaa",
-        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
-                + "aaaaaa"
-    };
-    private static final String[] DATA = {
-        "4869205468657265",
-        "7768617420646f2079612077616e7420666f72206e6f7468696e673f",
-        "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
-                + "dddddddddddddddddddddddddddddddddddd",
-        "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd"
-                + "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd",
-        "54657374205573696e67204c6172676572205468616e20426c6f636b2d53697a"
-                + "65204b6579202d2048617368204b6579204669727374",
-        "5468697320697320612074657374207573696e672061206c6172676572207468"
-                + "616e20626c6f636b2d73697a65206b657920616e642061206c61726765722074"
-                + "68616e20626c6f636b2d73697a6520646174612e20546865206b6579206e6565"
-                + "647320746f20626520686173686564206265666f7265206265696e6720757365"
-                + "642062792074686520484d414320616c676f726974686d2e"
-    };
-    private static final String[] MACS = {
-        "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7",
-        "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843",
-        "773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe",
-        "82558a389a443c0ea4cc819899f2083a85f0faa3e578f8077a2e3ff46729665b",
-        "60e431591ee0b67f0d8a26aacbf5b77f8e0bc6213728c5140546040f0ee37f54",
-        "9b09ffa71b942fcb27635fbcd5b0e944bfdc63644f0713938a7f51535c3a35e2"
-    };
-
-    private HmacSha256ByteSigner mMacByteSigner;
-
-    @Before
-    public void setUp() {
-        mMacByteSigner = HmacSha256ByteSigner.getInstance();
-    }
-
-    @Test
-    public void testSignBytes() {
-        for (int i = 0; i < KEYS.length; i++) {
-            byte[] key = hexStringToByteArray(KEYS[i]);
-            byte[] data = hexStringToByteArray(DATA[i]);
-
-            byte[] expected = hexStringToByteArray(MACS[i]);
-
-            assertArrayEquals(expected, mMacByteSigner.signBytes(key, data));
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/crypto/ParityBitUtilTest.java b/tests/iketests/src/java/com/android/internal/net/eap/crypto/ParityBitUtilTest.java
deleted file mode 100644
index 7ba024e..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/crypto/ParityBitUtilTest.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.crypto;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-/**
- * Inputs taken from RFC 2759 Section 9.3.
- *
- * @see <a href="https://tools.ietf.org/html/rfc2759#section-9.3">RFC 2759 Section 9.3, Examples of
- *     DES Key Generation</a>
- */
-public class ParityBitUtilTest {
-    private static final byte[] INPUT_BYTES = {(byte) 0xFC, (byte) 0x0E, (byte) 0x7E, (byte) 0x37};
-    private static final byte[] OUTPUT_BYTES = {(byte) 0xFD, (byte) 0x0E, (byte) 0x7F, (byte) 0x37};
-
-    private static final String[] RAW_KEYS = {"FC156AF7EDCD6C", "0EDDE3337D427F"};
-    private static final long[] RAW_KEY_LONGS = {0xFC156AF7EDCD6CL, 0xEDDE3337D427FL};
-    private static final String[] PARITY_CORRECTED_KEYS = {"FD0B5B5E7F6E34D9", "0E6E796737EA08FE"};
-
-    @Test
-    public void testGetByteWithParityBit() {
-        for (int i = 0; i < INPUT_BYTES.length; i++) {
-            assertEquals(OUTPUT_BYTES[i], ParityBitUtil.getByteWithParityBit(INPUT_BYTES[i]));
-        }
-    }
-
-    @Test
-    public void testByteArrayToLong() {
-        for (int i = 0; i < RAW_KEYS.length; i++) {
-            byte[] rawKey = hexStringToByteArray(RAW_KEYS[i]);
-
-            assertEquals(RAW_KEY_LONGS[i], ParityBitUtil.byteArrayToLong(rawKey));
-        }
-    }
-
-    @Test
-    public void testAddParityBits() {
-        for (int i = 0; i < RAW_KEYS.length; i++) {
-            byte[] rawKey = hexStringToByteArray(RAW_KEYS[i]);
-            byte[] parityCorrectedKey = hexStringToByteArray(PARITY_CORRECTED_KEYS[i]);
-
-            assertArrayEquals(parityCorrectedKey, ParityBitUtil.addParityBits(rawKey));
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/EapDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/EapDataTest.java
deleted file mode 100644
index 9d4cc7c..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/EapDataTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
-
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class EapDataTest {
-    private static final byte[] EXPECTED_EAP_DATA_BYTES = new byte[] {
-            EAP_TYPE_SIM,
-            (byte) 1,
-            (byte) 2,
-            (byte) 3
-    };
-    private static final byte[] EAP_TYPE_DATA = new byte[] {(byte) 1, (byte) 2, (byte) 3};
-    private static final int UNSUPPORTED_EAP_TYPE = -1;
-
-    @Test
-    public void testEapDataConstructor() {
-        new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-    }
-
-    @Test
-    public void testEapDataConstructorNullEapData() {
-        try {
-            new EapData(EAP_TYPE_SIM, null);
-            fail("IllegalArgumentException expected for null eapTypeData");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testEapDataConstructorUnsupportedType() {
-        try {
-            new EapData(UNSUPPORTED_EAP_TYPE, EAP_TYPE_DATA);
-            fail("Expected IllegalArgumentException");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testGetLength() {
-        EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-        assertEquals(EAP_TYPE_DATA.length + 1, eapData.getLength());
-    }
-
-    @Test
-    public void testEquals() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-        EapData eapDataCopy = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-        assertEquals(eapData, eapDataCopy);
-
-        EapData eapDataDifferent = new EapData(EAP_TYPE_SIM, new byte[0]);
-        assertNotEquals(eapData, eapDataDifferent);
-    }
-
-    @Test
-    public void testHashCode() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-        EapData eapDataCopy = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-        assertNotEquals(0, eapData.hashCode());
-        assertEquals(eapData.hashCode(), eapDataCopy.hashCode());
-    }
-
-    @Test
-    public void testEncodeToByteBuffer() {
-        EapData eapData = new EapData(EAP_TYPE_SIM, EAP_TYPE_DATA);
-
-        ByteBuffer b = ByteBuffer.allocate(eapData.getLength());
-        eapData.encodeToByteBuffer(b);
-        assertArrayEquals(EXPECTED_EAP_DATA_BYTES, b.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/EapMessageTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/EapMessageTest.java
deleted file mode 100644
index 813a30f..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/EapMessageTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_NAK;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_RESPONSE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_TYPE_DATA;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INCOMPLETE_HEADER_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_CODE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.LONG_SUCCESS_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_MISSING_TYPE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_UNSUPPORTED_TYPE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SHORT_PACKET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidPacketLengthException;
-import com.android.internal.net.eap.exceptions.InvalidEapCodeException;
-import com.android.internal.net.eap.exceptions.UnsupportedEapTypeException;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class EapMessageTest {
-    @Test
-    public void testConstructorRequestWithoutType() throws Exception {
-        try {
-            new EapMessage(EAP_CODE_REQUEST, ID_INT, null);
-            fail("Expected EapInvalidPacketLengthException for an EAP-Request without Type value");
-        } catch (EapInvalidPacketLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        EapMessage result = EapMessage.decode(EAP_SUCCESS_PACKET);
-        assertEquals(EAP_CODE_SUCCESS, result.eapCode);
-        assertEquals(ID_INT, result.eapIdentifier);
-        assertEquals(EAP_SUCCESS_PACKET.length, result.eapLength);
-        assertNull(result.eapData);
-
-        EapData expectedEapData = new EapData(EAP_TYPE_SIM,
-                hexStringToByteArray(EAP_REQUEST_SIM_TYPE_DATA));
-        result = EapMessage.decode(EAP_REQUEST_SIM_START_PACKET);
-        assertEquals(EAP_CODE_REQUEST, result.eapCode);
-        assertEquals(ID_INT, result.eapIdentifier);
-        assertEquals(EAP_REQUEST_SIM_START_PACKET.length, result.eapLength);
-        assertEquals(expectedEapData, result.eapData);
-    }
-
-    @Test
-    public void testDecodeInvalidCode() throws Exception {
-        try {
-            EapMessage.decode(INVALID_CODE_PACKET);
-            fail("Expected InvalidEapCodeException");
-        } catch (InvalidEapCodeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeIncompleteHeader() throws Exception {
-        try {
-            EapMessage.decode(INCOMPLETE_HEADER_PACKET);
-            fail("Expected EapInvalidPacketLengthException");
-        } catch (EapInvalidPacketLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeShortPacket() throws Exception {
-        try {
-            EapMessage.decode(SHORT_PACKET);
-            fail("Expected EapInvalidPacketLengthException");
-        } catch (EapInvalidPacketLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeSuccessIncorrectLength() throws Exception {
-        try {
-            EapMessage.decode(LONG_SUCCESS_PACKET);
-            fail("Expected EapInvalidPacketLengthException");
-        } catch (EapInvalidPacketLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeMissingTypeData() throws Exception {
-        try {
-            EapMessage.decode(REQUEST_MISSING_TYPE_PACKET);
-            fail("Expected EapInvalidPacketLengthException");
-        } catch (EapInvalidPacketLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeUnsupportedEapType() throws Exception {
-        try {
-            EapMessage.decode(REQUEST_UNSUPPORTED_TYPE_PACKET);
-            fail("Expected UnsupportedEapDataTypeException");
-        } catch (UnsupportedEapTypeException expected) {
-            assertEquals(ID_INT, expected.eapIdentifier);
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        EapMessage eapMessage = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-        byte[] actualPacket = eapMessage.encode();
-        assertArrayEquals(EAP_SUCCESS_PACKET, actualPacket);
-
-        EapData nakData = new EapData(EAP_NAK, new byte[] {EAP_TYPE_SIM});
-        eapMessage = new EapMessage(EAP_CODE_RESPONSE, ID_INT, nakData);
-        actualPacket = eapMessage.encode();
-        assertArrayEquals(EAP_RESPONSE_NAK_PACKET, actualPacket);
-    }
-
-    @Test
-    public void testEncodeDecode() throws Exception {
-        EapMessage eapMessage = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-        EapMessage result = EapMessage.decode(eapMessage.encode());
-
-        assertEquals(eapMessage.eapCode, result.eapCode);
-        assertEquals(eapMessage.eapIdentifier, result.eapIdentifier);
-        assertEquals(eapMessage.eapLength, result.eapLength);
-        assertEquals(eapMessage.eapData, result.eapData);
-    }
-
-    @Test
-    public void testDecodeEncode() throws Exception {
-        byte[] result = EapMessage.decode(EAP_REQUEST_SIM_START_PACKET).encode();
-        assertArrayEquals(EAP_REQUEST_SIM_START_PACKET, result);
-    }
-
-    @Test
-    public void testGetNakResponse() {
-        EapResult nakResponse = EapMessage.getNakResponse(ID_INT, Arrays.asList(EAP_TYPE_SIM));
-
-        assertTrue(nakResponse instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) nakResponse;
-        assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testGetNotificationResponse() {
-        EapResult notificationResponse = EapMessage.getNotificationResponse(ID_INT);
-
-        assertTrue(notificationResponse instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) notificationResponse;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/EapTestMessageDefinitions.java b/tests/iketests/src/java/com/android/internal/net/eap/message/EapTestMessageDefinitions.java
deleted file mode 100644
index 2051758..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/EapTestMessageDefinitions.java
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_VERSION_LIST_DATA;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY_STRING;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT_STRING;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES;
-
-/**
- * EapTestMessageDefinitions provides byte[] encodings of commonly used EAP Messages.
- *
- * @see <a href="https://tools.ietf.org/html/rfc3748#section-4">RFC 3748, Extensible Authentication
- * Protocol (EAP)</a>
- */
-public class EapTestMessageDefinitions {
-    public static final String ID = "10";
-    public static final int ID_INT = Integer.parseInt(ID, 16 /* radix */);
-
-    // EAP-AKA Identity request
-    public static final String EAP_REQUEST_TYPE_DATA = "0500000D010000";
-    public static final byte[] EAP_AKA_IDENTITY_REQUEST =
-            hexStringToByteArray(EAP_REQUEST_TYPE_DATA);
-
-    // EAP-AKA/Identity request with no attributes
-    public static final byte[] EAP_REQUEST_AKA = hexStringToByteArray("01" + ID + "000817050000");
-    public static final byte[] EAP_REQUEST_AKA_IDENTITY_PACKET =
-            hexStringToByteArray("01" + ID + "000A17" + EAP_REQUEST_TYPE_DATA);
-    public static final byte[] EAP_REQUEST_IDENTITY_PACKET =
-            hexStringToByteArray("01" + ID + "000501");
-
-    // EAP-Identity: hex for ASCII in "test@android.net"
-    public static final String EAP_IDENTITY_STRING = "7465737440616E64726F69642E6E6574";
-    public static final byte[] EAP_IDENTITY = hexStringToByteArray(EAP_IDENTITY_STRING);
-    public static final byte[] EAP_RESPONSE_IDENTITY_PACKET =
-            hexStringToByteArray("02" + ID + "001501" + EAP_IDENTITY_STRING);
-    public static final byte[] EAP_RESPONSE_IDENTITY_DEFAULT_PACKET =
-            hexStringToByteArray("02" + ID + "000501");
-    public static final byte[] EAP_REQUEST_NOTIFICATION_PACKET =
-            hexStringToByteArray("01" + ID + "000802AABBCC");
-    public static final byte[] EAP_SUCCESS_PACKET = hexStringToByteArray("03" + ID + "0004");
-    public static final byte[] EAP_FAILURE_PACKET = hexStringToByteArray("04" + ID + "0004");
-    public static final byte[] EAP_SIM_CLIENT_ERROR_RESPONSE =
-            hexStringToByteArray("02" + ID + "000C120E000016010001");
-    public static final byte[] EAP_SIM_CLIENT_ERROR_INSUFFICIENT_CHALLENGES =
-            hexStringToByteArray("02" + ID + "000C120E000016010002");
-    public static final byte[] EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS =
-            hexStringToByteArray("02" + ID + "000C120E000016010000");
-    public static final byte[] EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS =
-            hexStringToByteArray("02" + ID + "000C170E000016010000");
-
-    // EAP-SIM response containing SELECTED_VERSION (1) and IDENTITY attributes
-    public static final byte[] EAP_SIM_RESPONSE_PACKET = hexStringToByteArray(
-            "02" + ID + "0024120A0000100100010E060011" + IDENTITY_STRING + "000000");
-    public static final byte[] EAP_SIM_RESPONSE_WITHOUT_IDENTITY =
-            hexStringToByteArray("02" + ID + "0020120A000007050000" + NONCE_MT_STRING + "10010001");
-    public static final byte[] EAP_SIM_NOTIFICATION_RESPONSE = hexStringToByteArray(
-            "02" + ID + "0008120C0000");
-    public static final byte[] EAP_AKA_NOTIFICATION_RESPONSE =
-            hexStringToByteArray("02" + ID + "0008170C0000");
-
-    // Body of EapData is the list of supported methods
-    public static final byte[] EAP_RESPONSE_NAK_PACKET =
-            hexStringToByteArray("02" + ID + "00060312");
-    public static final byte[] EAP_RESPONSE_NOTIFICATION_PACKET =
-            hexStringToByteArray("02" + ID + "000502");
-    public static final byte[] EAP_REQUEST_MD5_CHALLENGE =
-            hexStringToByteArray("01" + ID + "000504");
-    public static final byte[] EAP_REQUEST_NAK_PACKET =
-            hexStringToByteArray("01" + ID + "000503");
-    public static final String EAP_REQUEST_SIM_TYPE_DATA = "0A00000F02000200010000";
-    public static final byte[] EAP_REQUEST_SIM_START_PACKET =
-            hexStringToByteArray("01" + ID + "001012" + EAP_REQUEST_SIM_TYPE_DATA);
-
-    public static final byte[] REQUEST_UNSUPPORTED_TYPE_PACKET =
-            hexStringToByteArray("01" + ID + "0005FF");
-    public static final byte[] REQUEST_MISSING_TYPE_PACKET =
-            hexStringToByteArray("01" + ID + "0004");
-    public static final byte[] LONG_SUCCESS_PACKET = hexStringToByteArray("03" + ID + "000500");
-    public static final byte[] SHORT_PACKET = hexStringToByteArray("01" + ID + "0005");
-    public static final byte[] INCOMPLETE_HEADER_PACKET = hexStringToByteArray("03" + ID);
-    public static final byte[] INVALID_CODE_PACKET = hexStringToByteArray("F0" + ID + "0004");
-
-    // Attributes
-    public static final String SKIPPABLE_DATA = "112233445566";
-    public static final byte[] SKIPPABLE_DATA_BYTES = hexStringToByteArray(SKIPPABLE_DATA);
-    public static final byte[] SKIPPABLE_INVALID_ATTRIBUTE =
-            hexStringToByteArray("FF02" + SKIPPABLE_DATA);
-    public static final byte[] NON_SKIPPABLE_INVALID_ATTRIBUTE =
-            hexStringToByteArray("7F010000");
-
-    // Type-Data
-    public static final byte[] EAP_SIM_START_SUBTYPE =
-            hexStringToByteArray("0A00000F02" + AT_VERSION_LIST_DATA + "0A010000");
-    public static final byte[] INVALID_SUBTYPE = hexStringToByteArray("FF");
-    public static final byte[] TYPE_DATA_INVALID_AT_RAND =
-            hexStringToByteArray("0A000001050000" + RAND_1);
-    public static final byte[] SHORT_TYPE_DATA = hexStringToByteArray("0A");
-    public static final byte[] TYPE_DATA_INVALID_ATTRIBUTE =
-            hexStringToByteArray("0A00007F01");
-    public static final byte[] EAP_SIM_START_DUPLICATE_ATTRIBUTES =
-            hexStringToByteArray("0A00000F02" + "0A010000" + "0A010000");
-
-    // RAND Challenge Results
-    public static final String SRES_1 = "11223344";
-    public static final byte[] SRES_1_BYTES = hexStringToByteArray(SRES_1);
-    public static final String SRES_2 = "44332211";
-    public static final byte[] SRES_2_BYTES = hexStringToByteArray(SRES_2);
-    public static final byte[] SRES_BYTES = hexStringToByteArray(SRES_1 + SRES_2);
-    public static final String KC_1 = "0102030405060708";
-    public static final byte[] KC_1_BYTES = hexStringToByteArray(KC_1);
-    public static final String KC_2 = "0807060504030201";
-    public static final byte[] KC_2_BYTES = hexStringToByteArray(KC_2);
-    public static final byte[] VALID_CHALLENGE_RESPONSE =
-            hexStringToByteArray("04" + SRES_1 + "08" + KC_1);
-    public static final byte[] CHALLENGE_RESPONSE_INVALID_SRES = hexStringToByteArray("03");
-    public static final byte[] CHALLENGE_RESPONSE_INVALID_KC =
-            hexStringToByteArray("04" + SRES_1 + "04");
-
-    public static final String IMSI = "123456789012345";
-    public static final String EAP_SIM_IDENTITY = "1" + IMSI;
-    public static final byte[] EAP_SIM_IDENTITY_BYTES = hexStringToByteArray(EAP_SIM_IDENTITY);
-
-    // ASCII hex for "0" + IMSI (EAP-AKA identity format)
-    public static final String EAP_AKA_IDENTITY_BYTES = "30313233343536373839303132333435";
-
-    // Master Key generation
-    public static final String MK_STRING = "0123456789ABCDEF0123456789ABCDEF01234567";
-    public static final byte[] MK = hexStringToByteArray(MK_STRING);
-    public static final String K_ENCR_STRING = "000102030405060708090A0B0C0D0E0F";
-    public static final byte[] K_ENCR = hexStringToByteArray(K_ENCR_STRING);
-    public static final String K_AUT_STRING = "0F0E0D0C0B0A09080706050403020100";
-    public static final byte[] K_AUT = hexStringToByteArray(K_AUT_STRING);
-    public static final String MSK_STRING =
-            "00112233445566778899AABBCCDDEEFF"
-            + "00112233445566778899AABBCCDDEEFF"
-            + "00112233445566778899AABBCCDDEEFF"
-            + "00112233445566778899AABBCCDDEEFF";
-    public static final byte[] MSK = hexStringToByteArray(MSK_STRING);
-    public static final String EMSK_STRING =
-            "FFEEDDCCBBAA99887766554433221100"
-            + "FFEEDDCCBBAA99887766554433221100"
-            + "FFEEDDCCBBAA99887766554433221100"
-            + "FFEEDDCCBBAA99887766554433221100";
-    public static final byte[] EMSK = hexStringToByteArray(EMSK_STRING);
-
-    // MAC computation
-    public static final String ORIGINAL_MAC_STRING = "112233445566778899AABBCCDDEEFF11";
-    public static final byte[] ORIGINAL_MAC = hexStringToByteArray(ORIGINAL_MAC_STRING);
-    public static final String COMPUTED_MAC_STRING = "FFEEDDCCBBAA998877665544332211FF";
-    public static final byte[] COMPUTED_MAC = hexStringToByteArray(COMPUTED_MAC_STRING);
-    public static final String EAP_SIM_CHALLENGE_REQUEST_STRING =
-            "01" + ID + "0040" // EAP-Request | ID | length in bytes
-            + "120b0000" // EAP-SIM | Challenge | 2B padding
-            + "01090000" + RAND_1 + RAND_2 // EAP-SIM AT_RAND attribute
-            + "0B05000000000000000000000000000000000000"; // AT_MAC attribute with no MAC
-    public static final byte[] MAC_INPUT =
-            hexStringToByteArray(EAP_SIM_CHALLENGE_REQUEST_STRING + NONCE_MT_STRING);
-
-    // Response Message with MAC
-    public static final String EAP_SIM_CHALLENGE_RESPONSE_EMPTY_MAC =
-            "02" + ID + "001C" // EAP-Response | ID | length in bytes
-            + "120b0000" // EAP-SIM | Challenge | 2B padding
-            + "0B05000000000000000000000000000000000000"; // AT_MAC attribute with no MAC
-    public static final byte[] EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT =
-            hexStringToByteArray(EAP_SIM_CHALLENGE_RESPONSE_EMPTY_MAC + SRES_1 + SRES_2);
-    public static final byte[] EAP_SIM_CHALLENGE_RESPONSE_WITH_MAC = hexStringToByteArray(
-            "02" + ID + "001C" // EAP-Response | ID | length in bytes
-            + "120b0000" // EAP-SIM | Challenge | 2B padding
-            + "0B050000" + COMPUTED_MAC_STRING); // AT_MAC attribute
-    public static final byte[] EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC = hexStringToByteArray(
-            "01" + ID + "0020" // EAP-Request | ID | length in bytes
-                    + "120C0000" // EAP-SIM | Notification | 2B padding
-                    + "0C010000" // AT_NOTIFICATION attribute
-                    + "0B05000000000000000000000000000000000000"); // empty AT_MAC attribute
-    public static final byte[] EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC = hexStringToByteArray(
-            "02" + ID + "001C" // EAP-Response | ID | length in bytes
-                    + "120C0000" // EAP-SIM | Notification | 2B padding
-                    + "0B05000000000000000000000000000000000000"); // empty AT_MAC attribute
-    public static final byte[] EAP_SIM_NOTIFICATION_RESPONSE_WITH_MAC = hexStringToByteArray(
-            "02" + ID + "001C" // EAP-Response | ID | length in bytes
-            + "120C0000" // EAP-SIM | Notification | 2B padding
-            + "0B050000" + COMPUTED_MAC_STRING); // AT_MAC attribute
-
-    public static final byte[] EAP_AKA_IDENTITY_RESPONSE =
-            hexStringToByteArray("02" + ID + "001C" // EAP-Response | ID | length in bytes
-                    + "17050000" // EAP-AKA | Identity | 2B padding
-                    + "0E050010" + EAP_AKA_IDENTITY_BYTES); // AT_IDENTITY ("0" + IMSI)
-
-    // Base64 of: FF0111
-    public static final String EAP_AKA_UICC_RESP_INVALID_TAG = "/wER";
-
-    // Base64 of: DC0E112233445566778899AABBCCDDEE
-    public static final String EAP_AKA_UICC_RESP_SYNCHRONIZE_BASE_64 = "3A4RIjNEVWZ3iJmqu8zd7g==";
-
-    public static final byte[] EAP_AKA_SYNCHRONIZATION_FAILURE =
-            hexStringToByteArray("02" + ID + "0018" // EAP-Response | ID | length in bytes
-                    + "17040000" // EAP-SIM | Synchronization-Failure | 2B padding
-                    + "0404112233445566778899AABBCCDDEE"); // AT_AUTS attribute
-
-    public static final String IK = "00112233445566778899AABBCCDDEEFF";
-    public static final byte[] IK_BYTES = hexStringToByteArray(IK);
-    public static final String CK = "FFEEDDCCBBAA99887766554433221100";
-    public static final byte[] CK_BYTES = hexStringToByteArray(CK);
-
-    // Base-64 of: 'DB05' + RES_BYTES + '10' + IK + '10' + CK
-    // 'DB0511223344551000112233445566778899AABBCCDDEEFF10FFEEDDCCBBAA99887766554433221100'
-    public static final String EAP_AKA_UICC_RESP_SUCCESS_BASE_64 =
-            "2wURIjNEVRAAESIzRFVmd4iZqrvM3e7/EP/u3cy7qpmId2ZVRDMiEQA=";
-
-    public static final byte[] EAP_AKA_AUTHENTICATION_REJECT =
-            hexStringToByteArray("02" + ID + "000817020000");
-    public static final String EAP_AKA_CHALLENGE_RESPONSE_MAC = "C70366512D9C5EBA8E3484509A25DCE4";
-    public static final byte[] EAP_AKA_CHALLENGE_RESPONSE_MAC_BYTES =
-            hexStringToByteArray(EAP_AKA_CHALLENGE_RESPONSE_MAC);
-    public static final byte[] EAP_AKA_CHALLENGE_RESPONSE_TYPE_DATA =
-            hexStringToByteArray(
-                    "01000003030028" + RES + "0000000B050000" + EAP_AKA_CHALLENGE_RESPONSE_MAC);
-    public static final byte[] EAP_AKA_CHALLENGE_RESPONSE =
-            hexStringToByteArray(
-                    "02100028" // EAP-Response | ID | length in bytes
-                            + "17010000" // EAP-AKA | Challenge | 2B padding
-                            + "03030028" + RES + "000000" // AT_RES attribute
-                            + "0B050000" + EAP_AKA_CHALLENGE_RESPONSE_MAC); // AT_MAC attribute
-
-    public static final byte[] EAP_SUCCESS = hexStringToByteArray("03860004");
-
-    public static final byte[] EAP_REQUEST_MSCHAP_V2 =
-            hexStringToByteArray("01" + ID + "00061A01");
-
-    // MSCHAPv2 Test vectors taken from RFC 2759#9.2 and RFC 3079#3.5.3
-    public static final String MSCHAP_V2_USERNAME = "User";
-    public static final String MSCHAP_V2_USERNAME_HEX = "55736572";
-    public static final byte[] MSCHAP_V2_USERNAME_ASCII_BYTES =
-            hexStringToByteArray(MSCHAP_V2_USERNAME_HEX);
-    public static final String MSCHAP_V2_PASSWORD = "clientPass";
-    public static final byte[] MSCHAP_V2_PASSWORD_UTF_BYTES =
-            hexStringToByteArray("63006C00690065006E0074005000610073007300");
-    public static final String MSCHAP_V2_AUTHENTICATOR_CHALLENGE_STRING =
-            "5B5D7C7D7B3F2F3E3C2C602132262628";
-    public static final byte[] MSCHAP_V2_AUTHENTICATOR_CHALLENGE =
-            hexStringToByteArray(MSCHAP_V2_AUTHENTICATOR_CHALLENGE_STRING);
-    public static final String MSCHAP_V2_PEER_CHALLENGE_STRING = "21402324255E262A28295F2B3A337C7E";
-    public static final byte[] MSCHAP_V2_PEER_CHALLENGE =
-            hexStringToByteArray(MSCHAP_V2_PEER_CHALLENGE_STRING);
-    public static final byte[] MSCHAP_V2_CHALLENGE = hexStringToByteArray("D02E4386BCE91226");
-    public static final byte[] MSCHAP_V2_PASSWORD_HASH =
-            hexStringToByteArray("44EBBA8D5312B8D611474411F56989AE");
-    public static final byte[] MSCHAP_V2_PASSWORD_HASH_HASH =
-            hexStringToByteArray("41C00C584BD2D91C4017A2A12FA59F3F");
-    public static final String MSCHAP_V2_NT_RESPONSE_STRING =
-            "82309ECD8D708B5EA08FAA3981CD83544233114A3D85D6DF";
-    public static final byte[] MSCHAP_V2_NT_RESPONSE =
-            hexStringToByteArray(MSCHAP_V2_NT_RESPONSE_STRING);
-    public static final byte[] MSCHAP_V2_AUTHENTICATOR_RESPONSE =
-            hexStringToByteArray("407A5589115FD0D6209F510FE9C04566932CDA56");
-    public static final byte[] MSCHAP_V2_MASTER_KEY =
-            hexStringToByteArray("FDECE3717A8C838CB388E527AE3CDD31");
-
-    // generated based on RFC 3079#3.5.3 params
-    public static final String SEND_KEY = "D5F0E9521E3EA9589645E86051C82226";
-    public static final byte[] MSCHAP_V2_SEND_START_KEY = hexStringToByteArray(SEND_KEY);
-
-    // This value is labeled 'send key' in RFC 3079#3.5.3. However, it's used as 'receive key' here,
-    // because send and receive keys are swapped for peers relative to authenticators.
-    public static final String RECEIVE_KEY = "8B7CDC149B993A1BA118CB153F56DCCB";
-    public static final byte[] MSCHAP_V2_RECEIVE_START_KEY = hexStringToByteArray(RECEIVE_KEY);
-
-    // MSK: MSCHAP_V2_SEND_START_KEY + MSCHAP_V2_RECEIVE_START_KEY
-    public static final byte[] MSCHAP_V2_MSK = hexStringToByteArray(SEND_KEY + RECEIVE_KEY);
-
-    public static final String MSCHAP_V2_ID = "42";
-    public static final int MSCHAP_V2_ID_INT = Integer.parseInt(MSCHAP_V2_ID, 16 /* radix */);
-    public static final byte[] EAP_MSCHAP_V2_CHALLENGE_RESPONSE =
-            hexStringToByteArray("02" + ID + "003F" // EAP-Response | ID | length in bytes
-                    + "1A02" + MSCHAP_V2_ID // EAP-MSCHAPv2 | Response | MSCHAPv2 ID
-                    + "003A31" // MS length | Value Size (0x31)
-                    + MSCHAP_V2_PEER_CHALLENGE_STRING
-                    + "0000000000000000" // 8B (reserved)
-                    + MSCHAP_V2_NT_RESPONSE_STRING
-                    + "00" // Flags (always 0)
-                    + MSCHAP_V2_USERNAME_HEX);
-
-    public static final byte[] EAP_MSCHAP_V2_SUCCESS_RESPONSE =
-            hexStringToByteArray("02" + ID + "0006" // EAP-Response | ID | length in bytes
-                    + "1A03"); // EAP-MSCHAPv2 | Success
-
-    public static final byte[] INVALID_AUTHENTICATOR_RESPONSE = new byte[20];
-
-    public static final byte[] EAP_MSCHAP_V2_FAILURE_RESPONSE =
-            hexStringToByteArray("02" + ID + "0006" // EAP-Response | ID | length in bytes
-                    + "1A04"); // EAP-MSCHAPv2 | Failure
-
-    public static final byte[] EAP_AKA_PRIME_REQUEST =
-            hexStringToByteArray("01" + ID + "000832050000");
-    public static final byte[] EAP_AKA_PRIME_CLIENT_ERROR_UNABLE_TO_PROCESS =
-            hexStringToByteArray("02" + ID + "000C320E000016010000");
-    public static final String EAP_AKA_PRIME_IDENTITY = "36313233343536373839303132333435";
-    public static final byte[] EAP_AKA_PRIME_IDENTITY_BYTES =
-            hexStringToByteArray(EAP_AKA_PRIME_IDENTITY);
-    public static final byte[] EAP_AKA_PRIME_IDENTITY_RESPONSE =
-            hexStringToByteArray(
-                    "02" + ID + "001C" // EAP-Response | ID | length in bytes
-                            + "32050000" // EAP-AKA' | Identity | 2B padding
-                            + "0E050010" + EAP_AKA_PRIME_IDENTITY); // AT_IDENTITY ("6" + IMSI)
-    public static final byte[] EAP_AKA_PRIME_AUTHENTICATION_REJECT =
-            hexStringToByteArray(
-                    "02" + ID + "0008" // EAP-Response | ID | length in bytes
-                            + "32020000"); // EAP-AKA' | Authentication Reject | 2B padding
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeRequestTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeRequestTest.java
deleted file mode 100644
index 45a8673..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeRequestTest.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_LONG_MS_LENGTH;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_SHORT_CHALLENGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_SHORT_MS_LENGTH;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_REQUEST_WRONG_OP_CODE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_CHALLENGE_REQUEST;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SERVER_NAME_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_CHALLENGE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.BufferUnderflowException;
-
-public class EapMsChapV2ChallengeRequestTest {
-    private static final String TAG = EapMsChapV2ChallengeRequestTest.class.getSimpleName();
-
-    private EapMsChapV2TypeDataDecoder mTypeDataDecoder;
-
-    @Before
-    public void setUp() {
-        mTypeDataDecoder = new EapMsChapV2TypeDataDecoder();
-    }
-
-    @Test
-    public void testDecodeChallengeRequest() {
-        DecodeResult<EapMsChapV2ChallengeRequest> result =
-                mTypeDataDecoder.decodeChallengeRequest(TAG, EAP_MSCHAP_V2_CHALLENGE_REQUEST);
-        assertTrue(result.isSuccessfulDecode());
-        EapMsChapV2ChallengeRequest challengeRequest = result.eapTypeData;
-
-        assertEquals(EAP_MSCHAP_V2_CHALLENGE, challengeRequest.opCode);
-        assertEquals(ID_INT, challengeRequest.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_CHALLENGE_REQUEST.length, challengeRequest.msLength);
-        assertArrayEquals(CHALLENGE_BYTES, challengeRequest.challenge);
-        assertArrayEquals(SERVER_NAME_BYTES, challengeRequest.name);
-    }
-
-    @Test
-    public void testDecodeChallengeRequestWrongOpCode() {
-        DecodeResult<EapMsChapV2ChallengeRequest> result =
-                mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_WRONG_OP_CODE);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeChallengeRequestShortChallenge() {
-        DecodeResult<EapMsChapV2ChallengeRequest> result =
-                mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_SHORT_CHALLENGE);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeChallengeRequestShortMsLength() {
-        DecodeResult<EapMsChapV2ChallengeRequest> result =
-                mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_SHORT_MS_LENGTH);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeChallengeRequestLongMsLength() {
-        DecodeResult<EapMsChapV2ChallengeRequest> result =
-                mTypeDataDecoder.decodeChallengeRequest(TAG, CHALLENGE_REQUEST_LONG_MS_LENGTH);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof BufferUnderflowException);
-    }
-
-    @Test
-    public void testEncodeChallengeRequestFails() throws Exception {
-        EapMsChapV2ChallengeRequest challengeRequest =
-                new EapMsChapV2ChallengeRequest(
-                        ID_INT,
-                        EAP_MSCHAP_V2_CHALLENGE_REQUEST.length,
-                        CHALLENGE_BYTES,
-                        SERVER_NAME_BYTES);
-        try {
-            challengeRequest.encode();
-            fail("Expected UnsupportedOperationException for encoding a Challenge Request");
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeResponseTest.java
deleted file mode 100644
index 3e243a9..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2ChallengeResponseTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_CHALLENGE_RESPONSE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.NT_RESPONSE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PEER_CHALLENGE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PEER_NAME_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SHORT_CHALLENGE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SHORT_NT_RESPONSE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_RESPONSE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeResponse;
-
-import org.junit.Test;
-
-public class EapMsChapV2ChallengeResponseTest {
-    private static final int FLAGS = 0;
-    private static final int INVALID_FLAGS = 0xFF;
-
-    @Test
-    public void testConstructor() throws Exception {
-        EapMsChapV2ChallengeResponse challengeResponse =
-                new EapMsChapV2ChallengeResponse(
-                        ID_INT, PEER_CHALLENGE_BYTES, NT_RESPONSE_BYTES, FLAGS, PEER_NAME_BYTES);
-        assertEquals(EAP_MSCHAP_V2_RESPONSE, challengeResponse.opCode);
-        assertEquals(ID_INT, challengeResponse.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_CHALLENGE_RESPONSE.length, challengeResponse.msLength);
-        assertArrayEquals(PEER_CHALLENGE_BYTES, challengeResponse.peerChallenge);
-        assertArrayEquals(NT_RESPONSE_BYTES, challengeResponse.ntResponse);
-        assertEquals(FLAGS, challengeResponse.flags);
-        assertArrayEquals(PEER_NAME_BYTES, challengeResponse.name);
-    }
-
-    @Test
-    public void testConstructorInvalidChallenge() {
-        try {
-            EapMsChapV2ChallengeResponse challengeResponse =
-                    new EapMsChapV2ChallengeResponse(
-                            ID_INT,
-                            SHORT_CHALLENGE_BYTES,
-                            NT_RESPONSE_BYTES,
-                            FLAGS,
-                            PEER_NAME_BYTES);
-            fail("Expected EapMsChapV2ParsingException for invalid Peer Challenge length");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testConstructorInvalidNtResponse() {
-        try {
-            EapMsChapV2ChallengeResponse challengeResponse =
-                    new EapMsChapV2ChallengeResponse(
-                            ID_INT,
-                            PEER_CHALLENGE_BYTES,
-                            SHORT_NT_RESPONSE,
-                            FLAGS,
-                            PEER_NAME_BYTES);
-            fail("Expected EapMsChapV2ParsingException for invalid NT-Response length");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testConstructorInvalidFlags() {
-        try {
-            EapMsChapV2ChallengeResponse challengeResponse =
-                    new EapMsChapV2ChallengeResponse(
-                            ID_INT,
-                            PEER_CHALLENGE_BYTES,
-                            NT_RESPONSE_BYTES,
-                            INVALID_FLAGS,
-                            PEER_NAME_BYTES);
-            fail("Expected EapMsChapV2ParsingException for non-zero Flags value");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        EapMsChapV2ChallengeResponse challengeResponse =
-                new EapMsChapV2ChallengeResponse(
-                        ID_INT, PEER_CHALLENGE_BYTES, NT_RESPONSE_BYTES, FLAGS, PEER_NAME_BYTES);
-        byte[] encodedChallengeResponse = challengeResponse.encode();
-
-        assertArrayEquals(EAP_MSCHAP_V2_CHALLENGE_RESPONSE, encodedChallengeResponse);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureRequestTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureRequestTest.java
deleted file mode 100644
index ead8022..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureRequestTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_REQUEST;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ERROR_CODE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_EXTRA_ATTRIBUTE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_INVALID_CHALLENGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_INVALID_ERROR_CODE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_INVALID_PASSWORD_CHANGE_PROTOCOL;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.FAILURE_REQUEST_SHORT_CHALLENGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE_MISSING_TEXT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PASSWORD_CHANGE_PROTOCOL;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.RETRY_BIT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class EapMsChapV2FailureRequestTest {
-    private static final String TAG = EapMsChapV2FailureRequestTest.class.getSimpleName();
-
-    private EapMsChapV2TypeDataDecoder mTypeDataDecoder;
-
-    @Before
-    public void setUp() {
-        mTypeDataDecoder = new EapMsChapV2TypeDataDecoder();
-    }
-
-    @Test
-    public void testDecodeFailureRequest() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(TAG, EAP_MSCHAP_V2_FAILURE_REQUEST);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2FailureRequest failureRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_FAILURE, failureRequest.opCode);
-        assertEquals(ID_INT, failureRequest.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_FAILURE_REQUEST.length, failureRequest.msLength);
-        assertEquals(ERROR_CODE, failureRequest.errorCode);
-        assertEquals(RETRY_BIT, failureRequest.isRetryable);
-        assertArrayEquals(CHALLENGE_BYTES, failureRequest.challenge);
-        assertEquals(PASSWORD_CHANGE_PROTOCOL, failureRequest.passwordChangeProtocol);
-        assertEquals(MESSAGE, failureRequest.message);
-    }
-
-    @Test
-    public void testDecodeFailureRequestMissingMessage() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(
-                        TAG, EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2FailureRequest failureRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_FAILURE, failureRequest.opCode);
-        assertEquals(ID_INT, failureRequest.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE.length, failureRequest.msLength);
-        assertEquals(ERROR_CODE, failureRequest.errorCode);
-        assertEquals(RETRY_BIT, failureRequest.isRetryable);
-        assertArrayEquals(CHALLENGE_BYTES, failureRequest.challenge);
-        assertEquals(PASSWORD_CHANGE_PROTOCOL, failureRequest.passwordChangeProtocol);
-        assertEquals(MESSAGE_MISSING_TEXT, failureRequest.message);
-    }
-
-    @Test
-    public void testDecodeFailureRequestMissingMessageWithSpace() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(
-                        TAG, EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2FailureRequest failureRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_FAILURE, failureRequest.opCode);
-        assertEquals(ID_INT, failureRequest.msChapV2Id);
-        assertEquals(
-                EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE.length,
-                failureRequest.msLength);
-        assertEquals(ERROR_CODE, failureRequest.errorCode);
-        assertEquals(RETRY_BIT, failureRequest.isRetryable);
-        assertArrayEquals(CHALLENGE_BYTES, failureRequest.challenge);
-        assertEquals(PASSWORD_CHANGE_PROTOCOL, failureRequest.passwordChangeProtocol);
-        assertEquals(MESSAGE_MISSING_TEXT, failureRequest.message);
-    }
-
-    @Test
-    public void testDecodeFailureRequestInvalidErrorCode() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_INVALID_ERROR_CODE);
-        assertTrue(!result.isSuccessfulDecode());
-        assertTrue(result.eapError.cause instanceof NumberFormatException);
-    }
-
-    @Test
-    public void testDecodeFailureRequestInvalidChallenge() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_INVALID_CHALLENGE);
-        assertTrue(!result.isSuccessfulDecode());
-        assertTrue(result.eapError.cause instanceof NumberFormatException);
-    }
-
-    @Test
-    public void testDecodeFailureRequestShortChallenge() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_SHORT_CHALLENGE);
-        assertTrue(!result.isSuccessfulDecode());
-        assertTrue(result.eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeFailureRequestInvalidPasswordChangeProtocol() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(
-                        TAG, FAILURE_REQUEST_INVALID_PASSWORD_CHANGE_PROTOCOL);
-        assertTrue(!result.isSuccessfulDecode());
-        assertTrue(result.eapError.cause instanceof NumberFormatException);
-    }
-
-    @Test
-    public void testDecodeFailureExtraAttribute() {
-        DecodeResult<EapMsChapV2FailureRequest> result =
-                mTypeDataDecoder.decodeFailureRequest(TAG, FAILURE_REQUEST_EXTRA_ATTRIBUTE);
-        assertTrue(!result.isSuccessfulDecode());
-        assertTrue(result.eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testEncodeFails() throws Exception {
-        EapMsChapV2FailureRequest failureRequest =
-                new EapMsChapV2FailureRequest(
-                        ID_INT,
-                        EAP_MSCHAP_V2_FAILURE_REQUEST.length,
-                        ERROR_CODE,
-                        RETRY_BIT,
-                        CHALLENGE_BYTES,
-                        PASSWORD_CHANGE_PROTOCOL,
-                        MESSAGE);
-        try {
-            failureRequest.encode();
-            fail("Expected UnsupportedOperationException for encoding a request");
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureResponseTest.java
deleted file mode 100644
index 261ddb2..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2FailureResponseTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_FAILURE_RESPONSE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureResponse;
-
-import org.junit.Test;
-
-public class EapMsChapV2FailureResponseTest {
-    @Test
-    public void testGetEapMsChapV2FailureResponse() {
-        EapMsChapV2FailureResponse failureResponse =
-                EapMsChapV2FailureResponse.getEapMsChapV2FailureResponse();
-        assertEquals(EAP_MSCHAP_V2_FAILURE, failureResponse.opCode);
-    }
-
-    @Test
-    public void testEncode() {
-        EapMsChapV2FailureResponse failureResponse =
-                EapMsChapV2FailureResponse.getEapMsChapV2FailureResponse();
-        assertArrayEquals(EAP_MSCHAP_V2_FAILURE_RESPONSE, failureResponse.encode());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2PacketDefinitions.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2PacketDefinitions.java
deleted file mode 100644
index e70c2a2..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2PacketDefinitions.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-
-public class EapMsChapV2PacketDefinitions {
-    public static final String ID = "1F";
-    public static final int ID_INT = Integer.parseInt(ID, 16 /* radix */);
-
-    public static final String CHALLENGE = "000102030405060708090A0B0C0D0E0F";
-    public static final byte[] CHALLENGE_BYTES = hexStringToByteArray(CHALLENGE);
-
-    // server name is the ASCII hex for "authenticator@android.net"
-    public static final String SERVER_NAME = "61757468656E74696361746F7240616E64726F69642E6E6574";
-    public static final byte[] SERVER_NAME_BYTES = hexStringToByteArray(SERVER_NAME);
-    public static final byte[] EAP_MSCHAP_V2_CHALLENGE_REQUEST =
-            hexStringToByteArray("01" + ID + "002E10" + CHALLENGE + SERVER_NAME);
-
-    public static final byte[] CHALLENGE_REQUEST_WRONG_OP_CODE = hexStringToByteArray("02");
-    public static final String SHORT_CHALLENGE = "001122334455";
-    public static final byte[] SHORT_CHALLENGE_BYTES = hexStringToByteArray(SHORT_CHALLENGE);
-    public static final byte[] CHALLENGE_REQUEST_SHORT_CHALLENGE =
-            hexStringToByteArray("01" + ID + "002406" + SHORT_CHALLENGE + SERVER_NAME);
-    public static final byte[] CHALLENGE_REQUEST_SHORT_MS_LENGTH =
-            hexStringToByteArray("01" + ID + "000110" + CHALLENGE + SERVER_NAME);
-    public static final byte[] CHALLENGE_REQUEST_LONG_MS_LENGTH =
-            hexStringToByteArray("01" + ID + "00FF10" + CHALLENGE + SERVER_NAME);
-
-    public static final String PEER_CHALLENGE = "00112233445566778899AABBCCDDEEFF";
-    public static final byte[] PEER_CHALLENGE_BYTES = hexStringToByteArray(PEER_CHALLENGE);
-    public static final String NT_RESPONSE = "FFEEDDCCBBAA998877665544332211000011223344556677";
-    public static final byte[] NT_RESPONSE_BYTES = hexStringToByteArray(NT_RESPONSE);
-
-    // peer name is the ASCII hex for "peer@android.net"
-    public static final String PEER_NAME = "7065657240616E64726F69642E6E6574";
-    public static final byte[] PEER_NAME_BYTES = hexStringToByteArray(PEER_NAME);
-    public static final byte[] EAP_MSCHAP_V2_CHALLENGE_RESPONSE =
-            hexStringToByteArray(
-                    "02"
-                            + ID
-                            + "004631"
-                            + PEER_CHALLENGE
-                            + "0000000000000000"
-                            + NT_RESPONSE
-                            + "00"
-                            + PEER_NAME);
-
-    public static final byte[] SHORT_NT_RESPONSE = hexStringToByteArray("0011223344");
-
-    public static final String AUTH_STRING = "00112233445566778899AABBCCDDEEFF00112233";
-
-    // ASCII hex for AUTH_STRING
-    public static final String AUTH_STRING_HEX =
-            "30303131323233333434353536363737383839394141424243434444454546463030313132323333";
-    public static final byte[] AUTH_BYTES = hexStringToByteArray(AUTH_STRING);
-
-    // hex("S=") + AUTH_STRING_HEX
-    public static final String FORMATTED_AUTH_STRING = "533D" + AUTH_STRING_HEX;
-
-    public static final String SPACE_HEX = "20";
-
-    // ASCII hex for: "test Android 1234"
-    public static final String MESSAGE = "test Android 1234";
-    public static final String MESSAGE_HEX = "7465737420416E64726F69642031323334";
-
-    // hex("M=") + MESSAGE_HEX
-    public static final String FORMATTED_MESSAGE = "4D3D" + MESSAGE_HEX;
-
-    public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST =
-            hexStringToByteArray(
-                    "03" + ID + "0042" + FORMATTED_AUTH_STRING + SPACE_HEX + FORMATTED_MESSAGE);
-    public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE =
-            hexStringToByteArray("03" + ID + "0031" + FORMATTED_AUTH_STRING + SPACE_HEX + "4D3D");
-    public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE =
-            hexStringToByteArray("03" + ID + "002E" + FORMATTED_AUTH_STRING);
-    public static final byte[] EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE =
-            hexStringToByteArray("03" + ID + "002F" + FORMATTED_AUTH_STRING + SPACE_HEX);
-    public static final String MESSAGE_MISSING_TEXT = "<omitted by authenticator>";
-
-    public static final String SHORT_AUTH_STRING = "001122334455";
-
-    public static final byte[] SUCCESS_REQUEST_WRONG_OP_CODE = hexStringToByteArray("02");
-
-    // message format: hex("M=") + AUTH_STRING_HEX + hex("M=") + MESSAGE_HEX
-    public static final byte[] SUCCESS_REQUEST_WRONG_PREFIX =
-            hexStringToByteArray("03" + ID + "00314D3D" + AUTH_STRING_HEX + SPACE_HEX + "4D3D");
-
-    // message format: hex("S=") + SHORT_AUTH_STRING + hex("M=") + MESSAGE_HEX
-    public static final byte[] SUCCESS_REQUEST_SHORT_AUTH_STRING =
-            hexStringToByteArray("03" + ID + "0031533D" + SHORT_AUTH_STRING + SPACE_HEX + "4D3D");
-
-    public static final String INVALID_AUTH_HEX =
-            "3030313132323333343435353636373738383939414142424343444445454646303031317A7A7979";
-    public static final byte[] SUCCESS_REQUEST_INVALID_AUTH_STRING =
-            hexStringToByteArray("03" + ID + "0031533D" + INVALID_AUTH_HEX + SPACE_HEX + "4D3D");
-
-    // extra key-value: hex("N=12")
-    public static final String EXTRA_KEY = "4E3D3132";
-    public static final byte[] SUCCESS_REQUEST_EXTRA_ATTRIBUTE =
-            hexStringToByteArray(
-                    "03"
-                            + ID
-                            + "0042"
-                            + FORMATTED_AUTH_STRING
-                            + SPACE_HEX
-                            + EXTRA_KEY
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-
-    public static final String SUCCESS_REQUEST = "S=" + AUTH_STRING + " M=" + MESSAGE;
-    public static final String EXTRA_M_MESSAGE = "M=" + MESSAGE;
-    public static final String SUCCESS_REQUEST_EXTRA_M =
-            "S=" + AUTH_STRING + " M=" + EXTRA_M_MESSAGE;
-    public static final String SUCCESS_REQUEST_MISSING_M = "S=" + AUTH_STRING;
-    public static final String SUCCESS_REQUEST_INVALID_FORMAT =
-            "S==" + AUTH_STRING + "M=" + MESSAGE;
-    public static final String SUCCESS_REQUEST_DUPLICATE_KEY =
-            "S=" + AUTH_STRING + " S=" + AUTH_STRING + " M=" + MESSAGE;
-
-    public static final byte[] EAP_MSCHAP_V2_SUCCESS_RESPONSE = hexStringToByteArray("03");
-
-    public static final int ERROR_CODE = 647; // account disabled
-
-    // formatted error code: hex("E=" + ERROR_CODE)
-    public static final String FORMATTED_ERROR_CODE = "453D363437";
-    public static final boolean RETRY_BIT = true;
-
-    // formatted retry bit: hex("R=1")
-    public static final String FORMATTED_RETRY_BIT = "523D31";
-
-    // challenge hex: hex(CHALLENGE)
-    public static final String CHALLENGE_HEX =
-            "3030303130323033303430353036303730383039304130423043304430453046";
-
-    // formatted challenge: hex("C=") + CHALLENGE_HEX
-    public static final String FORMATTED_CHALLENGE = "433D" + CHALLENGE_HEX;
-
-    public static final int PASSWORD_CHANGE_PROTOCOL = 3;
-
-    // formatted password change protocol: hex("V=3")
-    public static final String FORMATTED_PASSWORD_CHANGE_PROTOCOL = "563D33";
-
-    public static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0048"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-    public static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0034"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL);
-    public static final byte[] EAP_MSCHAP_V2_FAILURE_REQUEST_MISSING_MESSAGE_WITH_SPACE =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0035"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX);
-
-    // invalid error code: hex("E=abc")
-    public static final String INVALID_ERROR_CODE = "453D616263";
-    public static final byte[] FAILURE_REQUEST_INVALID_ERROR_CODE =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0048"
-                            + INVALID_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-
-    // invalid challenge: hex("C=zyxd")
-    public static final String INVALID_CHALLENGE = "433D7A797864";
-    public static final byte[] FAILURE_REQUEST_INVALID_CHALLENGE =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0032"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + INVALID_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-
-    // short challenge: hex("C=" + SHORT_CHALLENGE)
-    public static final String FORMATTED_SHORT_CHALLENGE = "433D303031313232333334343535";
-    public static final byte[] FAILURE_REQUEST_SHORT_CHALLENGE =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0034"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_SHORT_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-
-    // invalid password change protocol: hex("V=d")
-    public static final String INVALID_PASSWORD_CHANGE_PROTOCOL = "563D64";
-    public static final byte[] FAILURE_REQUEST_INVALID_PASSWORD_CHANGE_PROTOCOL =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0048"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_CHALLENGE
-                            + SPACE_HEX
-                            + INVALID_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-
-    public static final byte[] FAILURE_REQUEST_EXTRA_ATTRIBUTE =
-            hexStringToByteArray(
-                    "04"
-                            + ID
-                            + "0048"
-                            + FORMATTED_ERROR_CODE
-                            + SPACE_HEX
-                            + FORMATTED_RETRY_BIT
-                            + SPACE_HEX
-                            + FORMATTED_CHALLENGE
-                            + SPACE_HEX
-                            + FORMATTED_PASSWORD_CHANGE_PROTOCOL
-                            + SPACE_HEX
-                            + EXTRA_KEY
-                            + SPACE_HEX
-                            + FORMATTED_MESSAGE);
-
-    public static final byte[] EAP_MSCHAP_V2_FAILURE_RESPONSE = hexStringToByteArray("04");
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessRequestTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessRequestTest.java
deleted file mode 100644
index 1e0909e..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessRequestTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.AUTH_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE_MISSING_TEXT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_EXTRA_ATTRIBUTE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_INVALID_AUTH_STRING;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_SHORT_AUTH_STRING;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_WRONG_OP_CODE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_WRONG_PREFIX;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.BufferUnderflowException;
-
-public class EapMsChapV2SuccessRequestTest {
-    private static final String TAG = EapMsChapV2SuccessRequestTest.class.getSimpleName();
-
-    private EapMsChapV2TypeDataDecoder mTypeDataDecoder;
-
-    @Before
-    public void setUp() {
-        mTypeDataDecoder = new EapMsChapV2TypeDataDecoder();
-    }
-
-    @Test
-    public void testDecodeSuccessRequest() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2SuccessRequest successRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode);
-        assertEquals(ID_INT, successRequest.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_SUCCESS_REQUEST.length, successRequest.msLength);
-        assertArrayEquals(AUTH_BYTES, successRequest.authBytes);
-        assertEquals(MESSAGE, successRequest.message);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestEmptyMessage() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(
-                        TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2SuccessRequest successRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode);
-        assertEquals(ID_INT, successRequest.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_SUCCESS_REQUEST_EMPTY_MESSAGE.length, successRequest.msLength);
-        assertArrayEquals(AUTH_BYTES, successRequest.authBytes);
-        assertTrue(successRequest.message.isEmpty());
-    }
-
-    @Test
-    public void testDecodeSuccessRequestMissingMessage() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(
-                        TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2SuccessRequest successRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode);
-        assertEquals(ID_INT, successRequest.msChapV2Id);
-        assertEquals(EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE.length, successRequest.msLength);
-        assertArrayEquals(AUTH_BYTES, successRequest.authBytes);
-        assertEquals(MESSAGE_MISSING_TEXT, successRequest.message);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestMissingMessageWithSpace() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(
-                        TAG, EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE);
-        assertTrue(result.isSuccessfulDecode());
-
-        EapMsChapV2SuccessRequest successRequest = result.eapTypeData;
-        assertEquals(EAP_MSCHAP_V2_SUCCESS, successRequest.opCode);
-        assertEquals(ID_INT, successRequest.msChapV2Id);
-        assertEquals(
-                EAP_MSCHAP_V2_SUCCESS_REQUEST_MISSING_MESSAGE_WITH_SPACE.length,
-                successRequest.msLength);
-        assertArrayEquals(AUTH_BYTES, successRequest.authBytes);
-        assertEquals(MESSAGE_MISSING_TEXT, successRequest.message);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestWrongOpCode() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_WRONG_OP_CODE);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestShortMessage() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, new byte[0]);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof BufferUnderflowException);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestInvalidPrefix() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_WRONG_PREFIX);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestShortAuthString() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_SHORT_AUTH_STRING);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestInvalidAuthString() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_INVALID_AUTH_STRING);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof NumberFormatException);
-    }
-
-    @Test
-    public void testDecodeSuccessRequestExtraAttribute() {
-        DecodeResult<EapMsChapV2SuccessRequest> result =
-                mTypeDataDecoder.decodeSuccessRequest(TAG, SUCCESS_REQUEST_EXTRA_ATTRIBUTE);
-        assertFalse(result.isSuccessfulDecode());
-        EapError eapError = result.eapError;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-    }
-
-    @Test
-    public void testEncodeFails() throws Exception {
-        EapMsChapV2SuccessRequest successRequest =
-                new EapMsChapV2SuccessRequest(
-                        ID_INT, EAP_MSCHAP_V2_SUCCESS_REQUEST.length, AUTH_BYTES, MESSAGE);
-        try {
-            successRequest.encode();
-            fail("Expected UnsupportedOperationException for encoding a request");
-        } catch (UnsupportedOperationException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessResponseTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessResponseTest.java
deleted file mode 100644
index 524b3ec..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2SuccessResponseTest.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EAP_MSCHAP_V2_SUCCESS_RESPONSE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessResponse;
-
-import org.junit.Test;
-
-public class EapMsChapV2SuccessResponseTest {
-    @Test
-    public void testGetEapMsChapV2SuccessResponse() {
-        EapMsChapV2SuccessResponse successResponse =
-                EapMsChapV2SuccessResponse.getEapMsChapV2SuccessResponse();
-        assertEquals(EAP_MSCHAP_V2_SUCCESS, successResponse.opCode);
-    }
-
-    @Test
-    public void testEncode() {
-        EapMsChapV2SuccessResponse successResponse =
-                EapMsChapV2SuccessResponse.getEapMsChapV2SuccessResponse();
-        assertArrayEquals(EAP_MSCHAP_V2_SUCCESS_RESPONSE, successResponse.encode());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeDataTest.java
deleted file mode 100644
index 45f1c64..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/mschapv2/EapMsChapV2TypeDataTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.mschapv2;
-
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.AUTH_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.AUTH_STRING;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.EXTRA_M_MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE_MISSING_TEXT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_DUPLICATE_KEY;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_EXTRA_M;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_INVALID_FORMAT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SUCCESS_REQUEST_MISSING_M;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_CHALLENGE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2VariableTypeData;
-
-import org.junit.Test;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class EapMsChapV2TypeDataTest {
-    private static final int INVALID_OPCODE = -1;
-    private static final int MSCHAP_V2_ID = 1;
-    private static final int MS_LENGTH = 32;
-    private static final String HEX_STRING_INVALID_LENGTH = "00112";
-    private static final String HEX_STRING_INVALID_CHARS = "001122z-+x";
-
-    @Test
-    public void testEapMsChapV2TypeDataConstructor() throws Exception {
-        EapMsChapV2TypeData typeData = new EapMsChapV2TypeData(EAP_MSCHAP_V2_CHALLENGE) {};
-        assertEquals(EAP_MSCHAP_V2_CHALLENGE, typeData.opCode);
-
-        try {
-            new EapMsChapV2TypeData(INVALID_OPCODE) {};
-            fail("ExpectedEapMsChapV2ParsingException for invalid OpCode");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testEapMsChapV2VariableTypeDataConstructor() throws Exception {
-        EapMsChapV2VariableTypeData typeData =
-                new EapMsChapV2VariableTypeData(
-                        EAP_MSCHAP_V2_CHALLENGE, MSCHAP_V2_ID, MS_LENGTH) {};
-        assertEquals(EAP_MSCHAP_V2_CHALLENGE, typeData.opCode);
-        assertEquals(MSCHAP_V2_ID, typeData.msChapV2Id);
-        assertEquals(MS_LENGTH, typeData.msLength);
-
-        try {
-            new EapMsChapV2VariableTypeData(INVALID_OPCODE, MSCHAP_V2_ID, MS_LENGTH) {};
-            fail("ExpectedEapMsChapV2ParsingException for invalid OpCode");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeResultIsSuccessfulDecode() throws Exception {
-        DecodeResult<EapMsChapV2TypeData> result =
-                new DecodeResult(new EapMsChapV2TypeData(EAP_MSCHAP_V2_CHALLENGE) {});
-        assertTrue(result.isSuccessfulDecode());
-
-        result = new DecodeResult(new EapError(new Exception()));
-        assertFalse(result.isSuccessfulDecode());
-    }
-
-    @Test
-    public void testGetMessageMappings() throws Exception {
-        Map<String, String> expectedMappings = new HashMap<>();
-        expectedMappings.put("S", AUTH_STRING);
-        expectedMappings.put("M", MESSAGE);
-        assertEquals(expectedMappings, EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST));
-
-        expectedMappings = new HashMap<>();
-        expectedMappings.put("S", AUTH_STRING);
-        expectedMappings.put("M", EXTRA_M_MESSAGE);
-        assertEquals(
-                expectedMappings, EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_EXTRA_M));
-
-        expectedMappings = new HashMap<>();
-        expectedMappings.put("S", AUTH_STRING);
-        expectedMappings.put("M", MESSAGE_MISSING_TEXT);
-        assertEquals(
-                expectedMappings,
-                EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_MISSING_M));
-    }
-
-    @Test
-    public void testGetMessageMappingsInvalidFormat() {
-        try {
-            EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_INVALID_FORMAT);
-            fail("Expected EapMsChapV2ParsingException for extra '='s in message");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testGetMessageMappingDuplicateKey() {
-        try {
-            EapMsChapV2TypeData.getMessageMappings(SUCCESS_REQUEST_DUPLICATE_KEY);
-            fail("Expected EapMsChapV2ParsingException for duplicate key in message");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testHexStringToByteArray() throws Exception {
-        byte[] result = EapMsChapV2TypeData.hexStringToByteArray(AUTH_STRING);
-        assertArrayEquals(AUTH_BYTES, result);
-    }
-
-    @Test
-    public void testHexStringToByteArrayInvalidLength() {
-        try {
-            EapMsChapV2TypeData.hexStringToByteArray(HEX_STRING_INVALID_LENGTH);
-            fail("Expected EapMsChapV2ParsingException for invalid hex string length");
-        } catch (EapMsChapV2ParsingException expected) {
-        }
-    }
-
-    @Test
-    public void testHexStringToByteArrayInvalidChars() throws Exception {
-        try {
-            EapMsChapV2TypeData.hexStringToByteArray(HEX_STRING_INVALID_CHARS);
-            fail("Expected NumberFormatException for invalid hex chars");
-        } catch (NumberFormatException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java
deleted file mode 100644
index 6a9e517..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaPrimeTypeDataTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF_INPUT;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INPUT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.KDF_VERSION;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NETWORK_NAME_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NETWORK_NAME_HEX;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map.Entry;
-
-public class EapAkaPrimeTypeDataTest {
-    private static final String RAND = "7A1FCDC0034BA1227E7B9FCEAFD47D53";
-    private static final byte[] RAND_BYTES = hexStringToByteArray(RAND);
-    private static final String AUTN = "000102030405060708090A0B0C0D0E0F";
-    private static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN);
-    private static final String MAC = "95FEB9E70427F34B4FAC8F2C7A65A302";
-    private static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
-    private static final byte[] EAP_AKA_PRIME_CHALLENGE_REQUEST =
-            hexStringToByteArray(
-                    "010000" // Challenge | 2B padding
-                            + "01050000" + RAND // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "1704000B" + NETWORK_NAME_HEX + "00" // AT_KDF_INPUT
-                            + "18010001" // AT_KDF
-                            + "0B050000" + MAC); // AT_MAC attribute
-    private static final byte[] EAP_AKA_PRIME_MULTIPLE_AT_KDF =
-            hexStringToByteArray(
-                    "010000" // Challenge | 2B padding
-                            + "01050000" + RAND // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "1704000B" + NETWORK_NAME_HEX + "00" // AT_KDF_INPUT
-                            + "18010001" // AT_KDF
-                            + "18010002" // AT_KDF
-                            + "0B050000" + MAC); // AT_MAC attribute
-
-    private EapAkaPrimeTypeDataDecoder mTypeDataDecoder;
-
-    @Before
-    public void setUp() {
-        mTypeDataDecoder = EapAkaPrimeTypeData.getEapAkaPrimeTypeDataDecoder();
-    }
-
-    @Test
-    public void testDecode() {
-        DecodeResult<EapAkaTypeData> result =
-                mTypeDataDecoder.decode(EAP_AKA_PRIME_CHALLENGE_REQUEST);
-
-        assertTrue(result.isSuccessfulDecode());
-        EapAkaPrimeTypeData eapAkaPrimeTypeData = (EapAkaPrimeTypeData) result.eapTypeData;
-        assertEquals(EAP_AKA_CHALLENGE, eapAkaPrimeTypeData.eapSubtype);
-
-        // also check Map entries (needs to match input order)
-        Iterator<Entry<Integer, EapSimAkaAttribute>> itr =
-                eapAkaPrimeTypeData.attributeMap.entrySet().iterator();
-        Entry<Integer, EapSimAkaAttribute> entry = itr.next();
-        assertEquals(EAP_AT_RAND, (int) entry.getKey());
-        assertArrayEquals(RAND_BYTES, ((AtRandAka) entry.getValue()).rand);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_AUTN, (int) entry.getKey());
-        assertArrayEquals(AUTN_BYTES, ((AtAutn) entry.getValue()).autn);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_KDF_INPUT, (int) entry.getKey());
-        assertArrayEquals(NETWORK_NAME_BYTES, ((AtKdfInput) entry.getValue()).networkName);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_KDF, (int) entry.getKey());
-        assertEquals(KDF_VERSION, ((AtKdf) entry.getValue()).kdf);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_MAC, (int) entry.getKey());
-        assertArrayEquals(MAC_BYTES, ((AtMac) entry.getValue()).mac);
-
-        assertFalse(itr.hasNext());
-    }
-
-    @Test
-    public void testDecodeMultipleAtKdfAttributes() {
-        DecodeResult<EapAkaTypeData> result =
-                mTypeDataDecoder.decode(EAP_AKA_PRIME_MULTIPLE_AT_KDF);
-
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(AtClientErrorCode.UNABLE_TO_PROCESS, result.atClientErrorCode);
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        LinkedHashMap<Integer, EapSimAkaAttribute> attributes = new LinkedHashMap<>();
-        attributes.put(EAP_AT_RAND, new AtRandAka(RAND_BYTES));
-        attributes.put(EAP_AT_AUTN, new AtAutn(AUTN_BYTES));
-        attributes.put(EAP_AT_KDF_INPUT, new AtKdfInput(AT_KDF_INPUT.length, NETWORK_NAME_BYTES));
-        attributes.put(EAP_AT_KDF, new AtKdf(KDF_VERSION));
-        attributes.put(EAP_AT_MAC, new AtMac(MAC_BYTES));
-        EapAkaPrimeTypeData eapAkaPrimeTypeData =
-                new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, attributes);
-
-        byte[] result = eapAkaPrimeTypeData.encode();
-        assertArrayEquals(EAP_AKA_PRIME_CHALLENGE_REQUEST, result);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java
deleted file mode 100644
index b2d89d1..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapAkaTypeDataTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CHALLENGE_RESPONSE_MAC_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CHALLENGE_RESPONSE_TYPE_DATA;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_IDENTITY_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_SUBTYPE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_CHECKCODE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES;
-
-import static junit.framework.TestCase.fail;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EapSimAkaUnsupportedAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.Map.Entry;
-
-public class EapAkaTypeDataTest {
-    private static final int UNABLE_TO_PROCESS_CODE = 0;
-    private static final int INVALID_SUBTYPE_INT = -1;
-
-    private static final int EAP_AT_TRUST_IND = 139;
-    private static final String RAND = "7A1FCDC0034BA1227E7B9FCEAFD47D53";
-    private static final byte[] RAND_BYTES = hexStringToByteArray(RAND);
-    private static final String AUTN = "000102030405060708090A0B0C0D0E0F";
-    private static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN);
-    private static final String MAC = "95FEB9E70427F34B4FAC8F2C7A65A302";
-    private static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
-    private static final byte[] EAP_AKA_REQUEST =
-            hexStringToByteArray(
-                    "010000" // Challenge | 2B padding
-                            + "01050000" + RAND // AT_RAND attribute
-                            + "02050000" + AUTN // AT_AUTN attribute
-                            + "8B010002" // AT_RESULT_IND attribute (TS 124 302#8.2.3.1)
-                            + "0B050000" + MAC // AT_MAC attribute
-                            + "86010000"); // AT_CHECKCODE attribute
-
-    private EapAkaTypeDataDecoder mEapAkaTypeDataDecoder;
-
-    @Before
-    public void setUp() {
-        mEapAkaTypeDataDecoder = EapAkaTypeData.getEapAkaTypeDataDecoder();
-    }
-
-    @Test
-    public void testDecode() {
-        DecodeResult<EapAkaTypeData> result =
-                mEapAkaTypeDataDecoder.decode(EAP_AKA_CHALLENGE_RESPONSE_TYPE_DATA);
-
-        assertTrue(result.isSuccessfulDecode());
-        EapAkaTypeData eapAkaTypeData = result.eapTypeData;
-        assertEquals(EAP_AKA_CHALLENGE, eapAkaTypeData.eapSubtype);
-
-        // also check Map entries (needs to match input order)
-        Iterator<Entry<Integer, EapSimAkaAttribute>> itr =
-                eapAkaTypeData.attributeMap.entrySet().iterator();
-        Entry<Integer, EapSimAkaAttribute> entry = itr.next();
-        assertEquals(EAP_AT_RES, (int) entry.getKey());
-        assertArrayEquals(RES_BYTES, ((AtRes) entry.getValue()).res);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_MAC, (int) entry.getKey());
-        assertArrayEquals(EAP_AKA_CHALLENGE_RESPONSE_MAC_BYTES, ((AtMac) entry.getValue()).mac);
-
-        assertFalse(itr.hasNext());
-    }
-
-    @Test
-    public void testDecodeWithOptionalAttributes() {
-        DecodeResult<EapAkaTypeData> result = mEapAkaTypeDataDecoder.decode(EAP_AKA_REQUEST);
-
-        assertTrue(result.isSuccessfulDecode());
-        EapAkaTypeData eapAkaTypeData = result.eapTypeData;
-        assertEquals(EAP_AKA_CHALLENGE, eapAkaTypeData.eapSubtype);
-
-        // also check Map entries (needs to match input order)
-        Iterator<Entry<Integer, EapSimAkaAttribute>> itr =
-                eapAkaTypeData.attributeMap.entrySet().iterator();
-        Entry<Integer, EapSimAkaAttribute> entry = itr.next();
-        assertEquals(EAP_AT_RAND, (int) entry.getKey());
-        assertArrayEquals(RAND_BYTES, ((AtRandAka) entry.getValue()).rand);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_AUTN, (int) entry.getKey());
-        assertArrayEquals(AUTN_BYTES, ((AtAutn) entry.getValue()).autn);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_TRUST_IND, (int) entry.getKey());
-        assertTrue(entry.getValue() instanceof EapSimAkaUnsupportedAttribute);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_MAC, (int) entry.getKey());
-        assertArrayEquals(MAC_BYTES, ((AtMac) entry.getValue()).mac);
-
-        entry = itr.next();
-        assertEquals(EAP_AT_CHECKCODE, (int) entry.getKey());
-        assertTrue(entry.getValue() instanceof EapSimAkaUnsupportedAttribute);
-
-        assertFalse(itr.hasNext());
-    }
-
-    @Test
-    public void testDecodeInvalidSubtype() {
-        DecodeResult<EapAkaTypeData> result = mEapAkaTypeDataDecoder.decode(INVALID_SUBTYPE);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        LinkedHashMap<Integer, EapSimAkaAttribute> attributes = new LinkedHashMap<>();
-        attributes.put(EAP_AT_ANY_ID_REQ, new AtAnyIdReq());
-        EapAkaTypeData eapAkaTypeData = new EapAkaTypeData(EAP_AKA_IDENTITY, attributes);
-
-        byte[] result = eapAkaTypeData.encode();
-        assertArrayEquals(EAP_AKA_IDENTITY_REQUEST, result);
-    }
-
-    @Test
-    public void testConstructorInvalidSubtype() throws Exception {
-        try {
-            new EapAkaTypeData(INVALID_SUBTYPE_INT, Arrays.asList(new AtAnyIdReq()));
-            fail("Expected IllegalArgumentException for invalid subtype");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testConstructorDuplicateAttributes() throws Exception {
-        try {
-            new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq(), new AtAnyIdReq()));
-            fail("Expected IllegalArgumentException for duplicate attributes");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactoryTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactoryTest.java
deleted file mode 100644
index 5b6f5d6..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimAkaAttributeFactoryTest.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SKIPPABLE_DATA;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SKIPPABLE_DATA_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SKIPPABLE_INVALID_ATTRIBUTE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaUnsupportedAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EapSimAkaUnsupportedAttribute;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class EapSimAkaAttributeFactoryTest {
-    private static final int SKIPPABLE_ATTRIBUTE_TYPE = 0xFF;
-    private static final int SKIPPABLE_EXPECTED_LENGTH = 8;
-
-    private static final int NON_SKIPPABLE_ATTRIBUTE_TYPE = 0x7F;
-    private static final int NON_SKIPPABLE_ATTRIBUTE_LENGTH = 4;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecodeInvalidSkippable() throws Exception {
-        ByteBuffer byteBuffer = ByteBuffer.wrap(SKIPPABLE_DATA_BYTES);
-
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(
-                SKIPPABLE_ATTRIBUTE_TYPE,
-                SKIPPABLE_EXPECTED_LENGTH,
-                byteBuffer);
-        assertTrue(result instanceof EapSimAkaUnsupportedAttribute);
-        EapSimAkaUnsupportedAttribute unsupportedAttribute = (EapSimAkaUnsupportedAttribute) result;
-        assertEquals(SKIPPABLE_ATTRIBUTE_TYPE, unsupportedAttribute.attributeType);
-        assertEquals(SKIPPABLE_EXPECTED_LENGTH, unsupportedAttribute.lengthInBytes);
-        assertArrayEquals(hexStringToByteArray(SKIPPABLE_DATA), unsupportedAttribute.data);
-    }
-
-    @Test
-    public void testEncodeInvalidSkippable() throws Exception {
-        EapSimAkaUnsupportedAttribute unsupportedAttribute = new EapSimAkaUnsupportedAttribute(
-                SKIPPABLE_ATTRIBUTE_TYPE,
-                SKIPPABLE_EXPECTED_LENGTH,
-                hexStringToByteArray(SKIPPABLE_DATA));
-
-        ByteBuffer result = ByteBuffer.allocate(SKIPPABLE_EXPECTED_LENGTH);
-        unsupportedAttribute.encode(result);
-        assertArrayEquals(SKIPPABLE_INVALID_ATTRIBUTE, result.array());
-    }
-
-    @Test
-    public void testDecodeInvalidNonSkippable() throws Exception {
-        // Unskippable type + length + byte[] represent shortest legitimate attribute: "7F040000"
-        ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[2]);
-
-        try {
-            mAttributeFactory.getAttribute(
-                    NON_SKIPPABLE_ATTRIBUTE_TYPE,
-                    NON_SKIPPABLE_ATTRIBUTE_LENGTH,
-                    byteBuffer);
-            fail("Expected EapSimAkaUnsupportedAttributeException for decoding invalid"
-                    + " non-skippable Attribute");
-        } catch (EapSimAkaUnsupportedAttributeException expected) {
-        }
-    }
-
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java
deleted file mode 100644
index 678a812..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/EapSimTypeDataTest.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka;
-
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_START_DUPLICATE_ATTRIBUTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_START_SUBTYPE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_SUBTYPE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SHORT_TYPE_DATA;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.TYPE_DATA_INVALID_ATTRIBUTE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.TYPE_DATA_INVALID_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST;
-
-import static junit.framework.TestCase.fail;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map.Entry;
-
-public class EapSimTypeDataTest {
-    private static final int UNABLE_TO_PROCESS_CODE = 0;
-    private static final int INSUFFICIENT_CHALLENGES_CODE = 2;
-    private static final int EAP_SIM_START = 10;
-    private static final int INVALID_SUBTYPE_INT = -1;
-
-    private EapSimTypeDataDecoder mEapSimTypeDataDecoder;
-
-    @Before
-    public void setUp() {
-        mEapSimTypeDataDecoder = EapSimTypeData.getEapSimTypeDataDecoder();
-    }
-
-    @Test
-    public void testConstructor() throws Exception {
-        List<EapSimAkaAttribute> attributes = Arrays.asList(
-                new AtVersionList(8, 1), new AtPermanentIdReq());
-
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, attributes);
-        assertEquals(EAP_SIM_START, eapSimTypeData.eapSubtype);
-
-        // check order of entries in EapSimTypeData.attributeMap
-        Iterator<Entry<Integer, EapSimAkaAttribute>> itr =
-                eapSimTypeData.attributeMap.entrySet().iterator();
-        Entry<Integer, EapSimAkaAttribute> pair = itr.next();
-        assertEquals(EAP_AT_VERSION_LIST, (int) pair.getKey());
-        assertEquals(Arrays.asList(1), ((AtVersionList) pair.getValue()).versions);
-
-        pair = itr.next();
-        assertEquals(EAP_AT_PERMANENT_ID_REQ, (int) pair.getKey());
-        assertTrue(pair.getValue() instanceof AtPermanentIdReq);
-    }
-
-    @Test
-    public void testDecode() {
-        DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(EAP_SIM_START_SUBTYPE);
-
-        assertTrue(result.isSuccessfulDecode());
-        EapSimTypeData eapSimTypeData = result.eapTypeData;
-        assertEquals(EAP_SIM_START, eapSimTypeData.eapSubtype);
-        assertTrue(eapSimTypeData.attributeMap.containsKey(EAP_AT_VERSION_LIST));
-        AtVersionList atVersionList = (AtVersionList)
-                eapSimTypeData.attributeMap.get(EAP_AT_VERSION_LIST);
-        assertEquals(Arrays.asList(1), atVersionList.versions);
-        assertTrue(eapSimTypeData.attributeMap.containsKey(EAP_AT_PERMANENT_ID_REQ));
-
-        // also check order of Map entries (needs to match input order)
-        Iterator<Integer> itr = eapSimTypeData.attributeMap.keySet().iterator();
-        assertEquals(EAP_AT_VERSION_LIST, (int) itr.next());
-        assertEquals(EAP_AT_PERMANENT_ID_REQ, (int) itr.next());
-        assertFalse(itr.hasNext());
-    }
-
-    @Test
-    public void testDecodeNullTypeData() {
-        DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(null);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testDecodeInvalidSubtype() {
-        DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(INVALID_SUBTYPE);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testDecodeInvalidAtRand() {
-        DecodeResult<EapSimTypeData> result =
-                mEapSimTypeDataDecoder.decode(TYPE_DATA_INVALID_AT_RAND);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(INSUFFICIENT_CHALLENGES_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testDecodeShortPacket() {
-        DecodeResult<EapSimTypeData> result = mEapSimTypeDataDecoder.decode(SHORT_TYPE_DATA);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testDecodeInvalidEapAttribute() {
-        DecodeResult<EapSimTypeData> result =
-                mEapSimTypeDataDecoder.decode(TYPE_DATA_INVALID_ATTRIBUTE);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        LinkedHashMap<Integer, EapSimAkaAttribute> attributes = new LinkedHashMap<>();
-        attributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1));
-        attributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq());
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, attributes);
-
-        byte[] result = eapSimTypeData.encode();
-        assertArrayEquals(EAP_SIM_START_SUBTYPE, result);
-    }
-
-    @Test
-    public void testDecodeDuplicateAttributes() {
-        DecodeResult<EapSimTypeData> result =
-                mEapSimTypeDataDecoder.decode(EAP_SIM_START_DUPLICATE_ATTRIBUTES);
-        assertFalse(result.isSuccessfulDecode());
-        assertEquals(UNABLE_TO_PROCESS_CODE, result.atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testConstructorInvalidSubtype() throws Exception {
-        try {
-            new EapSimTypeData(INVALID_SUBTYPE_INT, Arrays.asList(new AtPermanentIdReq()));
-            fail("Expected IllegalArgumentException for invalid subtype");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testConstructorDuplicateAttributes() throws Exception {
-        try {
-            new EapSimTypeData(
-                    EAP_SIM_START, Arrays.asList(new AtPermanentIdReq(), new AtPermanentIdReq()));
-            fail("Expected IllegalArgumentException for duplicate attributes");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutnTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutnTest.java
deleted file mode 100644
index ebf22e4..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutnTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTN;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTN_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtAutnTest {
-    private EapAkaAttributeFactory mEapAkaAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_AUTN);
-        EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtAutn atAutn = (AtAutn) result;
-        assertEquals(EAP_AT_AUTN, atAutn.attributeType);
-        assertEquals(AT_AUTN.length, atAutn.lengthInBytes);
-        assertArrayEquals(AUTN_BYTES, atAutn.autn);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_AUTN_INVALID_LENGTH);
-        try {
-            mEapAkaAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_AUTN.length);
-        atAutn.encode(result);
-        assertArrayEquals(AT_AUTN, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutsTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutsTest.java
deleted file mode 100644
index d65a735..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtAutsTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_AUTS;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTS;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_AUTS_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTS_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAuts;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtAutsTest {
-    private EapAkaAttributeFactory mEapAkaAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_AUTS);
-        EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtAuts atAuts = (AtAuts) result;
-        assertEquals(EAP_AT_AUTS, atAuts.attributeType);
-        assertEquals(AT_AUTS.length, atAuts.lengthInBytes);
-        assertArrayEquals(AUTS_BYTES, atAuts.auts);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_AUTS_INVALID_LENGTH);
-        try {
-            mEapAkaAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtAuts atAuts = new AtAuts(AUTS_BYTES);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_AUTS.length);
-        atAuts.encode(result);
-        assertArrayEquals(AT_AUTS, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtBiddingTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtBiddingTest.java
deleted file mode 100644
index efdfcc2..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtBiddingTest.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_BIDDING;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_BIDDING_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_BIDDING_SUPPORTS_AKA_PRIME;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtBiddingTest {
-    private EapAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = EapAkaAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecodeServerSupportsAkaPrime() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_BIDDING_SUPPORTS_AKA_PRIME);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtBidding atBidding = (AtBidding) result;
-        assertEquals(EAP_AT_BIDDING, atBidding.attributeType);
-        assertEquals(AT_BIDDING_SUPPORTS_AKA_PRIME.length, atBidding.lengthInBytes);
-        assertTrue(atBidding.doesServerSupportEapAkaPrime);
-    }
-
-    @Test
-    public void testDecodeDoesNotSupportAkaPrime() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtBidding atBidding = (AtBidding) result;
-        assertEquals(EAP_AT_BIDDING, atBidding.attributeType);
-        assertEquals(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME.length, atBidding.lengthInBytes);
-        assertFalse(atBidding.doesServerSupportEapAkaPrime);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_BIDDING_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeServerSupportsAkaPrime() throws Exception {
-        AtBidding atBidding = new AtBidding(true);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_BIDDING_SUPPORTS_AKA_PRIME.length);
-        atBidding.encode(result);
-        assertArrayEquals(AT_BIDDING_SUPPORTS_AKA_PRIME, result.array());
-    }
-
-    @Test
-    public void testEncodeDoesNotSupportAkaPrime() throws Exception {
-        AtBidding atBidding = new AtBidding(false);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME.length);
-        atBidding.encode(result);
-        assertArrayEquals(AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtClientErrorCodeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtClientErrorCodeTest.java
deleted file mode 100644
index 2051414..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtClientErrorCodeTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToInt;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_CLIENT_ERROR_CODE;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_CLIENT_ERROR_CODE;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_CLIENT_ERROR_CODE_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.ERROR_CODE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.BufferUnderflowException;
-import java.nio.ByteBuffer;
-
-public class AtClientErrorCodeTest {
-    private static final int EXPECTED_LENGTH = 4;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_CLIENT_ERROR_CODE);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtClientErrorCode);
-        AtClientErrorCode atClientErrorCode = (AtClientErrorCode) result;
-        assertEquals(EAP_AT_CLIENT_ERROR_CODE, atClientErrorCode.attributeType);
-        assertEquals(EXPECTED_LENGTH, atClientErrorCode.lengthInBytes);
-        assertEquals(hexStringToInt(ERROR_CODE), atClientErrorCode.errorCode);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_CLIENT_ERROR_CODE_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected BufferUnderflowException for invalid attribute length");
-        } catch (BufferUnderflowException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtClientErrorCode atNotification = new AtClientErrorCode(
-                EXPECTED_LENGTH, hexStringToInt(ERROR_CODE));
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atNotification.encode(result);
-        assertArrayEquals(AT_CLIENT_ERROR_CODE, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtCounterTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtCounterTest.java
deleted file mode 100644
index eb1086d..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtCounterTest.java
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_COUNTER;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_COUNTER_TOO_SMALL;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER_TOO_SMALL;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_COUNTER_TOO_SMALL_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.COUNTER_INT;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtCounter;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtCounterTooSmall;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtCounterTest {
-    private static final int EXPECTED_LENGTH = 4;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecodeAtCounter() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_COUNTER);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtCounter);
-        AtCounter atCounter = (AtCounter) result;
-        assertEquals(EAP_AT_COUNTER, atCounter.attributeType);
-        assertEquals(EXPECTED_LENGTH, atCounter.lengthInBytes);
-        assertEquals(COUNTER_INT, atCounter.counter);
-    }
-
-    @Test
-    public void testDecodeAtCounterInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_COUNTER_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeAtCounter() throws Exception {
-        AtCounter atCounter = new AtCounter(COUNTER_INT);
-
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-        atCounter.encode(result);
-        assertArrayEquals(AT_COUNTER, result.array());
-    }
-
-    @Test
-    public void testAtCounterTooSmallConstructor() throws Exception {
-        AtCounterTooSmall atCounterTooSmall = new AtCounterTooSmall();
-        assertEquals(EAP_AT_COUNTER_TOO_SMALL, atCounterTooSmall.attributeType);
-        assertEquals(EXPECTED_LENGTH, atCounterTooSmall.lengthInBytes);
-    }
-
-    @Test
-    public void testDecodeAtCounterTooSmall() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_COUNTER_TOO_SMALL);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtCounterTooSmall);
-        AtCounterTooSmall atCounterTooSmall = (AtCounterTooSmall) result;
-        assertEquals(EAP_AT_COUNTER_TOO_SMALL, atCounterTooSmall.attributeType);
-        assertEquals(EXPECTED_LENGTH, atCounterTooSmall.lengthInBytes);
-    }
-
-    @Test
-    public void testDecodeAtCounterTooSmallInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_COUNTER_TOO_SMALL_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeAtCounterTooSmall() throws Exception {
-        AtCounterTooSmall atCounterTooSmall = new AtCounterTooSmall();
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-        atCounterTooSmall.encode(result);
-        assertArrayEquals(AT_COUNTER_TOO_SMALL, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdReqTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdReqTest.java
deleted file mode 100644
index d006053..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdReqTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_FULLAUTH_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.ANY_ID_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_FULL_AUTH_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.FULL_AUTH_ID_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.PERMANENT_ID_INVALID_LENGTH;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtFullauthIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtIdReqTest {
-    private static final int EXPECTED_LENGTH = 4;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecodeAtPermanentIdReq() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_PERMANENT_ID_REQ);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtPermanentIdReq);
-        AtPermanentIdReq atPermanentIdReq = (AtPermanentIdReq) result;
-        assertEquals(EAP_AT_PERMANENT_ID_REQ, atPermanentIdReq.attributeType);
-        assertEquals(EXPECTED_LENGTH, atPermanentIdReq.lengthInBytes);
-    }
-
-    @Test
-    public void testDecodeAtPermanentIdReqInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(PERMANENT_ID_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeAtPermanentIdReq() throws Exception {
-        AtPermanentIdReq atPermanentIdReq = new AtPermanentIdReq();
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atPermanentIdReq.encode(result);
-        assertArrayEquals(AT_PERMANENT_ID_REQ, result.array());
-    }
-
-    @Test
-    public void testDecodeAtAnyIdReq() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_ANY_ID_REQ);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtAnyIdReq);
-        AtAnyIdReq atAnyIdReq = (AtAnyIdReq) result;
-        assertEquals(EAP_AT_ANY_ID_REQ, atAnyIdReq.attributeType);
-        assertEquals(EXPECTED_LENGTH, atAnyIdReq.lengthInBytes);
-    }
-
-    @Test
-    public void testDecodeAtAnyIdReqInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(ANY_ID_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeAtAnyIdReq() throws Exception {
-        AtAnyIdReq atPermanentIdReq = new AtAnyIdReq();
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atPermanentIdReq.encode(result);
-        assertArrayEquals(AT_ANY_ID_REQ, result.array());
-    }
-
-    @Test
-    public void testDecodeAtFullauthIdReq() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_FULL_AUTH_ID_REQ);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtFullauthIdReq);
-        AtFullauthIdReq atFullauthIdReq = (AtFullauthIdReq) result;
-        assertEquals(EAP_AT_FULLAUTH_ID_REQ, atFullauthIdReq.attributeType);
-        assertEquals(EXPECTED_LENGTH, atFullauthIdReq.lengthInBytes);
-    }
-
-    @Test
-    public void testDecodeAtFullauthIdReqInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(FULL_AUTH_ID_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeAtFullauthIdReq() throws Exception {
-        AtFullauthIdReq atPermanentIdReq = new AtFullauthIdReq();
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atPermanentIdReq.encode(result);
-        assertArrayEquals(AT_FULL_AUTH_ID_REQ, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdentityTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdentityTest.java
deleted file mode 100644
index cf8e880..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtIdentityTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtIdentityTest {
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_IDENTITY);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtIdentity);
-        AtIdentity atIdentity = (AtIdentity) result;
-        assertEquals(EAP_AT_IDENTITY, atIdentity.attributeType);
-        assertEquals(AT_IDENTITY.length, atIdentity.lengthInBytes);
-        assertArrayEquals(IDENTITY, atIdentity.identity);
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtIdentity atIdentity = new AtIdentity(AT_IDENTITY.length, IDENTITY);
-        ByteBuffer result = ByteBuffer.allocate(AT_IDENTITY.length);
-        atIdentity.encode(result);
-
-        assertArrayEquals(AT_IDENTITY, result.array());
-    }
-
-    @Test
-    public void testGetAtIdentity() throws Exception {
-        AtIdentity atIdentity = AtIdentity.getAtIdentity(IDENTITY);
-
-        assertArrayEquals(IDENTITY, atIdentity.identity);
-
-        ByteBuffer buffer = ByteBuffer.allocate(atIdentity.lengthInBytes);
-        atIdentity.encode(buffer);
-        buffer.rewind();
-
-        EapSimAkaAttribute eapSimAkaAttribute =
-                EapSimAttributeFactory.getInstance().getAttribute(buffer);
-        assertTrue(eapSimAkaAttribute instanceof AtIdentity);
-        AtIdentity newAtIdentity = (AtIdentity) eapSimAkaAttribute;
-        assertEquals(atIdentity.lengthInBytes, newAtIdentity.lengthInBytes);
-        assertArrayEquals(atIdentity.identity, newAtIdentity.identity);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfInputTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfInputTest.java
deleted file mode 100644
index 51ea3f1..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfInputTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF_INPUT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INPUT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INPUT_EMPTY_NETWORK_NAME;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NETWORK_NAME_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtKdfInputTest {
-    private EapAkaPrimeAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = EapAkaPrimeAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_KDF_INPUT);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtKdfInput atKdfInput = (AtKdfInput) result;
-        assertEquals(EAP_AT_KDF_INPUT, atKdfInput.attributeType);
-        assertEquals(AT_KDF_INPUT.length, atKdfInput.lengthInBytes);
-        assertArrayEquals(NETWORK_NAME_BYTES, atKdfInput.networkName);
-    }
-
-    @Test
-    public void testDecodeEmptyNetworkName() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_KDF_INPUT_EMPTY_NETWORK_NAME);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtKdfInput atKdfInput = (AtKdfInput) result;
-        assertEquals(EAP_AT_KDF_INPUT, atKdfInput.attributeType);
-        assertEquals(AT_KDF_INPUT_EMPTY_NETWORK_NAME.length, atKdfInput.lengthInBytes);
-        assertArrayEquals(new byte[0], atKdfInput.networkName);
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtKdfInput atKdfInput = new AtKdfInput(AT_KDF_INPUT.length, NETWORK_NAME_BYTES);
-        ByteBuffer result = ByteBuffer.allocate(AT_KDF_INPUT.length);
-
-        atKdfInput.encode(result);
-        assertArrayEquals(AT_KDF_INPUT, result.array());
-        assertFalse(result.hasRemaining());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfTest.java
deleted file mode 100644
index 0bb0732..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtKdfTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_KDF;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_KDF_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.KDF_VERSION;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtKdfTest {
-    private EapAkaPrimeAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = EapAkaPrimeAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_KDF);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtKdf atKdf = (AtKdf) result;
-        assertEquals(EAP_AT_KDF, atKdf.attributeType);
-        assertEquals(AT_KDF.length, atKdf.lengthInBytes);
-        assertEquals(KDF_VERSION, atKdf.kdf);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_KDF_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtKdf atKdf = new AtKdf(KDF_VERSION);
-        ByteBuffer result = ByteBuffer.allocate(AT_KDF.length);
-
-        atKdf.encode(result);
-        assertArrayEquals(AT_KDF, result.array());
-        assertFalse(result.hasRemaining());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java
deleted file mode 100644
index 82b066d..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtMacTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_MAC;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_MAC_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.MAC;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtMacTest {
-    private static final int EXPECTED_LENGTH = 20;
-    private static final int MAC_LENGTH = 16;
-    private static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
-    private static final byte[] INVALID_MAC = {(byte) 1, (byte) 2, (byte) 3};
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testConstructor() throws Exception {
-        AtMac atMac = new AtMac();
-        assertEquals(EAP_AT_MAC, atMac.attributeType);
-        assertEquals(EXPECTED_LENGTH, atMac.lengthInBytes);
-        assertArrayEquals(new byte[MAC_LENGTH], atMac.mac);
-    }
-
-    @Test
-    public void testParameterizedConstructor() throws Exception {
-        AtMac atMac = new AtMac(MAC_BYTES);
-        assertEquals(EAP_AT_MAC, atMac.attributeType);
-        assertEquals(EXPECTED_LENGTH, atMac.lengthInBytes);
-        assertArrayEquals(MAC_BYTES, atMac.mac);
-    }
-
-    @Test
-    public void testParameterizedConstructorInvalidMac() {
-        try {
-            AtMac atMac = new AtMac(INVALID_MAC);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid MAC length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_MAC);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtMac);
-        AtMac atMac = (AtMac) result;
-        assertEquals(EAP_AT_MAC, atMac.attributeType);
-        assertEquals(EXPECTED_LENGTH, atMac.lengthInBytes);
-        assertArrayEquals(MAC_BYTES, atMac.mac);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_MAC_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtMac atMac = new AtMac(MAC_BYTES);
-
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-        atMac.encode(result);
-        assertArrayEquals(AT_MAC, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceMtTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceMtTest.java
deleted file mode 100644
index 751908a..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceMtTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NONCE_MT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_MT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt;
-import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtNonceMtTest {
-    private static final byte[] INVALID_NONCE = new byte[10];
-    private static final int EXPECTED_LENGTH = 20;
-
-    private EapSimAttributeFactory mEapSimAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapSimAttributeFactory = EapSimAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testConstructorInvalidNonceLength() {
-        try {
-            new AtNonceMt(INVALID_NONCE);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid NonceMt length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NONCE_MT);
-        EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtNonceMt);
-        AtNonceMt atNonceMt = (AtNonceMt) result;
-        assertEquals(EAP_AT_NONCE_MT, atNonceMt.attributeType);
-        assertEquals(EXPECTED_LENGTH, atNonceMt.lengthInBytes);
-        assertArrayEquals(NONCE_MT, atNonceMt.nonceMt);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NONCE_INVALID_LENGTH);
-        try {
-            mEapSimAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws EapSimAkaInvalidAttributeException {
-        AtNonceMt atNonceMt = new AtNonceMt(NONCE_MT);
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atNonceMt.encode(result);
-        assertArrayEquals(AT_NONCE_MT, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceSTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceSTest.java
deleted file mode 100644
index 1ad6466..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNonceSTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NONCE_S;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_S;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NONCE_S_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_S;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceS;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtNonceSTest {
-    private static final byte[] INVALID_NONCE = new byte[10];
-    private static final int EXPECTED_LENGTH = 20;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testConstructorInvalidNonceLength() {
-        try {
-            new AtNonceS(INVALID_NONCE);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid NonceMt length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NONCE_S);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtNonceS);
-        AtNonceS atNonceS = (AtNonceS) result;
-        assertEquals(EAP_AT_NONCE_S, atNonceS.attributeType);
-        assertEquals(EXPECTED_LENGTH, atNonceS.lengthInBytes);
-        assertArrayEquals(hexStringToByteArray(NONCE_S), atNonceS.nonceS);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NONCE_S_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtNonceS atNonceS = new AtNonceS(hexStringToByteArray(NONCE_S));
-
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-        atNonceS.encode(result);
-        assertArrayEquals(AT_NONCE_S, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNotificationTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNotificationTest.java
deleted file mode 100644
index 2db3cbb..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtNotificationTest.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToInt;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_POST_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NOTIFICATION_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_NOTIFICATION_INVALID_STATE;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NOTIFICATION_CODE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtNotificationTest {
-    private static final int EXPECTED_LENGTH = 4;
-    private static final int UNKNOWN_CODE = 0xA0FF;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NOTIFICATION);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtNotification);
-        AtNotification atNotification = (AtNotification) result;
-        assertEquals(EAP_AT_NOTIFICATION, atNotification.attributeType);
-        assertEquals(EXPECTED_LENGTH, atNotification.lengthInBytes);
-        assertTrue(atNotification.isSuccessCode);
-        assertFalse(atNotification.isPreSuccessfulChallenge);
-        assertEquals(hexStringToInt(NOTIFICATION_CODE), atNotification.notificationCode);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NOTIFICATION_INVALID_LENGTH);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid attribute length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeInvalidState() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_NOTIFICATION_INVALID_STATE);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid state");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtNotification atNotification = new AtNotification(hexStringToInt(NOTIFICATION_CODE));
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atNotification.encode(result);
-        assertArrayEquals(AT_NOTIFICATION, result.array());
-    }
-
-    @Test
-    public void testToString() throws Exception {
-        AtNotification knownCode = new AtNotification(GENERAL_FAILURE_POST_CHALLENGE);
-        AtNotification unknownCode = new AtNotification(UNKNOWN_CODE);
-
-        assertNotNull(knownCode.toString());
-        assertNotNull(unknownCode.toString());
-        assertNotEquals(knownCode.toString(), unknownCode.toString());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtPaddingTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtPaddingTest.java
deleted file mode 100644
index d310d50..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtPaddingTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PADDING;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_PADDING;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_PADDING_INVALID_PADDING;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAtPaddingException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPadding;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtPaddingTest {
-    private static final int EXPECTED_LENGTH = 8;
-
-    private EapSimAkaAttributeFactory mAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mAttributeFactory = new EapSimAkaAttributeFactory() {};
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_PADDING);
-        EapSimAkaAttribute result = mAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtPadding);
-        AtPadding atPadding = (AtPadding) result;
-        assertEquals(EAP_AT_PADDING, atPadding.attributeType);
-        assertEquals(EXPECTED_LENGTH, atPadding.lengthInBytes);
-    }
-
-    @Test
-    public void testDecodeInvalidPadding() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_PADDING_INVALID_PADDING);
-        try {
-            mAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAtPaddingException for nonzero padding bytes");
-        } catch (EapSimAkaInvalidAtPaddingException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtPadding atPadding = new AtPadding(EXPECTED_LENGTH);
-
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-        atPadding.encode(result);
-
-        assertFalse(result.hasRemaining());
-        assertArrayEquals(AT_PADDING, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandAkaTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandAkaTest.java
deleted file mode 100644
index bdffdda..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandAkaTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_AKA;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_AKA_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtRandAkaTest {
-    private EapAkaAttributeFactory mEapAkaAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RAND_AKA);
-        EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtRandAka atRandAka = (AtRandAka) result;
-        assertEquals(EAP_AT_RAND, atRandAka.attributeType);
-        assertEquals(AT_RAND_AKA.length, atRandAka.lengthInBytes);
-        assertArrayEquals(RAND_1_BYTES, atRandAka.rand);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RAND_AKA_INVALID_LENGTH);
-        try {
-            mEapAkaAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_RAND_AKA.length);
-        atRandAka.encode(result);
-        assertArrayEquals(AT_RAND_AKA, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandSimTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandSimTest.java
deleted file mode 100644
index 7456be6..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtRandSimTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_SIM;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_SIM_DUPLICATE_RANDS;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RAND_SIM_INVALID_NUM_RANDS;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimInvalidAtRandException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim;
-import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtRandSimTest {
-    private static final int EXPECTED_NUM_RANDS = 2;
-
-    private EapSimAttributeFactory mEapSimAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapSimAttributeFactory = EapSimAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RAND_SIM);
-        EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtRandSim);
-        AtRandSim atRandSim = (AtRandSim) result;
-        assertEquals(EAP_AT_RAND, atRandSim.attributeType);
-        assertEquals(AT_RAND_SIM.length, atRandSim.lengthInBytes);
-        assertEquals(EXPECTED_NUM_RANDS, atRandSim.rands.size());
-        assertArrayEquals(hexStringToByteArray(RAND_1), atRandSim.rands.get(0));
-        assertArrayEquals(hexStringToByteArray(RAND_2), atRandSim.rands.get(1));
-    }
-
-    @Test
-    public void testDecodeInvalidNumRands() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RAND_SIM_INVALID_NUM_RANDS);
-        try {
-            mEapSimAttributeFactory.getAttribute(input);
-            fail("Expected EapSimInvalidAtRandException for invalid number of RANDs");
-        } catch (EapSimInvalidAtRandException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeDuplicateRands() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RAND_SIM_DUPLICATE_RANDS);
-        try {
-            mEapSimAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for duplicate RANDs");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        byte[][] expectedRands = new byte[][] {
-                hexStringToByteArray(RAND_1),
-                hexStringToByteArray(RAND_2)
-        };
-        AtRandSim atRandSim = new AtRandSim(AT_RAND_SIM.length, expectedRands);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_RAND_SIM.length);
-        atRandSim.encode(result);
-        assertArrayEquals(AT_RAND_SIM, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtResTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtResTest.java
deleted file mode 100644
index 34c2ff3..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtResTest.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES_INVALID_RES_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES_LONG_RES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_RES_SHORT_RES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapAkaAttributeFactory;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRes;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtResTest {
-    private EapAkaAttributeFactory mEapAkaAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapAkaAttributeFactory = EapAkaAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RES);
-        EapSimAkaAttribute result = mEapAkaAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        AtRes atRes = (AtRes) result;
-        assertEquals(EAP_AT_RES, atRes.attributeType);
-        assertEquals(AT_RES.length, atRes.lengthInBytes);
-        assertArrayEquals(RES_BYTES, atRes.res);
-    }
-
-    @Test
-    public void testDecodeInvalidResLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RES_INVALID_RES_LENGTH);
-        try {
-            mEapAkaAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid RES length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeShortResLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RES_SHORT_RES);
-        try {
-            mEapAkaAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for too short RES");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeLongResLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_RES_LONG_RES);
-        try {
-            mEapAkaAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for too long RES");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtRes atRes = new AtRes(AT_RES.length, RES_BYTES);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_RES.length);
-        atRes.encode(result);
-        assertArrayEquals(AT_RES, result.array());
-    }
-
-    @Test
-    public void testGetAtRes() throws Exception {
-        AtRes atRes = AtRes.getAtRes(RES_BYTES);
-
-        ByteBuffer result = ByteBuffer.allocate(AT_RES.length);
-        atRes.encode(result);
-        assertArrayEquals(AT_RES, result.array());
-    }
-
-    @Test
-    public void testIsValidResLen() {
-        // valid RES length: 4 <= RES length <= 16
-        assertTrue(AtRes.isValidResLen(5));
-        assertFalse(AtRes.isValidResLen(0));
-        assertFalse(AtRes.isValidResLen(20));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtSelectedVersionTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtSelectedVersionTest.java
deleted file mode 100644
index 659fe9a..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtSelectedVersionTest.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_SELECTED_VERSION;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_SELECTED_VERSION;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_SELECTED_VERSION_INVALID_LENGTH;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtSelectedVersion;
-import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class AtSelectedVersionTest {
-    private static final int EXPECTED_LENGTH = 4;
-    private static final int EXPECTED_VERSION = 1;
-
-    private EapSimAttributeFactory mEapSimAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapSimAttributeFactory = EapSimAttributeFactory.getInstance();
-    }
-
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_SELECTED_VERSION);
-        EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtSelectedVersion);
-        AtSelectedVersion atSelectedVersion = (AtSelectedVersion) result;
-        assertEquals(EAP_AT_SELECTED_VERSION, atSelectedVersion.attributeType);
-        assertEquals(EXPECTED_LENGTH, atSelectedVersion.lengthInBytes);
-        assertEquals(EXPECTED_VERSION, atSelectedVersion.selectedVersion);
-    }
-
-    @Test
-    public void testDecodeInvalidLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_SELECTED_VERSION_INVALID_LENGTH);
-        try {
-            mEapSimAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid actual list length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtSelectedVersion atSelectedVersion = new AtSelectedVersion(
-                EXPECTED_LENGTH, EXPECTED_VERSION);
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atSelectedVersion.encode(result);
-        assertArrayEquals(AT_SELECTED_VERSION, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtVersionListTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtVersionListTest.java
deleted file mode 100644
index 96bb7ca..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/AtVersionListTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToInt;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_VERSION_LIST;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_VERSION_LIST_INVALID_LENGTH;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.VERSION;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-import com.android.internal.net.eap.message.simaka.EapSimAttributeFactory;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import java.util.List;
-
-public class AtVersionListTest {
-    private static final int EXPECTED_LENGTH = 8;
-    private static final List<Integer> EXPECTED_VERSIONS = Arrays.asList(1);
-
-    private EapSimAttributeFactory mEapSimAttributeFactory;
-
-    @Before
-    public void setUp() {
-        mEapSimAttributeFactory = EapSimAttributeFactory.getInstance();
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_VERSION_LIST);
-        EapSimAkaAttribute result = mEapSimAttributeFactory.getAttribute(input);
-
-        assertFalse(input.hasRemaining());
-        assertTrue(result instanceof AtVersionList);
-        AtVersionList atVersionList = (AtVersionList) result;
-        assertEquals(EAP_AT_VERSION_LIST, atVersionList.attributeType);
-        assertEquals(EXPECTED_LENGTH, atVersionList.lengthInBytes);
-        assertEquals(EXPECTED_VERSIONS, atVersionList.versions);
-    }
-
-    @Test
-    public void testDecodeInvalidActualLength() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(AT_VERSION_LIST_INVALID_LENGTH);
-        try {
-            mEapSimAttributeFactory.getAttribute(input);
-            fail("Expected EapSimAkaInvalidAttributeException for invalid actual list length");
-        } catch (EapSimAkaInvalidAttributeException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        AtVersionList atVersionList = new AtVersionList(EXPECTED_LENGTH, hexStringToInt(VERSION));
-        ByteBuffer result = ByteBuffer.allocate(EXPECTED_LENGTH);
-
-        atVersionList.encode(result);
-        assertArrayEquals(AT_VERSION_LIST, result.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapSimAkaAttributeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapSimAkaAttributeTest.java
deleted file mode 100644
index 98ea222..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapSimAkaAttributeTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class EapSimAkaAttributeTest {
-    private static final int EXPECTED_ATTRIBUTE_TYPE = 1;
-    private static final int EXPECTED_LENGTH_IN_BYTES = 4;
-    private static final int BUFFER_LENGTH = 2;
-    private static final int EXPECTED_LENGTH_ENCODED = 1;
-    private static final byte[] EXPECTED_ENCODING = {
-            (byte) EXPECTED_ATTRIBUTE_TYPE,
-            (byte) EXPECTED_LENGTH_ENCODED
-    };
-
-    @Test
-    public void testEncode() throws Exception {
-        EapSimAkaAttribute eapSimAkaAttribute = new EapSimAkaAttribute(
-                EXPECTED_ATTRIBUTE_TYPE,
-                EXPECTED_LENGTH_IN_BYTES) {
-            public void encode(ByteBuffer byteBuffer) {
-                encodeAttributeHeader(byteBuffer);
-            }
-        };
-
-        ByteBuffer result = ByteBuffer.allocate(BUFFER_LENGTH);
-        eapSimAkaAttribute.encode(result);
-        assertArrayEquals(EXPECTED_ENCODING, result.array());
-        assertFalse(result.hasRemaining());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapTestAttributeDefinitions.java b/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapTestAttributeDefinitions.java
deleted file mode 100644
index 60397e1..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/message/simaka/attributes/EapTestAttributeDefinitions.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.message.simaka.attributes;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-
-/**
- * EapTestAttributeDefinitions provides byte[] encodings of commonly used EAP Messages.
- *
- * @ee <a href="https://tools.ietf.org/html/rfc4186#section-10">RFC 4186, EAP-SIM Authentication,
- * Section 10</a>
- * @see <a href="https://tools.ietf.org/html/rfc4187#section-10">RFC 4187, EAP-AKA Authentication,
- * Section 10</a>
- */
-public class EapTestAttributeDefinitions {
-    public static final String VERSION = "0001";
-    public static final String AT_VERSION_LIST_DATA = "0002" + VERSION + "0000";
-    public static final byte[] AT_VERSION_LIST =
-            hexStringToByteArray("0F02" + AT_VERSION_LIST_DATA);
-    public static final byte[] AT_SELECTED_VERSION = hexStringToByteArray("10010001");
-    public static final String NONCE_MT_STRING = "0123456789ABCDEFFEDCBA9876543210";
-    public static final byte[] NONCE_MT = hexStringToByteArray(NONCE_MT_STRING);
-    public static final byte[] AT_NONCE_MT = hexStringToByteArray("07050000" + NONCE_MT_STRING);
-    public static final byte[] AT_PERMANENT_ID_REQ = hexStringToByteArray("0A010000");
-    public static final byte[] AT_ANY_ID_REQ = hexStringToByteArray("0D010000");
-    public static final byte[] AT_FULL_AUTH_ID_REQ = hexStringToByteArray("11010000");
-
-    // Identity = "test1@android.net"
-    public static final String IDENTITY_STRING = "746573743140616E64726F69642E6E6574";
-    public static final byte[] IDENTITY = hexStringToByteArray(IDENTITY_STRING);
-    public static final byte[] AT_IDENTITY =
-            hexStringToByteArray("0E060011" + IDENTITY_STRING + "000000");
-    public static final String RAND_1 = "00112233445566778899AABBCCDDEEFF";
-    public static final byte[] RAND_1_BYTES = hexStringToByteArray(RAND_1);
-    public static final String RAND_2 = "FFEEDDCCBBAA99887766554433221100";
-    public static final byte[] RAND_2_BYTES = hexStringToByteArray(RAND_2);
-    public static final byte[] AT_RAND_SIM = hexStringToByteArray("01090000" + RAND_1 + RAND_2);
-    public static final byte[] AT_RAND_AKA = hexStringToByteArray("01050000" + RAND_1);
-    public static final byte[] AT_PADDING = hexStringToByteArray("0602000000000000");
-    public static final String MAC = "112233445566778899AABBCCDDEEFF11";
-    public static final byte[] MAC_BYTES = hexStringToByteArray(MAC);
-    public static final byte[] AT_MAC = hexStringToByteArray("0B050000" + MAC);
-    public static final String COUNTER = "000A";
-    public static final int COUNTER_INT = Integer.parseInt(COUNTER, 16 /* radix */);
-    public static final byte[] AT_COUNTER = hexStringToByteArray("1301" + COUNTER);
-    public static final byte[] AT_COUNTER_TOO_SMALL = hexStringToByteArray("14010000");
-    public static final String NONCE_S = "0123456789ABCDEFFEDCBA9876543210";
-    public static final byte[] AT_NONCE_S = hexStringToByteArray("15050000" + NONCE_S);
-    public static final String NOTIFICATION_CODE = "8000";
-    public static final byte[] AT_NOTIFICATION = hexStringToByteArray("0C01" + NOTIFICATION_CODE);
-    public static final String ERROR_CODE = "0001";
-    public static final byte[] AT_CLIENT_ERROR_CODE = hexStringToByteArray("1601" + ERROR_CODE);
-    public static final String AUTN = "0123456789ABCDEFFEDCBA9876543210";
-    public static final byte[] AUTN_BYTES = hexStringToByteArray(AUTN);
-    public static final byte[] AT_AUTN = hexStringToByteArray("02050000" + AUTN);
-    public static final String RES = "1122334455";
-    public static final byte[] RES_BYTES = hexStringToByteArray(RES);
-    public static final byte[] AT_RES = hexStringToByteArray("03030028" + RES + "000000");
-    public static final String AUTS = "112233445566778899AABBCCDDEE";
-    public static final byte[] AUTS_BYTES = hexStringToByteArray(AUTS);
-    public static final byte[] AT_AUTS = hexStringToByteArray("0404" + AUTS);
-    public static final byte[] AT_BIDDING_SUPPORTS_AKA_PRIME = hexStringToByteArray("88018000");
-    public static final byte[] AT_BIDDING_DOES_NOT_SUPPORT_AKA_PRIME =
-            hexStringToByteArray("88010000");
-
-    // Network Name = "android.net"
-    public static final String NETWORK_NAME_HEX = "616E64726F69642E6E6574";
-    public static final byte[] NETWORK_NAME_BYTES = hexStringToByteArray(NETWORK_NAME_HEX);
-    public static final byte[] AT_KDF_INPUT =
-            hexStringToByteArray("1704000B" + NETWORK_NAME_HEX + "00");
-    public static final byte[] AT_KDF_INPUT_EMPTY_NETWORK_NAME = hexStringToByteArray("17010000");
-    public static final int KDF_VERSION = 1;
-    public static final byte[] AT_KDF = hexStringToByteArray("18010001");
-
-    public static final byte[] AT_VERSION_LIST_INVALID_LENGTH = hexStringToByteArray("0F020003");
-    public static final byte[] AT_SELECTED_VERSION_INVALID_LENGTH =
-            hexStringToByteArray("10020001");
-    public static final byte[] AT_NONCE_INVALID_LENGTH =
-            hexStringToByteArray("07060000" + NONCE_MT_STRING);
-    public static final byte[] PERMANENT_ID_INVALID_LENGTH = hexStringToByteArray("0A020000");
-    public static final byte[] ANY_ID_INVALID_LENGTH = hexStringToByteArray("0D020000");
-    public static final byte[] FULL_AUTH_ID_INVALID_LENGTH = hexStringToByteArray("11020000");
-    public static final byte[] AT_RAND_SIM_INVALID_NUM_RANDS =
-            hexStringToByteArray("01050000" + RAND_1);
-    public static final byte[] AT_RAND_SIM_DUPLICATE_RANDS =
-            hexStringToByteArray("01090000" + RAND_1 + RAND_1);
-    public static final byte[] AT_RAND_AKA_INVALID_LENGTH = hexStringToByteArray("01010000");
-    public static final byte[] AT_PADDING_INVALID_PADDING = hexStringToByteArray("0601FFFF");
-    public static final byte[] AT_MAC_INVALID_LENGTH = hexStringToByteArray("0B06");
-    public static final byte[] AT_COUNTER_INVALID_LENGTH = hexStringToByteArray("1302");
-    public static final byte[] AT_COUNTER_TOO_SMALL_INVALID_LENGTH = hexStringToByteArray("1402");
-    public static final byte[] AT_NONCE_S_INVALID_LENGTH = hexStringToByteArray("1506");
-    public static final byte[] AT_NOTIFICATION_INVALID_LENGTH = hexStringToByteArray("0C02");
-    public static final byte[] AT_NOTIFICATION_INVALID_STATE = hexStringToByteArray("0C01C000");
-    public static final byte[] AT_CLIENT_ERROR_CODE_INVALID_LENGTH = hexStringToByteArray("1602");
-    public static final byte[] AT_AUTN_INVALID_LENGTH = hexStringToByteArray("02010000");
-    public static final byte[] AT_RES_INVALID_RES_LENGTH =
-            hexStringToByteArray("030300241122334450000000");
-    public static final byte[] AT_RES_SHORT_RES =
-            hexStringToByteArray("0302000811000000");
-    public static final byte[] AT_RES_LONG_RES =
-            hexStringToByteArray("0306008800112233445566778899AABBCCDDEEFF11000000");
-    public static final byte[] AT_AUTS_INVALID_LENGTH = hexStringToByteArray("03010000");
-    public static final byte[] AT_KDF_INVALID_LENGTH = hexStringToByteArray("18020001");
-    public static final byte[] AT_BIDDING_INVALID_LENGTH = hexStringToByteArray("88020000");
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/CreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/CreatedStateTest.java
deleted file mode 100644
index a452fa6..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/CreatedStateTest.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_IDENTITY_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.statemachine.EapStateMachine.IdentityState;
-import com.android.internal.net.eap.statemachine.EapStateMachine.MethodState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class CreatedStateTest extends EapStateTest {
-    private EapStateMachine mEapStateMachineSpy;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mEapStateMachineSpy = spy(mEapStateMachine);
-        mEapState = mEapStateMachineSpy.new CreatedState();
-    }
-
-    @Test
-    public void testProcessIdentityRequest() {
-        mEapState.process(EAP_REQUEST_IDENTITY_PACKET);
-
-        verify(mEapStateMachineSpy).transitionAndProcess(
-                any(IdentityState.class), eq(EAP_REQUEST_IDENTITY_PACKET));
-    }
-
-    @Test
-    public void testProcessNotificationRequest() {
-        EapResult eapResult = mEapState.process(EAP_REQUEST_NOTIFICATION_PACKET);
-
-        // state shouldn't change after Notification request
-        assertTrue(eapResult instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) eapResult;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-        verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any());
-    }
-
-    @Test
-    public void testProcessSimStart() {
-        mEapState.process(EAP_REQUEST_SIM_START_PACKET);
-
-        // EapStateMachine should change to MethodState for method-type packet
-        verify(mEapStateMachineSpy).transitionAndProcess(
-                any(MethodState.class), eq(EAP_REQUEST_SIM_START_PACKET));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaChallengeStateTest.java
deleted file mode 100644
index b07d1ff..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaChallengeStateTest.java
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CK_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_AUTHENTICATION_REJECT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CHALLENGE_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_SYNCHRONIZATION_FAILURE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_UICC_RESP_INVALID_TAG;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_UICC_RESP_SUCCESS_BASE_64;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_UICC_RESP_SYNCHRONIZE_BASE_64;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IK_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTS_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.simaka.EapAkaInvalidAuthenticationResponse;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtBidding;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState.RandChallengeResult;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class EapAkaChallengeStateTest extends EapAkaStateTest {
-    private ChallengeState mChallengeState;
-
-    // '10' + RAND_1_BYTES + '10' + AUTN_BYTES
-    private static final String BASE_64_CHALLENGE =
-            "EAARIjNEVWZ3iJmqu8zd7v8QASNFZ4mrze/+3LqYdlQyEA==";
-
-    /**
-     * Process to generate MAC:
-     *
-     * message =    01100044 | EAP-Request, ID, length in bytes
-     *              17010000 | EAP-AKA, AKA-Challenge, padding
-     *              0105000000112233445566778899AABBCCDDEEFF | AT_RAND
-     *              020500000123456789ABCDEFFEDCBA9876543210 | AT_AUTN
-     *              0B05000000000000000000000000000000000000 | AT_MAC (zeroed out)
-     *
-     * MK = SHA-1(Identity | IK | CK)
-     * K_encr, K_aut, MSK, EMSK = PRF(MK)
-     * MAC = HMAC-SHA-1(K_aut, message)
-     */
-    private static final byte[] REQUEST_MAC_BYTES =
-            hexStringToByteArray("3EB97A1D0E62894FD0DA384D24D8983C");
-
-    /**
-     * message =    01100048 | EAP-Request, ID, length in bytes
-     *              17010000 | EAP-AKA, AKA-Challenge, padding
-     *              0105000000112233445566778899AABBCCDDEEFF | AT_RAND
-     *              020500000123456789ABCDEFFEDCBA9876543210 | AT_AUTN
-     *              88018000 | AT_BIDDING
-     *              0B05000000000000000000000000000000000000 | AT_MAC (zeroed out)
-     */
-    private static final byte[] BIDDING_DOWN_MAC =
-            hexStringToByteArray("9CB543894A5EFDC32DF6A6CE1AB0E01A");
-
-    @Before
-    public void setUp() {
-        super.setUp();
-
-        mChallengeState = mEapAkaMethodStateMachine.new ChallengeState(IDENTITY);
-        mEapAkaMethodStateMachine.transitionTo(mChallengeState);
-    }
-
-    @Test
-    public void testProcessIncorrectEapMethodType() throws Exception {
-        EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapResult result = mChallengeState.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessSuccess() throws Exception {
-        System.arraycopy(MSK, 0, mEapAkaMethodStateMachine.mMsk, 0, MSK.length);
-        System.arraycopy(EMSK, 0, mEapAkaMethodStateMachine.mEmsk, 0, EMSK.length);
-
-        mChallengeState.mHadSuccessfulChallenge = true;
-        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-
-        EapSuccess eapSuccess = (EapSuccess) mEapAkaMethodStateMachine.process(input);
-        assertArrayEquals(MSK, eapSuccess.msk);
-        assertArrayEquals(EMSK, eapSuccess.emsk);
-        assertTrue(mEapAkaMethodStateMachine.getState() instanceof FinalState);
-    }
-
-    @Test
-    public void testProcessInvalidSuccess() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-
-        EapError eapError = (EapError) mEapAkaMethodStateMachine.process(input);
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessFailure() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
-        EapResult result = mEapAkaMethodStateMachine.process(input);
-        assertTrue(mEapAkaMethodStateMachine.getState() instanceof FinalState);
-
-        assertTrue(result instanceof EapFailure);
-    }
-
-    @Test
-    public void testProcessMissingAtRand() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(REQUEST_MAC_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(EAP_AKA_CHALLENGE, Arrays.asList(atAutn, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessMissingAtAutn() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtMac atMac = new AtMac(REQUEST_MAC_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessMissingAtMac() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atAutn)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testRandChallengeResultConstructor() throws Exception {
-        RandChallengeResult result =
-                mChallengeState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES);
-        assertArrayEquals(RES_BYTES, result.res);
-        assertArrayEquals(IK_BYTES, result.ik);
-        assertArrayEquals(CK_BYTES, result.ck);
-        assertNull(result.auts);
-
-        result = mChallengeState.new RandChallengeResult(AUTS_BYTES);
-        assertArrayEquals(AUTS_BYTES, result.auts);
-        assertNull(result.res);
-        assertNull(result.ik);
-        assertNull(result.ck);
-
-        try {
-            mChallengeState.new RandChallengeResult(new byte[0], IK_BYTES, CK_BYTES);
-            fail("Expected EapSimAkaInvalidLengthException for invalid RES length");
-        } catch (EapSimAkaInvalidLengthException ex) {
-        }
-
-        try {
-            mChallengeState.new RandChallengeResult(RES_BYTES, new byte[0], CK_BYTES);
-            fail("Expected EapSimAkaInvalidLengthException for invalid IK length");
-        } catch (EapSimAkaInvalidLengthException ex) {
-        }
-
-        try {
-            mChallengeState.new RandChallengeResult(RES_BYTES, IK_BYTES, new byte[0]);
-            fail("Expected EapSimAkaInvalidLengthException for invalid CK length");
-        } catch (EapSimAkaInvalidLengthException ex) {
-        }
-
-        try {
-            mChallengeState.new RandChallengeResult(new byte[0]);
-            fail("Expected EapSimAkaInvalidLengthException for invalid AUTS length");
-        } catch (EapSimAkaInvalidLengthException ex) {
-        }
-    }
-
-    @Test
-    public void testProcessIccAuthenticationNullResponse() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(REQUEST_MAC_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE))
-                .thenReturn(null);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_AUTHENTICATION_REJECT, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessIccAuthenticationInvalidTag() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(REQUEST_MAC_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE))
-                .thenReturn(EAP_AKA_UICC_RESP_INVALID_TAG);
-
-        EapError eapError = (EapError) mEapAkaMethodStateMachine.process(eapMessage);
-        assertTrue(eapError.cause instanceof EapAkaInvalidAuthenticationResponse);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessIccAuthenticationSynchronizeTag() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(REQUEST_MAC_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE))
-                .thenReturn(EAP_AKA_UICC_RESP_SYNCHRONIZE_BASE_64);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_SYNCHRONIZATION_FAILURE, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessValidChallenge() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(REQUEST_MAC_BYTES);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(
-                                EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atAutn, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE))
-                .thenReturn(EAP_AKA_UICC_RESP_SUCCESS_BASE_64);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_CHALLENGE_RESPONSE, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessBiddingDownAttack() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtBidding atBidding = new AtBidding(true);
-        AtMac atMac = new AtMac(BIDDING_DOWN_MAC);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atBidding, atMac)));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getIccAuthentication(
-                TelephonyManager.APPTYPE_USIM,
-                TelephonyManager.AUTHTYPE_EAP_AKA,
-                BASE_64_CHALLENGE))
-                .thenReturn(EAP_AKA_UICC_RESP_SUCCESS_BASE_64);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_AUTHENTICATION_REJECT, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaCreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaCreatedStateTest.java
deleted file mode 100644
index 6e100db..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaCreatedStateTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.IdentityState;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-
-import org.junit.Test;
-
-import java.util.LinkedHashMap;
-
-public class EapAkaCreatedStateTest extends EapAkaStateTest {
-    @Test
-    public void testProcessTransitionToIdentityState() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // Don't actually need any attributes in the attributeMap, since we only care about the
-        // state transition here.
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaTypeData(EAP_AKA_IDENTITY, new LinkedHashMap<>()));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mEapAkaMethodStateMachine.process(eapMessage);
-
-        assertTrue(mEapAkaMethodStateMachine.getState() instanceof IdentityState);
-
-        // decoded in CreatedState and IdentityState
-        verify(mMockEapAkaTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-    }
-
-    @Test
-    public void testProcessTransitionToChallengeState() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // Don't actually need any attributes in the attributeMap, since we only care about the
-        // state transition here.
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaTypeData(EAP_AKA_CHALLENGE, new LinkedHashMap<>()));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mEapAkaMethodStateMachine.process(eapMessage);
-
-        ChallengeState challengeState = (ChallengeState) mEapAkaMethodStateMachine.getState();
-        assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity);
-
-        // decoded in CreatedState and ChallengeState
-        verify(mMockEapAkaTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-    }
-
-    @Test
-    public void testProcessSuccess() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-        EapResult result = mEapAkaMethodStateMachine.process(input);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessFailure() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
-        EapResult result = mEapAkaMethodStateMachine.process(input);
-        assertTrue(mEapAkaMethodStateMachine.getState() instanceof FinalState);
-
-        assertTrue(result instanceof EapFailure);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaIdentityStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaIdentityStateTest.java
deleted file mode 100644
index 20175f9..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaIdentityStateTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_IDENTITY_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.IdentityState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-
-public class EapAkaIdentityStateTest extends EapAkaStateTest {
-    private IdentityState mIdentityState;
-
-    @Before
-    public void setUp() {
-        super.setUp();
-
-        mIdentityState = mEapAkaMethodStateMachine.new IdentityState();
-        mEapAkaMethodStateMachine.transitionTo(mIdentityState);
-    }
-
-    @Test
-    public void testProcessIdentityRequest() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq())));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_IDENTITY_RESPONSE, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager).getSubscriberId();
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessWithoutIdentityRequestAttributes() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaTypeData(EAP_AKA_IDENTITY, new LinkedHashMap<>()));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessMultipleIdentityRequestAttributes() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(
-                                EAP_AKA_IDENTITY,
-                                Arrays.asList(new AtAnyIdReq(), new AtPermanentIdReq())));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessImsiUnavailable() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq())));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(null);
-
-        EapError eapError = (EapError) mEapAkaMethodStateMachine.process(eapMessage);
-        assertTrue(eapError.cause instanceof EapSimAkaIdentityUnavailableException);
-
-        verify(mMockEapAkaTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager).getSubscriberId();
-        verifyNoMoreInteractions(mMockEapAkaTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessTransitionToChallengeState() throws Exception {
-        // transition to IdentityState so we can verify the transition to ChallengeState
-        IdentityState identityState = mEapAkaMethodStateMachine.new IdentityState();
-        mEapAkaMethodStateMachine.transitionTo(identityState);
-
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // Don't actually need any attributes in the attributeMap, since we only care about the
-        // state transition here.
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaTypeData(EAP_AKA_CHALLENGE, new LinkedHashMap<>()));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mEapAkaMethodStateMachine.process(eapMessage);
-
-        assertTrue(mEapAkaMethodStateMachine.getState() instanceof ChallengeState);
-
-        // decoded in IdentityState and ChallengeState
-        verify(mMockEapAkaTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachineTest.java
deleted file mode 100644
index db2899b..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaMethodStateMachineTest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_NOTIFICATION_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.CreatedState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class EapAkaMethodStateMachineTest {
-    private static final int SUB_ID = 1;
-    private static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566");
-
-    // EAP-Identity = hex("test@android.net")
-    protected static final byte[] EAP_IDENTITY_BYTES =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    protected TelephonyManager mMockTelephonyManager;
-    private EapAkaTypeDataDecoder mMockEapAkaTypeDataDecoder;
-
-    private EapAkaConfig mEapAkaConfig = new EapAkaConfig(SUB_ID, APPTYPE_USIM);
-    private EapAkaMethodStateMachine mEapAkaMethodStateMachine;
-
-    @Before
-    public void setUp() {
-        mMockTelephonyManager = mock(TelephonyManager.class);
-        mMockEapAkaTypeDataDecoder = mock(EapAkaTypeDataDecoder.class);
-
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-
-        mEapAkaMethodStateMachine =
-                new EapAkaMethodStateMachine(
-                        mMockTelephonyManager,
-                        EAP_IDENTITY_BYTES,
-                        mEapAkaConfig,
-                        mMockEapAkaTypeDataDecoder,
-                        false);
-
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-    }
-
-    @Test
-    public void testEapAkaMethodStateMachineStartState() {
-        assertTrue(mEapAkaMethodStateMachine.getState() instanceof CreatedState);
-    }
-
-    @Test
-    public void testGetEapMethod() {
-        assertEquals(EAP_TYPE_AKA, mEapAkaMethodStateMachine.getEapMethod());
-    }
-
-    @Test
-    public void testEapAkaFailsOnMultipleAkaNotifications() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // First EAP-AKA/Notification
-        EapAkaTypeData notificationTypeData =
-                new EapAkaTypeData(
-                        EAP_AKA_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE)));
-        DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(notificationTypeData);
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_NOTIFICATION_RESPONSE, eapResponse.packet);
-        verify(mMockEapAkaTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-
-        // Transition to IdentityState
-        decodeResult =
-                new DecodeResult<>(
-                        new EapAkaTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq())));
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI);
-
-        eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertFalse(
-                "EAP-Request/AKA-Identity returned a Client-Error response",
-                Arrays.equals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet));
-
-        // decoded in: previous 1 time + in CreatedState and IdentityState
-        verify(mMockEapAkaTypeDataDecoder, times(3)).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager).getSubscriberId();
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-
-        // Second EAP-AKA/Notification
-        decodeResult = new DecodeResult<>(notificationTypeData);
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapError eapError = (EapError) mEapAkaMethodStateMachine.process(eapMessage);
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-
-        // decoded previous 3 times + 1
-        verify(mMockEapAkaTypeDataDecoder, times(4)).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeChallengeStateTest.java
deleted file mode 100644
index 731eb6b..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeChallengeStateTest.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CK_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_AUTHENTICATION_REJECT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IK_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AUTN_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.MAC_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RES_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig;
-
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAutn;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdf;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtKdfInput;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandAka;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.ChallengeState.RandChallengeResult;
-import com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class EapAkaPrimeChallengeStateTest extends EapAkaPrimeStateTest {
-    private static final String SERVER_NETWORK_NAME_STRING = "foo:bar:buzz";
-    private static final byte[] SERVER_NETWORK_NAME =
-            SERVER_NETWORK_NAME_STRING.getBytes(StandardCharsets.UTF_8);
-    private static final String INCORRECT_NETWORK_NAME = "foo:buzz";
-    private static final byte[] INCORRECT_SERVER_NETWORK_NAME =
-            INCORRECT_NETWORK_NAME.getBytes(StandardCharsets.UTF_8);
-    private static final int VALID_KDF = 1;
-    private static final int INVALID_KDF = 10;
-
-    private static final byte[] EXPECTED_CK_IK_PRIME =
-            hexStringToByteArray(
-                    "A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6");
-    private static final byte[] K_ENCR = hexStringToByteArray("15a5bb098528210cde9e8d4a1bd63850");
-    private static final byte[] K_AUT =
-            hexStringToByteArray(
-                    "957b3d518ac9ff028f2cc5177fedad841f5f812cb06e2b88aceaa98129680f35");
-    private static final byte[] K_RE =
-            hexStringToByteArray(
-                    "3c15cf7112935a8170d0904622ecbb67c49dcba5d50814bdd81958e045e42f9c");
-    private static final byte[] MSK =
-            hexStringToByteArray(
-                    "1dcca0351a58d2b858e6cf2380551470d67cc8749d1915409793171abd360118"
-                            + "e3ae271bf088ca5a41bb1b9b8f7028bcba888298bfbf64d7b8a4f53a6c2cdf18");
-    private static final byte[] EMSK =
-            hexStringToByteArray(
-                    "a5e6b66a9cb2daa9fe3867d41145848e7bf50d749bfd1bb0d090257402e6a555"
-                            + "da6d538e76b71e9f80afe60709965a63a355bdccc4e3a8b358e098e41545fa67");
-
-    private ChallengeState mState;
-
-    @Before
-    public void setUp() {
-        super.setUp();
-
-        mState = mStateMachine.new ChallengeState();
-        mStateMachine.transitionTo(mState);
-    }
-
-    @Test
-    public void testTransitionWithEapIdentity() throws Exception {
-        mStateMachine.transitionTo(mStateMachine.new CreatedState());
-
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>()));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mStateMachine.process(eapMessage);
-
-        ChallengeState challengeState = (ChallengeState) mStateMachine.getState();
-        assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity);
-
-        // decode() is called in CreatedState and ChallengeState
-        verify(mMockTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-
-    @Test
-    public void testTransitionWithEapAkaPrimeIdentity() throws Exception {
-        mStateMachine.transitionTo(mStateMachine.new CreatedState());
-
-        // Process AKA' Identity Request
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaPrimeTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq())));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI);
-
-        EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_PRIME_IDENTITY_RESPONSE, eapResponse.packet);
-
-        // decode() is called in CreatedState and IdentityState
-        verify(mMockTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager).getSubscriberId();
-
-        // Process AKA' Challenge Request
-        decodeResult =
-                new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>()));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mStateMachine.process(eapMessage);
-
-        ChallengeState challengeState = (ChallengeState) mStateMachine.getState();
-        assertArrayEquals(EAP_AKA_PRIME_IDENTITY_BYTES, challengeState.mIdentity);
-
-        // decode() called again in IdentityState and ChallengeState
-        verify(mMockTypeDataDecoder, times(4)).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessMissingAtKdf() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(MAC_BYTES);
-        AtKdfInput atKdfInput = new AtKdfInput(0, SERVER_NETWORK_NAME);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaPrimeTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atMac, atKdfInput)));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet);
-        verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessMissingAtKdfInput() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(MAC_BYTES);
-        AtKdf atKdf = new AtKdf(VALID_KDF);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaPrimeTypeData(
-                                EAP_AKA_CHALLENGE, Arrays.asList(atRandAka, atAutn, atMac, atKdf)));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet);
-        verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessUnsupportedKdf() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(MAC_BYTES);
-        AtKdfInput atKdfInput = new AtKdfInput(0, SERVER_NETWORK_NAME);
-        AtKdf atKdf = new AtKdf(INVALID_KDF);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaPrimeTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf)));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet);
-        verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessIncorrectNetworkName() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(MAC_BYTES);
-        AtKdfInput atKdfInput = new AtKdfInput(0, INCORRECT_SERVER_NETWORK_NAME);
-        AtKdf atKdf = new AtKdf(VALID_KDF);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaPrimeTypeData(
-                                EAP_AKA_CHALLENGE,
-                                Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf)));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_PRIME_AUTHENTICATION_REJECT, eapResponse.packet);
-        verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessIncorrectNetworkNameIsIgnored() throws Exception {
-        // Create state machine with configs allowing invalid network name to be ignored
-        mStateMachine =
-                new EapAkaPrimeMethodStateMachine(
-                        mMockContext,
-                        EAP_IDENTITY_BYTES,
-                        new EapSessionConfig.EapAkaPrimeConfig(
-                                SUB_ID, APPTYPE_USIM, PEER_NETWORK_NAME, true),
-                        mMockTypeDataDecoder);
-        mState = mStateMachine.new ChallengeState();
-        mStateMachine.transitionTo(mState);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(MAC_BYTES);
-        AtKdfInput atKdfInput = new AtKdfInput(0, INCORRECT_SERVER_NETWORK_NAME);
-        AtKdf atKdf = new AtKdf(VALID_KDF);
-
-        EapAkaPrimeTypeData eapAkaPrimeTypeData =
-                new EapAkaPrimeTypeData(
-                        EAP_AKA_CHALLENGE,
-                        Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf));
-        assertTrue(
-                "Incorrect network names should be ignored",
-                mState.isValidChallengeAttributes(eapAkaPrimeTypeData));
-    }
-
-    @Test
-    public void testHasMatchingNetworkNames() {
-        // "" should match anything
-        assertTrue(mState.hasMatchingNetworkNames("", SERVER_NETWORK_NAME_STRING));
-        assertTrue(mState.hasMatchingNetworkNames(SERVER_NETWORK_NAME_STRING, ""));
-
-        // "foo:bar" should match "foo:bar:buzz"
-        assertTrue(mState.hasMatchingNetworkNames(PEER_NETWORK_NAME, SERVER_NETWORK_NAME_STRING));
-        assertTrue(mState.hasMatchingNetworkNames(SERVER_NETWORK_NAME_STRING, PEER_NETWORK_NAME));
-
-        // "foo:buzz" shouldn't match "foo:bar:buzz"
-        assertFalse(
-                mState.hasMatchingNetworkNames(SERVER_NETWORK_NAME_STRING, INCORRECT_NETWORK_NAME));
-        assertFalse(
-                mState.hasMatchingNetworkNames(INCORRECT_NETWORK_NAME, SERVER_NETWORK_NAME_STRING));
-    }
-
-    @Test
-    public void testDeriveCkIkPrime() throws Exception {
-        RandChallengeResult randChallengeResult =
-                mState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES);
-        AtKdfInput atKdfInput =
-                new AtKdfInput(0, PEER_NETWORK_NAME.getBytes(StandardCharsets.UTF_8));
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-
-        // S = FC | Network Name | len(Network Name) | SQN ^ AK | len(SQN ^ AK)
-        //   = 20666F6F3A62617200070123456789AB0006
-        // K = CK | IK
-        //   = FFEEDDCCBBAA9988776655443322110000112233445566778899AABBCCDDEEFF
-        // CK' | IK' = HMAC-SHA256(K, S)
-        //           = A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6
-        byte[] result = mState.deriveCkIkPrime(randChallengeResult, atKdfInput, atAutn);
-        assertArrayEquals(EXPECTED_CK_IK_PRIME, result);
-    }
-
-    @Test
-    public void testGenerateAndPersistEapAkaKeys() throws Exception {
-        RandChallengeResult randChallengeResult =
-                mState.new RandChallengeResult(RES_BYTES, IK_BYTES, CK_BYTES);
-
-        AtRandAka atRandAka = new AtRandAka(RAND_1_BYTES);
-        AtAutn atAutn = new AtAutn(AUTN_BYTES);
-        AtMac atMac = new AtMac(MAC_BYTES);
-        AtKdfInput atKdfInput =
-                new AtKdfInput(0, PEER_NETWORK_NAME.getBytes(StandardCharsets.UTF_8));
-        AtKdf atKdf = new AtKdf(VALID_KDF);
-
-        EapAkaPrimeTypeData eapAkaPrimeTypeData =
-                new EapAkaPrimeTypeData(
-                        EAP_AKA_CHALLENGE,
-                        Arrays.asList(atRandAka, atAutn, atMac, atKdfInput, atKdf));
-
-        // CK' | IK' = A0B37E7C7E9CC4F37A5C0AAA55DC87BE51FDA70A9D8F37E62E23B15F1B3941E6
-        // data = "EAP-AKA'" | Identity
-        //      = 4541502D414B41277465737440616E64726F69642E6E6574
-        // prf+(CK' | IK', data) = T1 | T2 | T3 | T4 | T5 | T6 | T7
-        // T1 = 15a5bb098528210cde9e8d4a1bd63850957b3d518ac9ff028f2cc5177fedad84
-        // T2 = 1f5f812cb06e2b88aceaa98129680f353c15cf7112935a8170d0904622ecbb67
-        // T3 = c49dcba5d50814bdd81958e045e42f9c1dcca0351a58d2b858e6cf2380551470
-        // T4 = d67cc8749d1915409793171abd360118e3ae271bf088ca5a41bb1b9b8f7028bc
-        // T5 = ba888298bfbf64d7b8a4f53a6c2cdf18a5e6b66a9cb2daa9fe3867d41145848e
-        // T6 = 7bf50d749bfd1bb0d090257402e6a555da6d538e76b71e9f80afe60709965a63
-        // T7 = a355bdccc4e3a8b358e098e41545fa677897d8341c4a107a2343f393ec966181
-        // K_encr | K_aut | K_re | MSK | EMSK = prf+(CK' | IK', data)
-        assertNull(
-                mState.generateAndPersistEapAkaKeys(randChallengeResult, 0, eapAkaPrimeTypeData));
-        assertArrayEquals(K_ENCR, mStateMachine.mKEncr);
-        assertArrayEquals(K_AUT, mStateMachine.mKAut);
-        assertArrayEquals(K_RE, mStateMachine.mKRe);
-        assertArrayEquals(MSK, mStateMachine.mMsk);
-        assertArrayEquals(EMSK, mStateMachine.mEmsk);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeCreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeCreatedStateTest.java
deleted file mode 100644
index 90d0bf6..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeCreatedStateTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-
-public class EapAkaPrimeCreatedStateTest extends EapAkaPrimeStateTest {
-    @Test
-    public void testProcessTransitionToIdentityState() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // Don't actually need any attributes in the attributeMap, since we only care about the
-        // state transition here.
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_IDENTITY, new ArrayList<>()));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mStateMachine.process(eapMessage);
-
-        assertTrue(mStateMachine.getState() instanceof EapAkaMethodStateMachine.IdentityState);
-
-        // decoded in CreatedState and IdentityState
-        verify(mMockTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder);
-    }
-
-    @Test
-    public void testProcessTransitionToChallengeState() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // Don't actually need any attributes in the attributeMap, since we only care about the
-        // state transition here.
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>()));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mStateMachine.process(eapMessage);
-
-        ChallengeState challengeState = (ChallengeState) mStateMachine.getState();
-        assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity);
-
-        // decoded in CreatedState and ChallengeState
-        verify(mMockTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeIdentityStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeIdentityStateTest.java
deleted file mode 100644
index 73191fb..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeIdentityStateTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_IDENTITY_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_IDENTITY;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.ChallengeState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-public class EapAkaPrimeIdentityStateTest extends EapAkaPrimeStateTest {
-    @Before
-    public void setUp() {
-        super.setUp();
-
-        mStateMachine.transitionTo(mStateMachine.new IdentityState());
-    }
-
-    @Test
-    public void testProcessIdentityRequest() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapAkaPrimeTypeData(EAP_AKA_IDENTITY, Arrays.asList(new AtAnyIdReq())));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI);
-
-        EapResponse eapResponse = (EapResponse) mStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_PRIME_IDENTITY_RESPONSE, eapResponse.packet);
-
-        verify(mMockTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager).getSubscriberId();
-        verifyNoMoreInteractions(mMockTypeDataDecoder, mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessTransitionToChallengeState() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // Don't actually need any attributes in the attributeMap, since we only care about the
-        // state transition here.
-        DecodeResult<EapAkaTypeData> decodeResult =
-                new DecodeResult<>(new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, new ArrayList<>()));
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mStateMachine.process(eapMessage);
-
-        assertTrue(mStateMachine.getState() instanceof ChallengeState);
-
-        // decoded in IdentityState and ChallengeState
-        verify(mMockTypeDataDecoder, times(2)).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachineTest.java
deleted file mode 100644
index 125b323..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeMethodStateMachineTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_CHALLENGE;
-import static com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.K_AUT_LEN;
-import static com.android.internal.net.eap.statemachine.EapAkaPrimeMethodStateMachine.K_RE_LEN;
-import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.KEY_LEN;
-import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.SESSION_KEY_LENGTH;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.statemachine.EapAkaMethodStateMachine.CreatedState;
-
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class EapAkaPrimeMethodStateMachineTest extends EapAkaPrimeTest {
-    private static final String TAG = EapAkaPrimeMethodStateMachineTest.class.getSimpleName();
-    private static final byte[] K_AUT =
-            hexStringToByteArray(
-                    "000102030405060708090A0B0C0D0E0F000102030405060708090A0B0C0D0E0F");
-    private static final byte[] MAC = hexStringToByteArray("0322b08b59cae2df8f766162ac76f30b");
-
-    @Test
-    public void testEapAkaPrimeMethodStateMachineStartState() {
-        assertTrue(mStateMachine.getState() instanceof CreatedState);
-    }
-
-    @Test
-    public void testKeyLengths() {
-        assertEquals(KEY_LEN, mStateMachine.getKEncrLength());
-        assertEquals(K_AUT_LEN, mStateMachine.getKAutLength());
-        assertEquals(K_RE_LEN, mStateMachine.getKReLen());
-        assertEquals(SESSION_KEY_LENGTH, mStateMachine.getMskLength());
-        assertEquals(SESSION_KEY_LENGTH, mStateMachine.getEmskLength());
-    }
-
-    @Test
-    public void testIsValidMacUsesHmacSha256() throws Exception {
-        System.arraycopy(K_AUT, 0, mStateMachine.mKAut, 0, K_AUT.length);
-
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, new byte[0]);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapAkaPrimeTypeData eapAkaPrimeTypeData =
-                new EapAkaPrimeTypeData(EAP_AKA_CHALLENGE, Arrays.asList(new AtMac(MAC)));
-
-        assertTrue(mStateMachine.isValidMac(TAG, eapMessage, eapAkaPrimeTypeData, new byte[0]));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeStateTest.java
deleted file mode 100644
index 18fce26..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeStateTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA_PRIME;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-
-import org.junit.Test;
-
-public class EapAkaPrimeStateTest extends EapAkaPrimeTest {
-    protected static final String NOTIFICATION_MESSAGE = "test";
-
-    @Test
-    public void testProcessNotification() throws Exception {
-        EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes());
-        EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preNotification = (EapMethodState) mStateMachine.getState();
-
-        EapResult result = mStateMachine.process(notification);
-        assertEquals(preNotification, mStateMachine.getState());
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testProcessInvalidDecodeResult() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA_PRIME, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preProcess = (EapMethodState) mStateMachine.getState();
-
-        AtClientErrorCode atClientErrorCode = AtClientErrorCode.UNABLE_TO_PROCESS;
-        DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(atClientErrorCode);
-        when(mMockTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResult result = mStateMachine.process(eapMessage);
-        assertEquals(preProcess, mStateMachine.getState());
-        verify(mMockTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockTypeDataDecoder);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_AKA_PRIME_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-    }
-
-    @Test
-    public void testHandleEapFailure() throws Exception {
-        EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_FAILURE, ID_INT, null));
-        assertTrue(result instanceof EapFailure);
-        assertTrue(mStateMachine.getState() instanceof FinalState);
-    }
-
-    @Test
-    public void testHandleEapSuccess() throws Exception {
-        EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_SUCCESS, ID_INT, null));
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeTest.java
deleted file mode 100644
index 48371bb..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaPrimeTest.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig.EapAkaPrimeConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.message.simaka.EapAkaPrimeTypeData;
-
-import org.junit.Before;
-
-public class EapAkaPrimeTest {
-
-    // newtork name example in RFC 5448#3.1
-    protected static final int SUB_ID = 1;
-    protected static final String PEER_NETWORK_NAME = "foo:bar";
-    protected static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = false;
-    protected static final EapAkaPrimeConfig EAP_AKA_PRIME_CONFIG =
-            new EapAkaPrimeConfig(
-                    SUB_ID, APPTYPE_USIM, PEER_NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES);
-    protected static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566");
-
-    // EAP-Identity = hex("test@android.net")
-    protected static final byte[] EAP_IDENTITY_BYTES =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    protected Context mMockContext;
-    protected TelephonyManager mMockTelephonyManager;
-    protected EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder mMockTypeDataDecoder;
-
-    protected EapAkaPrimeMethodStateMachine mStateMachine;
-
-    @Before
-    public void setUp() {
-        mMockContext = mock(Context.class);
-        mMockTelephonyManager = mock(TelephonyManager.class);
-        mMockTypeDataDecoder = mock(EapAkaPrimeTypeData.EapAkaPrimeTypeDataDecoder.class);
-
-        when(mMockContext.getSystemService(eq(Context.TELEPHONY_SERVICE)))
-                .thenReturn(mMockTelephonyManager);
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-
-        mStateMachine =
-                new EapAkaPrimeMethodStateMachine(
-                        mMockContext,
-                        EAP_IDENTITY_BYTES,
-                        EAP_AKA_PRIME_CONFIG,
-                        mMockTypeDataDecoder);
-
-        verify(mMockContext).getSystemService(eq(Context.TELEPHONY_SERVICE));
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaStateTest.java
deleted file mode 100644
index 23b240b..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapAkaStateTest.java
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_AKA;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_NOTIFICATION_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.simaka.EapAkaTypeData.EAP_AKA_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig.EapAkaConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapAkaTypeData.EapAkaTypeDataDecoder;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-
-public class EapAkaStateTest {
-    protected static final int SUB_ID = 1;
-    protected static final String NOTIFICATION_MESSAGE = "test";
-    protected static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566");
-
-    // EAP-Identity = hex("test@android.net")
-    protected static final byte[] EAP_IDENTITY_BYTES =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    protected TelephonyManager mMockTelephonyManager;
-    protected EapAkaTypeDataDecoder mMockEapAkaTypeDataDecoder;
-
-    protected EapAkaConfig mEapAkaConfig = new EapAkaConfig(SUB_ID, APPTYPE_USIM);
-    protected EapAkaMethodStateMachine mEapAkaMethodStateMachine;
-
-    @Before
-    public void setUp() {
-        mMockTelephonyManager = mock(TelephonyManager.class);
-        mMockEapAkaTypeDataDecoder = mock(EapAkaTypeDataDecoder.class);
-
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-
-        mEapAkaMethodStateMachine =
-                new EapAkaMethodStateMachine(
-                        mMockTelephonyManager,
-                        EAP_IDENTITY_BYTES,
-                        mEapAkaConfig,
-                        mMockEapAkaTypeDataDecoder,
-                        true);
-
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-    }
-
-    @Test
-    public void testProcessNotification() throws Exception {
-        EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes());
-        EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preNotification = (EapMethodState) mEapAkaMethodStateMachine.getState();
-
-        EapResult result = mEapAkaMethodStateMachine.process(notification);
-        assertEquals(preNotification, mEapAkaMethodStateMachine.getState());
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-
-        assertTrue(result instanceof EapResult.EapResponse);
-        EapResult.EapResponse eapResponse = (EapResult.EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testProcessEapAkaNotification() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preProcess = (EapMethodState) mEapAkaMethodStateMachine.getState();
-        EapAkaTypeData typeData =
-                new EapAkaTypeData(
-                        EAP_AKA_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE)));
-
-        DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(typeData);
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapAkaMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_AKA_NOTIFICATION_RESPONSE, eapResponse.packet);
-        assertEquals(preProcess, mEapAkaMethodStateMachine.getState());
-        verify(mMockEapAkaTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-    }
-
-    @Test
-    public void testProcessInvalidDecodeResult() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_AKA, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preProcess = (EapMethodState) mEapAkaMethodStateMachine.getState();
-
-        AtClientErrorCode atClientErrorCode = AtClientErrorCode.UNABLE_TO_PROCESS;
-        DecodeResult<EapAkaTypeData> decodeResult = new DecodeResult<>(atClientErrorCode);
-        when(mMockEapAkaTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResult result = mEapAkaMethodStateMachine.process(eapMessage);
-        assertEquals(preProcess, mEapAkaMethodStateMachine.getState());
-        verify(mMockEapAkaTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapAkaTypeDataDecoder);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_AKA_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapSuccessStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapSuccessStateTest.java
deleted file mode 100644
index d4377cb..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2AwaitingEapSuccessStateTest.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_MSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_NT_RESPONSE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class EapMsChapV2AwaitingEapSuccessStateTest extends EapMsChapV2StateTest {
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mStateMachine.transitionTo(
-                mStateMachine.new AwaitingEapSuccessState(MSCHAP_V2_NT_RESPONSE));
-    }
-
-    @Test
-    @Override
-    public void testHandleEapSuccess() throws Exception {
-        EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_SUCCESS, ID_INT, null));
-        EapSuccess eapSuccess = (EapSuccess) result;
-        assertArrayEquals(MSCHAP_V2_MSK, eapSuccess.msk);
-        assertArrayEquals(new byte[0], eapSuccess.emsk);
-        assertTrue(mStateMachine.getState() instanceof FinalState);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ChallengeStateTest.java
deleted file mode 100644
index ec442da..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ChallengeStateTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_MSCHAP_V2_CHALLENGE_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_CHALLENGE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PEER_CHALLENGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SERVER_NAME_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest.TYPE_DATA_HEADER_SIZE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest.VALUE_SIZE;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.ValidateAuthenticatorState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class EapMsChapV2ChallengeStateTest extends EapMsChapV2StateTest {
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mStateMachine.transitionTo(mStateMachine.new ChallengeState());
-    }
-
-    @Test
-    public void testProcessChallenge() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapMsChapV2ChallengeRequest challengeRequest =
-                new EapMsChapV2ChallengeRequest(
-                        MSCHAP_V2_ID_INT,
-                        TYPE_DATA_HEADER_SIZE + VALUE_SIZE + SERVER_NAME_BYTES.length,
-                        MSCHAP_V2_AUTHENTICATOR_CHALLENGE,
-                        SERVER_NAME_BYTES);
-        when(mMockTypeDataDecoder.decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(new DecodeResult<>(challengeRequest));
-
-        doAnswer(invocation -> {
-            byte[] dst = invocation.getArgument(0);
-            System.arraycopy(MSCHAP_V2_PEER_CHALLENGE, 0, dst, 0, MSCHAP_V2_PEER_CHALLENGE.length);
-            return null;
-        }).when(mMockSecureRandom).nextBytes(eq(new byte[MSCHAP_V2_PEER_CHALLENGE.length]));
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_MSCHAP_V2_CHALLENGE_RESPONSE, eapResponse.packet);
-        assertTrue(mStateMachine.getState() instanceof ValidateAuthenticatorState);
-        verify(mMockSecureRandom).nextBytes(any(byte[].class));
-        verify(mMockTypeDataDecoder).decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA));
-    }
-
-    @Test
-    public void testIncorrectTypeData() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        when(mMockTypeDataDecoder.decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(
-                        new DecodeResult<>(
-                                new EapError(
-                                        new EapMsChapV2ParsingException("incorrect type data"))));
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-        verify(mMockTypeDataDecoder).decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2CreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2CreatedStateTest.java
deleted file mode 100644
index 633e0eb..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2CreatedStateTest.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.SERVER_NAME_BYTES;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.exceptions.mschapv2.EapMsChapV2ParsingException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2ChallengeRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.ValidateAuthenticatorState;
-
-import org.junit.Test;
-
-public class EapMsChapV2CreatedStateTest extends EapMsChapV2StateTest {
-    @Test
-    public void testProcessChallengeRequest() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        when(mMockTypeDataDecoder.decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(
-                        new DecodeResult<>(
-                                new EapMsChapV2ChallengeRequest(
-                                        0, 0, CHALLENGE_BYTES, SERVER_NAME_BYTES)));
-
-        mStateMachine.process(eapMessage);
-
-        assertTrue(mStateMachine.getState() instanceof ValidateAuthenticatorState);
-        verify(mMockTypeDataDecoder, times(2))
-                .decodeChallengeRequest(any(String.class), eq(DUMMY_TYPE_DATA));
-    }
-
-    @Test
-    public void testIncorrectTypeData() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        when(mMockTypeDataDecoder.decodeChallengeRequest(
-                        eq(CREATED_STATE_TAG), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(
-                        new DecodeResult<>(
-                                new EapError(
-                                        new EapMsChapV2ParsingException("incorrect type data"))));
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapMsChapV2ParsingException);
-        verify(mMockTypeDataDecoder)
-                .decodeChallengeRequest(eq(CREATED_STATE_TAG), eq(DUMMY_TYPE_DATA));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachineTest.java
deleted file mode 100644
index b24c3f8..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2MethodStateMachineTest.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_CHALLENGE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_CHALLENGE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_MASTER_KEY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_MSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_NT_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD_HASH;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD_HASH_HASH;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD_UTF_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PEER_CHALLENGE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_RECEIVE_START_KEY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_SEND_START_KEY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_USERNAME;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_USERNAME_ASCII_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.net.eap.EapSessionConfig.EapMsChapV2Config;
-
-import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.CreatedState;
-import com.android.internal.net.utils.Log;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-
-public class EapMsChapV2MethodStateMachineTest {
-    private EapMsChapV2Config mEapMsChapV2Config;
-    private EapMsChapV2MethodStateMachine mStateMachine;
-
-    @Before
-    public void setUp() {
-        mEapMsChapV2Config = new EapMsChapV2Config(MSCHAP_V2_USERNAME, MSCHAP_V2_PASSWORD);
-        mStateMachine = new EapMsChapV2MethodStateMachine(mEapMsChapV2Config, new SecureRandom());
-    }
-
-    @Test
-    public void testGetEapMethod() {
-        assertEquals(EAP_TYPE_MSCHAP_V2, mStateMachine.getEapMethod());
-    }
-
-    @Test
-    public void testStartsOnCreatedState() {
-        assertTrue(mStateMachine.getState() instanceof CreatedState);
-    }
-
-    // Tests for MS CHAPv2 authentication utils. Test vectors from RFC 2759#9.2.
-
-    @Test
-    public void testUsernameToBytes() {
-        assertArrayEquals(
-                MSCHAP_V2_USERNAME_ASCII_BYTES,
-                EapMsChapV2MethodStateMachine.usernameToBytes(MSCHAP_V2_USERNAME));
-    }
-
-    @Test
-    public void testPasswordToBytes() {
-        assertArrayEquals(
-                MSCHAP_V2_PASSWORD_UTF_BYTES,
-                EapMsChapV2MethodStateMachine.passwordToBytes(MSCHAP_V2_PASSWORD));
-    }
-
-    @Test
-    public void testGenerateNtResponse() throws Exception {
-        byte[] ntResponse =
-                EapMsChapV2MethodStateMachine.generateNtResponse(
-                        MSCHAP_V2_AUTHENTICATOR_CHALLENGE,
-                        MSCHAP_V2_PEER_CHALLENGE,
-                        MSCHAP_V2_USERNAME,
-                        MSCHAP_V2_PASSWORD);
-        assertArrayEquals(MSCHAP_V2_NT_RESPONSE, ntResponse);
-    }
-
-    @Test
-    public void testChallengeHash() throws Exception {
-        byte[] challenge =
-                EapMsChapV2MethodStateMachine.challengeHash(
-                        MSCHAP_V2_PEER_CHALLENGE,
-                        MSCHAP_V2_AUTHENTICATOR_CHALLENGE,
-                        MSCHAP_V2_USERNAME);
-        assertArrayEquals(MSCHAP_V2_CHALLENGE, challenge);
-    }
-
-    @Test
-    public void testNtPasswordHash() {
-        byte[] passwordHash = EapMsChapV2MethodStateMachine.ntPasswordHash(MSCHAP_V2_PASSWORD);
-        assertArrayEquals(MSCHAP_V2_PASSWORD_HASH, passwordHash);
-    }
-
-    @Test
-    public void testHashNtPasswordHash() {
-        byte[] passwordHashHash =
-                EapMsChapV2MethodStateMachine.hashNtPasswordHash(MSCHAP_V2_PASSWORD_HASH);
-        assertArrayEquals(MSCHAP_V2_PASSWORD_HASH_HASH, passwordHashHash);
-    }
-
-    @Test
-    public void testChallengeResponse() throws Exception {
-        byte[] challengeResponse =
-                EapMsChapV2MethodStateMachine.challengeResponse(
-                        MSCHAP_V2_CHALLENGE, MSCHAP_V2_PASSWORD_HASH);
-        assertArrayEquals(MSCHAP_V2_NT_RESPONSE, challengeResponse);
-    }
-
-    @Test
-    public void testGenerateAuthenticatorResponse() throws Exception {
-        byte[] authenticatorResponse =
-                EapMsChapV2MethodStateMachine.generateAuthenticatorResponse(
-                        MSCHAP_V2_PASSWORD,
-                        MSCHAP_V2_NT_RESPONSE,
-                        MSCHAP_V2_PEER_CHALLENGE,
-                        MSCHAP_V2_AUTHENTICATOR_CHALLENGE,
-                        MSCHAP_V2_USERNAME);
-        assertArrayEquals(MSCHAP_V2_AUTHENTICATOR_RESPONSE, authenticatorResponse);
-    }
-
-    @Test
-    public void testCheckAuthenticatorResponse() throws Exception {
-        assertTrue(
-                "AuthenticatorResponse didn't match computed response",
-                EapMsChapV2MethodStateMachine.checkAuthenticatorResponse(
-                        MSCHAP_V2_PASSWORD,
-                        MSCHAP_V2_NT_RESPONSE,
-                        MSCHAP_V2_PEER_CHALLENGE,
-                        MSCHAP_V2_AUTHENTICATOR_CHALLENGE,
-                        MSCHAP_V2_USERNAME,
-                        MSCHAP_V2_AUTHENTICATOR_RESPONSE));
-    }
-
-    @Test
-    public void testGetMasterKey() throws Exception {
-        byte[] masterKey =
-                EapMsChapV2MethodStateMachine.getMasterKey(
-                        MSCHAP_V2_PASSWORD_HASH_HASH, MSCHAP_V2_NT_RESPONSE);
-        assertArrayEquals(MSCHAP_V2_MASTER_KEY, masterKey);
-    }
-
-    @Test
-    public void testGetAsymmetricStartKeySendKey() throws Exception {
-        byte[] startKey =
-                EapMsChapV2MethodStateMachine.getAsymmetricStartKey(MSCHAP_V2_MASTER_KEY, true);
-        assertArrayEquals(Log.byteArrayToHexString(startKey), MSCHAP_V2_SEND_START_KEY, startKey);
-    }
-
-    @Test
-    public void testGetAsymmetricStartKeyReceiveKey() throws Exception {
-        byte[] receiveKey =
-                EapMsChapV2MethodStateMachine.getAsymmetricStartKey(MSCHAP_V2_MASTER_KEY, false);
-        assertArrayEquals(MSCHAP_V2_RECEIVE_START_KEY, receiveKey);
-    }
-
-    @Test
-    public void testGenerateMsk() throws Exception {
-        byte[] msk =
-                EapMsChapV2MethodStateMachine.generateMsk(
-                        MSCHAP_V2_PASSWORD, MSCHAP_V2_NT_RESPONSE);
-        assertArrayEquals(MSCHAP_V2_MSK, msk);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2StateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2StateTest.java
deleted file mode 100644
index 1e4a0c5..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2StateTest.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PASSWORD;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_USERNAME;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import android.net.eap.EapSessionConfig.EapMsChapV2Config;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-
-public class EapMsChapV2StateTest {
-    protected static final String CREATED_STATE_TAG = "CreatedState";
-    protected static final String NOTIFICATION_MESSAGE = "test";
-    protected static final byte[] DUMMY_TYPE_DATA = hexStringToByteArray("00112233");
-
-    protected SecureRandom mMockSecureRandom;
-    protected EapMsChapV2TypeDataDecoder mMockTypeDataDecoder;
-
-    protected EapMsChapV2Config mEapMsChapV2Config;
-    protected EapMsChapV2MethodStateMachine mStateMachine;
-
-    @Before
-    public void setUp() {
-        mMockSecureRandom = mock(SecureRandom.class);
-        mMockTypeDataDecoder = mock(EapMsChapV2TypeDataDecoder.class);
-
-        mEapMsChapV2Config = new EapMsChapV2Config(MSCHAP_V2_USERNAME, MSCHAP_V2_PASSWORD);
-        mStateMachine =
-                new EapMsChapV2MethodStateMachine(
-                        mEapMsChapV2Config, mMockSecureRandom, mMockTypeDataDecoder);
-    }
-
-    @Test
-    public void testHandleEapFailure() throws Exception {
-        EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_FAILURE, ID_INT, null));
-        assertTrue(result instanceof EapFailure);
-        assertTrue(mStateMachine.getState() instanceof FinalState);
-    }
-
-    @Test
-    public void testHandleEapSuccess() throws Exception {
-        EapResult result = mStateMachine.process(new EapMessage(EAP_CODE_SUCCESS, ID_INT, null));
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testHandleEapNotification() throws Exception {
-        EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes());
-        EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preNotification = (EapMethodState) mStateMachine.getState();
-
-        EapResult result = mStateMachine.process(notification);
-        assertEquals(preNotification, mStateMachine.getState());
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ValidateAuthenticatorStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ValidateAuthenticatorStateTest.java
deleted file mode 100644
index dda7d5b..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapMsChapV2ValidateAuthenticatorStateTest.java
+++ /dev/null
@@ -1,173 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_MSCHAP_V2_FAILURE_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_MSCHAP_V2_SUCCESS_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.INVALID_AUTHENTICATOR_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_CHALLENGE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_AUTHENTICATOR_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_NT_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSCHAP_V2_PEER_CHALLENGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.CHALLENGE_BYTES;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.ERROR_CODE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.MESSAGE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.PASSWORD_CHANGE_PROTOCOL;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2PacketDefinitions.RETRY_BIT;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_FAILURE;
-import static com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EAP_MSCHAP_V2_SUCCESS;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2FailureRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2SuccessRequest;
-import com.android.internal.net.eap.message.mschapv2.EapMsChapV2TypeData.EapMsChapV2TypeDataDecoder.DecodeResult;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.AwaitingEapFailureState;
-import com.android.internal.net.eap.statemachine.EapMsChapV2MethodStateMachine.AwaitingEapSuccessState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.BufferUnderflowException;
-
-public class EapMsChapV2ValidateAuthenticatorStateTest extends EapMsChapV2StateTest {
-    private static final int INVALID_OP_CODE = -1;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mStateMachine.transitionTo(
-                mStateMachine.new ValidateAuthenticatorState(
-                        MSCHAP_V2_AUTHENTICATOR_CHALLENGE,
-                        MSCHAP_V2_PEER_CHALLENGE,
-                        MSCHAP_V2_NT_RESPONSE));
-    }
-
-    @Test
-    public void testProcessSuccessRequest() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapMsChapV2SuccessRequest successRequest =
-                new EapMsChapV2SuccessRequest(
-                        MSCHAP_V2_ID_INT, 0, MSCHAP_V2_AUTHENTICATOR_RESPONSE, MESSAGE);
-
-        when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(EAP_MSCHAP_V2_SUCCESS);
-        when(mMockTypeDataDecoder.decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(new DecodeResult<>(successRequest));
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_MSCHAP_V2_SUCCESS_RESPONSE, eapResponse.packet);
-        assertTrue(mStateMachine.getState() instanceof AwaitingEapSuccessState);
-        verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA));
-        verify(mMockTypeDataDecoder).decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessInvalidSuccessRequest() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapMsChapV2SuccessRequest successRequest =
-                new EapMsChapV2SuccessRequest(
-                        MSCHAP_V2_ID_INT, 0, INVALID_AUTHENTICATOR_RESPONSE, MESSAGE);
-
-        when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(EAP_MSCHAP_V2_SUCCESS);
-        when(mMockTypeDataDecoder.decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(new DecodeResult<>(successRequest));
-
-        EapResult result = mStateMachine.process(eapMessage);
-        assertTrue(result instanceof EapFailure);
-        assertTrue(mStateMachine.getState() instanceof FinalState);
-        verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA));
-        verify(mMockTypeDataDecoder).decodeSuccessRequest(any(String.class), eq(DUMMY_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessFailureRequest() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapMsChapV2FailureRequest failureRequest =
-                new EapMsChapV2FailureRequest(
-                        MSCHAP_V2_ID_INT,
-                        0,
-                        ERROR_CODE,
-                        RETRY_BIT,
-                        CHALLENGE_BYTES,
-                        PASSWORD_CHANGE_PROTOCOL,
-                        MESSAGE);
-
-        when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(EAP_MSCHAP_V2_FAILURE);
-        when(mMockTypeDataDecoder.decodeFailureRequest(any(String.class), eq(DUMMY_TYPE_DATA)))
-                .thenReturn(new DecodeResult<>(failureRequest));
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_MSCHAP_V2_FAILURE_RESPONSE, eapResponse.packet);
-        assertTrue(mStateMachine.getState() instanceof AwaitingEapFailureState);
-        verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA));
-        verify(mMockTypeDataDecoder).decodeFailureRequest(any(String.class), eq(DUMMY_TYPE_DATA));
-    }
-
-    @Test
-    public void testProcessEmptyTypeData() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, new byte[0]);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        when(mMockTypeDataDecoder.getOpCode(eq(new byte[0])))
-                .thenThrow(new BufferUnderflowException());
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof BufferUnderflowException);
-        verify(mMockTypeDataDecoder).getOpCode(eq(new byte[0]));
-    }
-
-    @Test
-    public void testProcessInvalidPacket() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_MSCHAP_V2, DUMMY_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        when(mMockTypeDataDecoder.getOpCode(eq(DUMMY_TYPE_DATA))).thenReturn(INVALID_OP_CODE);
-
-        EapResult result = mStateMachine.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-        verify(mMockTypeDataDecoder).getOpCode(eq(DUMMY_TYPE_DATA));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachineTest.java
deleted file mode 100644
index 7adc9f7..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimAkaMethodStateMachineTest.java
+++ /dev/null
@@ -1,475 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.COMPUTED_MAC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CHALLENGE_RESPONSE_WITH_MAC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_IDENTITY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE_WITH_MAC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_RESPONSE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK_STRING;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_1;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_2;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_AUT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_AUT_STRING;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_ENCR;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.K_ENCR_STRING;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MAC_INPUT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK_STRING;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ORIGINAL_MAC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_1;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_BYTES;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_POST_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CLIENT_ERROR;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.AT_IDENTITY;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.IDENTITY;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT_STRING;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2_BYTES;
-import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.KEY_LEN;
-import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.MAC_ALGORITHM_STRING;
-import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.MASTER_KEY_GENERATION_ALG;
-import static com.android.internal.net.eap.statemachine.EapSimAkaMethodStateMachine.SESSION_KEY_LENGTH;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig.EapSimConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.crypto.Fips186_2Prf;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtSelectedVersion;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.MessageDigest;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-public class EapSimAkaMethodStateMachineTest {
-    private static final String TAG = EapSimAkaMethodStateMachineTest.class.getSimpleName();
-    private static final int SUB_ID = 1;
-    private static final int AT_RAND_LEN = 36;
-    private static final String VERSIONS_STRING = "0001";
-    private static final String SELECTED_VERSION = "0001";
-    private static final byte[] SHA_1_INPUT = hexStringToByteArray("0123456789ABCDEF");
-    private static final byte[] FORMATTED_UICC_CHALLENGE =
-            hexStringToByteArray("1000112233445566778899AABBCCDDEEFF");
-    private static final String BASE_64_CHALLENGE = "EAARIjNEVWZ3iJmqu8zd7v8=";
-    private static final String BASE_64_RESPONSE = "BBEiM0QIAQIDBAUGBwg=";
-    private static final byte[] UICC_RESPONSE =
-            hexStringToByteArray("04" + SRES_1 + "08" + KC_1);
-
-    // EAP-Identity = hex("test@android.net")
-    protected static final byte[] EAP_IDENTITY_BYTES =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    // K_encr + K_aut + MSK + EMSK
-    private static final int PRF_OUTPUT_BYTES = (2 * KEY_LEN) + (2 * SESSION_KEY_LENGTH);
-
-    private TelephonyManager mMockTelephonyManager;
-    private EapSimConfig mEapSimConfig;
-    private EapSimAkaMethodStateMachine mStateMachine;
-
-    @Before
-    public void setUp() {
-        mMockTelephonyManager = mock(TelephonyManager.class);
-        mEapSimConfig = new EapSimConfig(SUB_ID, TelephonyManager.APPTYPE_USIM);
-
-        mStateMachine =
-                new EapSimAkaMethodStateMachine(
-                        mMockTelephonyManager, EAP_IDENTITY_BYTES, mEapSimConfig) {
-                    @Override
-                    EapSimAkaTypeData getEapSimAkaTypeData(AtClientErrorCode clientErrorCode) {
-                        return new EapSimTypeData(
-                                EAP_SIM_CLIENT_ERROR, Arrays.asList(clientErrorCode));
-                    }
-
-                    @Override
-                    EapSimAkaTypeData getEapSimAkaTypeData(
-                            int eapSubtype, List<EapSimAkaAttribute> attributes) {
-                        return new EapSimTypeData(eapSubtype, attributes);
-                    }
-
-                    @Override
-                    int getEapMethod() {
-                        return EAP_TYPE_SIM;
-                    }
-                };
-        mStateMachine = spy(mStateMachine);
-    }
-
-    @Test
-    public void testBuildClientErrorResponse() {
-        AtClientErrorCode errorCode = AtClientErrorCode.UNSUPPORTED_VERSION;
-
-        EapResult result =
-                mStateMachine.buildClientErrorResponse(ID_INT, EAP_TYPE_SIM, errorCode);
-        assertTrue(result instanceof EapResult.EapResponse);
-        EapResult.EapResponse eapResponse = (EapResult.EapResponse) result;
-        assertArrayEquals(EAP_SIM_CLIENT_ERROR_RESPONSE, eapResponse.packet);
-    }
-
-    @Test
-    public void testBuildResponseMessage() throws Exception {
-        List<EapSimAkaAttribute> attributes = new ArrayList<>();
-        attributes.add(new AtSelectedVersion(1));
-        attributes.add(new AtIdentity(AT_IDENTITY.length, IDENTITY));
-        int identifier = ID_INT;
-
-        EapResult result =
-                mStateMachine.buildResponseMessage(
-                        EAP_TYPE_SIM,
-                        EAP_SIM_START,
-                        identifier,
-                        attributes);
-        assertTrue(result instanceof EapResult);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_SIM_RESPONSE_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testGenerateAndPersistKeys() {
-        byte[] mkInput = hexStringToByteArray(
-                EAP_SIM_IDENTITY
-                        + KC_1
-                        + KC_2
-                        + NONCE_MT_STRING
-                        + VERSIONS_STRING
-                        + SELECTED_VERSION);
-        MessageDigest mockSha1 = mock(MessageDigest.class);
-        when(mockSha1.digest(eq(mkInput))).thenReturn(MK);
-
-        byte[] keys = hexStringToByteArray(K_ENCR_STRING + K_AUT_STRING + MSK_STRING + EMSK_STRING);
-        Fips186_2Prf mockFips186_2Prf = mock(Fips186_2Prf.class);
-        when(mockFips186_2Prf.getRandom(eq(MK), eq(PRF_OUTPUT_BYTES))).thenReturn(keys);
-
-        mStateMachine.generateAndPersistKeys(TAG, mockSha1, mockFips186_2Prf, mkInput);
-        assertArrayEquals(K_ENCR, mStateMachine.mKEncr);
-        assertArrayEquals(K_AUT, mStateMachine.mKAut);
-        assertArrayEquals(MSK, mStateMachine.mMsk);
-        assertArrayEquals(EMSK, mStateMachine.mEmsk);
-
-        verify(mockSha1).digest(eq(mkInput));
-        verify(mockFips186_2Prf).getRandom(eq(MK), eq(PRF_OUTPUT_BYTES));
-        verifyNoMoreInteractions(mockSha1, mockFips186_2Prf);
-    }
-
-    /**
-     * Test that we can actually instantiate and use the SHA-1algorithm.
-     */
-    @Test
-    public void testCreateSha1() throws Exception {
-        MessageDigest sha1 = MessageDigest.getInstance(MASTER_KEY_GENERATION_ALG);
-        byte[] sha1Result = sha1.digest(SHA_1_INPUT);
-        assertFalse(Arrays.equals(SHA_1_INPUT, sha1Result));
-    }
-
-    /**
-     * Test that we can actually instantiate and use the HMAC-SHA-1 algorithm.
-     */
-    @Test
-    public void testCreateHmacSha1() throws Exception {
-        Mac macAlgorithm = Mac.getInstance(MAC_ALGORITHM_STRING);
-        macAlgorithm.init(new SecretKeySpec(K_AUT, MAC_ALGORITHM_STRING));
-        byte[] mac = macAlgorithm.doFinal(MAC_INPUT);
-        assertFalse(Arrays.equals(MAC_INPUT, mac));
-    }
-
-    @Test
-    public void testProcessUiccAuthentication() throws Exception {
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE)).thenReturn(BASE_64_RESPONSE);
-
-        byte[] result =
-                mStateMachine.processUiccAuthentication(
-                        TAG,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        FORMATTED_UICC_CHALLENGE);
-
-        assertArrayEquals(UICC_RESPONSE, result);
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessUiccAuthenticationNullResponse() throws Exception {
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE)).thenReturn(null);
-
-        try {
-            mStateMachine.processUiccAuthentication(
-                    TAG,
-                    TelephonyManager.AUTHTYPE_EAP_AKA,
-                    FORMATTED_UICC_CHALLENGE);
-            fail("EapSimAkaAuthenticationFailureException expected for null TelMan response");
-        } catch (EapSimAkaAuthenticationFailureException expected) {
-        }
-
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_AKA,
-                        BASE_64_CHALLENGE);
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testGetMac() throws Exception {
-        AtMac atMac = new AtMac(ORIGINAL_MAC);
-        AtRandSim atRandSim = new AtRandSim(AT_RAND_LEN, RAND_1_BYTES, RAND_2_BYTES);
-        EapSimTypeData eapSimTypeData =
-                new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList(atRandSim, atMac));
-
-        Mac mockMac = mock(Mac.class);
-        when(mockMac.doFinal(eq(MAC_INPUT))).thenReturn(COMPUTED_MAC);
-        mStateMachine.mMacAlgorithm = mockMac;
-
-        byte[] mac = mStateMachine.getMac(EAP_CODE_REQUEST, ID_INT, eapSimTypeData, NONCE_MT);
-        assertArrayEquals(COMPUTED_MAC, mac);
-        AtMac postCalculationAtMac = (AtMac) eapSimTypeData.attributeMap.get(EAP_AT_MAC);
-        assertArrayEquals(ORIGINAL_MAC, postCalculationAtMac.mac);
-
-        verify(mockMac).doFinal(eq(MAC_INPUT));
-        verifyNoMoreInteractions(mockMac);
-    }
-
-    @Test
-    public void testGetMacNoMacAlgorithm() throws Exception {
-        try {
-            mStateMachine.getMac(EAP_CODE_REQUEST, ID_INT, null, null);
-            fail("Expected IllegalStateException if Mac not set");
-        } catch (IllegalStateException expected) {
-        }
-    }
-
-    @Test
-    public void testReceivedValidMac() throws Exception {
-        AtMac atMac = new AtMac(ORIGINAL_MAC);
-        AtRandSim atRandSim = new AtRandSim(AT_RAND_LEN, RAND_1_BYTES, RAND_2_BYTES);
-        EapSimTypeData eapSimTypeData =
-                new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList(atRandSim, atMac));
-        EapData eapData = new EapData(EAP_TYPE_SIM, new byte[0]);
-        EapMessage message = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        doReturn(ORIGINAL_MAC)
-                .when(mStateMachine)
-                .getMac(eq(EAP_CODE_REQUEST), eq(ID_INT), eq(eapSimTypeData), eq(NONCE_MT));
-
-        assertTrue(mStateMachine.isValidMac(TAG, message, eapSimTypeData, NONCE_MT));
-
-        doReturn(new byte[0])
-                .when(mStateMachine)
-                .getMac(eq(EAP_CODE_REQUEST), eq(ID_INT), eq(eapSimTypeData), eq(NONCE_MT));
-
-        assertFalse(mStateMachine.isValidMac(TAG, message, eapSimTypeData, NONCE_MT));
-
-        verify(mStateMachine, times(2))
-                .getMac(eq(EAP_CODE_REQUEST), eq(ID_INT), eq(eapSimTypeData), eq(NONCE_MT));
-    }
-
-    @Test
-    public void testBuildResponseMessageWithMac() {
-        Mac mockMac = mock(Mac.class);
-        when(mockMac.doFinal(eq(EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT))).thenReturn(COMPUTED_MAC);
-        mStateMachine.mMacAlgorithm = mockMac;
-
-        EapResult result =
-                mStateMachine.buildResponseMessageWithMac(ID_INT, EAP_SIM_CHALLENGE, SRES_BYTES);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_SIM_CHALLENGE_RESPONSE_WITH_MAC, eapResponse.packet);
-        verify(mockMac).doFinal(eq(EAP_SIM_CHALLENGE_RESPONSE_MAC_INPUT));
-        verifyNoMoreInteractions(mockMac);
-    }
-
-    @Test
-    public void testHandleEapSimNotificationPreChallenge() throws Exception {
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE)));
-
-        EapResponse eapResponse =
-                (EapResponse)
-                        mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData);
-        assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE, eapResponse.packet);
-        assertTrue(mStateMachine.mHasReceivedSimAkaNotification);
-        verify(mStateMachine, never()).transitionTo(any(EapMethodState.class));
-    }
-
-    @Test
-    public void testHandleEapSimNotificationPreChallengeInvalidPBit() throws Exception {
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_POST_CHALLENGE)));
-
-        EapResponse eapResponse =
-                (EapResponse)
-                        mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData);
-        assertArrayEquals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-        verify(mStateMachine, never())
-                .transitionTo(any(EapMethodStateMachine.EapMethodState.class));
-    }
-
-    @Test
-    public void testHandleEapSimNotificationMultipleNotifications() throws Exception {
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE)));
-
-        mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData);
-
-        EapError eapError =
-                (EapError) mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData);
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-        assertTrue(mStateMachine.mHasReceivedSimAkaNotification);
-        verify(mStateMachine, never())
-                .transitionTo(any(EapMethodStateMachine.EapMethodState.class));
-    }
-
-    @Test
-    public void testHandleEapSimNotificationInvalidAtMac() throws Exception {
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(
-                                new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE), new AtMac()));
-
-        EapResponse eapResponse =
-                (EapResponse)
-                        mStateMachine.handleEapSimAkaNotification(TAG, true, ID_INT, typeData);
-        assertArrayEquals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-        verify(mStateMachine, never())
-                .transitionTo(any(EapMethodStateMachine.EapMethodState.class));
-    }
-
-    @Test
-    public void testHandleEapSimNotificationPostChallenge() throws Exception {
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(
-                                new AtNotification(GENERAL_FAILURE_POST_CHALLENGE),
-                                new AtMac(ORIGINAL_MAC)));
-
-        Mac mockMac = mock(Mac.class);
-        when(mockMac.doFinal(eq(EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC)))
-                .thenReturn(ORIGINAL_MAC);
-        when(mockMac.doFinal(eq(EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC)))
-                .thenReturn(COMPUTED_MAC);
-        mStateMachine.mMacAlgorithm = mockMac;
-
-        EapResponse eapResponse =
-                (EapResponse)
-                        mStateMachine.handleEapSimAkaNotification(TAG, false, ID_INT, typeData);
-        assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE_WITH_MAC, eapResponse.packet);
-        assertTrue(mStateMachine.mHasReceivedSimAkaNotification);
-        verify(mStateMachine, never()).transitionTo(any(EapMethodState.class));
-
-        verify(mockMac).doFinal(eq(EAP_SIM_NOTIFICATION_REQUEST_WITH_EMPTY_MAC));
-        verify(mockMac).doFinal(eq(EAP_SIM_NOTIFICATION_RESPONSE_WITH_EMPTY_MAC));
-        verifyNoMoreInteractions(mockMac);
-    }
-
-    @Test
-    public void testHandleEapSimNotificationPostChallengeInvalidAtMac() throws Exception {
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_POST_CHALLENGE)));
-
-        EapResponse eapResponse =
-                (EapResponse)
-                        mStateMachine.handleEapSimAkaNotification(TAG, false, ID_INT, typeData);
-        assertArrayEquals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet);
-        verify(mStateMachine, never()).transitionTo(any(EapMethodState.class));
-    }
-
-    @Test
-    public void testKeyLengths() {
-        assertEquals(KEY_LEN, mStateMachine.getKEncrLength());
-        assertEquals(KEY_LEN, mStateMachine.getKAutLength());
-        assertEquals(SESSION_KEY_LENGTH, mStateMachine.getMskLength());
-        assertEquals(SESSION_KEY_LENGTH, mStateMachine.getEmskLength());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimChallengeStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimChallengeStateTest.java
deleted file mode 100644
index bffc03a..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimChallengeStateTest.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CHALLENGE_RESPONSE_INVALID_KC;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.CHALLENGE_RESPONSE_INVALID_SRES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_IDENTITY_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_1_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.KC_2_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_1_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SRES_2_BYTES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.VALID_CHALLENGE_RESPONSE;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_RAND;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_1_BYTES;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.RAND_2_BYTES;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaAuthenticationFailureException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidAttributeException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaInvalidLengthException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtRandSim;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.ChallengeState;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.ChallengeState.RandChallengeResult;
-
-import org.junit.Test;
-
-import java.nio.BufferUnderflowException;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.List;
-
-public class EapSimChallengeStateTest extends EapSimStateTest {
-    private static final int VALID_SRES_LENGTH = 4;
-    private static final int INVALID_SRES_LENGTH = 5;
-    private static final int VALID_KC_LENGTH = 8;
-    private static final int INVALID_KC_LENGTH = 9;
-    private static final int AT_RAND_LENGTH = 36;
-    private static final List<Integer> VERSIONS = Arrays.asList(1);
-
-    // Base64 of {@link EapTestAttributeDefinitions#RAND_1}
-    private static final String BASE_64_RAND_1 = "EAARIjNEVWZ3iJmqu8zd7v8=";
-
-    // Base64 of {@link EapTestAttributeDefinitions#RAND_2}
-    private static final String BASE_64_RAND_2 = "EP/u3cy7qpmId2ZVRDMiEQA=";
-
-    // Base64 of "04" + SRES_1 + "08" + KC_1
-    private static final String BASE_64_RESP_1 = "BBEiM0QIAQIDBAUGBwg=";
-
-    // Base64 of "04" + SRES_2 + "08" + KC_2
-    private static final String BASE_64_RESP_2 = "BEQzIhEICAcGBQQDAgE=";
-
-    // Base64 of "04" + SRES_1 + '081122"
-    private static final String BASE_64_INVALID_RESP = "BBEiM0QIESI=";
-
-    private AtNonceMt mAtNonceMt;
-    private ChallengeState mChallengeState;
-
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        try {
-            mAtNonceMt = new AtNonceMt(NONCE_MT);
-        } catch (EapSimAkaInvalidAttributeException ex) {
-            // this will never happen
-        }
-        mChallengeState = mEapSimMethodStateMachine
-                .new ChallengeState(VERSIONS, mAtNonceMt, EAP_SIM_IDENTITY_BYTES);
-        mEapSimMethodStateMachine.transitionTo(mChallengeState);
-    }
-
-    @Test
-    public void testProcessIncorrectEapMethodType() throws Exception {
-        EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapResult result = mChallengeState.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessSuccess() throws Exception {
-        System.arraycopy(MSK, 0, mEapSimMethodStateMachine.mMsk, 0, MSK.length);
-        System.arraycopy(EMSK, 0, mEapSimMethodStateMachine.mEmsk, 0, EMSK.length);
-
-        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-        EapResult result = mEapSimMethodStateMachine.process(input);
-        assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState);
-
-        EapSuccess eapSuccess = (EapSuccess) result;
-        assertArrayEquals(MSK, eapSuccess.msk);
-        assertArrayEquals(EMSK, eapSuccess.emsk);
-    }
-
-    @Test
-    public void testProcessFailure() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
-        EapResult result = mEapSimMethodStateMachine.process(input);
-        assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState);
-
-        assertTrue(result instanceof EapFailure);
-    }
-
-    @Test
-    public void testIsValidChallengeAttributes() {
-        LinkedHashMap<Integer, EapSimAkaAttribute> attributeMap = new LinkedHashMap<>();
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_CHALLENGE, attributeMap);
-        assertFalse(mChallengeState.isValidChallengeAttributes(eapSimTypeData));
-
-        attributeMap.put(EAP_AT_RAND, null); // value doesn't matter, just need key
-        eapSimTypeData = new EapSimTypeData(EAP_SIM_CHALLENGE, attributeMap);
-        assertFalse(mChallengeState.isValidChallengeAttributes(eapSimTypeData));
-
-        attributeMap.put(EAP_AT_MAC, null); // value doesn't matter, just need key
-        eapSimTypeData = new EapSimTypeData(EAP_SIM_CHALLENGE, attributeMap);
-        assertTrue(mChallengeState.isValidChallengeAttributes(eapSimTypeData));
-    }
-
-    @Test
-    public void testRandChallengeResultConstructor() {
-        try {
-            mChallengeState.new RandChallengeResult(
-                    new byte[VALID_SRES_LENGTH], new byte[INVALID_KC_LENGTH]);
-            fail("EapSimAkaInvalidLengthException expected for invalid SRES lengths");
-        } catch (EapSimAkaInvalidLengthException expected) {
-        }
-
-        try {
-            mChallengeState.new RandChallengeResult(
-                    new byte[INVALID_SRES_LENGTH], new byte[VALID_KC_LENGTH]);
-            fail("EapSimAkaInvalidLengthException expected for invalid Kc lengths");
-        } catch (EapSimAkaInvalidLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testRandChallengeResultEquals() throws Exception {
-        RandChallengeResult resultA =
-                mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES);
-        RandChallengeResult resultB =
-                mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES);
-        RandChallengeResult resultC =
-                mChallengeState.new RandChallengeResult(SRES_2_BYTES, KC_2_BYTES);
-
-        assertEquals(resultA, resultB);
-        assertNotEquals(resultA, resultC);
-    }
-
-    @Test
-    public void testRandChallengeResultHashCode() throws Exception {
-        RandChallengeResult resultA =
-                mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES);
-        RandChallengeResult resultB =
-                mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES);
-        RandChallengeResult resultC =
-                mChallengeState.new RandChallengeResult(SRES_2_BYTES, KC_2_BYTES);
-
-        assertEquals(resultA.hashCode(), resultB.hashCode());
-        assertNotEquals(resultA.hashCode(), resultC.hashCode());
-    }
-
-    @Test
-    public void testGetRandChallengeResultFromResponse() throws Exception {
-        RandChallengeResult result =
-                mChallengeState.getRandChallengeResultFromResponse(VALID_CHALLENGE_RESPONSE);
-
-        assertArrayEquals(SRES_1_BYTES, result.sres);
-        assertArrayEquals(KC_1_BYTES, result.kc);
-    }
-
-    @Test
-    public void testGetRandChallengeResultFromResponseInvalidSres() {
-        try {
-            mChallengeState.getRandChallengeResultFromResponse(CHALLENGE_RESPONSE_INVALID_SRES);
-            fail("EapSimAkaInvalidLengthException expected for invalid SRES_1 length");
-        } catch (EapSimAkaInvalidLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testGetRandChallengeResultFromResponseInvalidKc() {
-        try {
-            mChallengeState.getRandChallengeResultFromResponse(CHALLENGE_RESPONSE_INVALID_KC);
-            fail("EapSimAkaInvalidLengthException expected for invalid KC length");
-        } catch (EapSimAkaInvalidLengthException expected) {
-        }
-    }
-
-    @Test
-    public void testGetRandChallengeResults() throws Exception {
-        EapSimTypeData eapSimTypeData =
-                new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList(
-                        new AtRandSim(AT_RAND_LENGTH,
-                                hexStringToByteArray(RAND_1),
-                                hexStringToByteArray(RAND_2))));
-
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_1))
-                .thenReturn(BASE_64_RESP_1);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_2))
-                .thenReturn(BASE_64_RESP_2);
-
-        List<RandChallengeResult> actualResult =
-                mChallengeState.getRandChallengeResults(eapSimTypeData);
-
-        List<RandChallengeResult> expectedResult = Arrays.asList(
-                mChallengeState.new RandChallengeResult(SRES_1_BYTES, KC_1_BYTES),
-                mChallengeState.new RandChallengeResult(SRES_2_BYTES, KC_2_BYTES));
-        assertEquals(expectedResult, actualResult);
-
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_1);
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_2);
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testGetRandChallengeResultsBufferUnderflow() throws Exception {
-        EapSimTypeData eapSimTypeData =
-                new EapSimTypeData(EAP_SIM_CHALLENGE, Arrays.asList(
-                        new AtRandSim(AT_RAND_LENGTH,
-                                hexStringToByteArray(RAND_1),
-                                hexStringToByteArray(RAND_2))));
-
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_1))
-                .thenReturn(BASE_64_RESP_1);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_2))
-                .thenReturn(BASE_64_INVALID_RESP);
-
-        try {
-            mChallengeState.getRandChallengeResults(eapSimTypeData);
-            fail("BufferUnderflowException expected for short Kc value");
-        } catch (BufferUnderflowException ex) {
-        }
-
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_1);
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_2);
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessUiccAuthenticationNullResponse() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        AtRandSim atRandSim = new AtRandSim(AT_RAND_LENGTH, RAND_1_BYTES, RAND_2_BYTES);
-
-        DecodeResult<EapSimTypeData> decodeResult =
-                new DecodeResult<>(
-                        new EapSimTypeData(
-                                EAP_SIM_CHALLENGE,
-                                Arrays.asList(atRandSim, new AtMac())));
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-        when(mMockTelephonyManager
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_1))
-                .thenReturn(null);
-
-        EapError eapError = (EapError) mEapSimMethodStateMachine.process(eapMessage);
-        assertTrue(eapError.cause instanceof EapSimAkaAuthenticationFailureException);
-
-        verify(mMockEapSimTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verify(mMockTelephonyManager)
-                .getIccAuthentication(
-                        TelephonyManager.APPTYPE_USIM,
-                        TelephonyManager.AUTHTYPE_EAP_SIM,
-                        BASE_64_RAND_1);
-        verifyNoMoreInteractions(mMockEapSimTypeDataDecoder, mMockTelephonyManager);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimCreatedStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimCreatedStateTest.java
deleted file mode 100644
index bdd1920..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimCreatedStateTest.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.CreatedState;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.StartState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class EapSimCreatedStateTest extends EapSimStateTest {
-    private static final int EAP_SIM_START = 10;
-
-    private CreatedState mCreatedState;
-
-    @Before
-    public void setUp() {
-        super.setUp();
-        mCreatedState = mEapSimMethodStateMachine.new CreatedState();
-    }
-
-    @Test
-    public void testProcessSuccess() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-        EapResult result = mCreatedState.process(input);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessFailure() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
-        EapResult result = mCreatedState.process(input);
-        assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState);
-
-        assertTrue(result instanceof EapFailure);
-    }
-
-    @Test
-    public void testTransitionToStartState() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        List<EapSimAkaAttribute> attributes = Arrays.asList(
-                new AtVersionList(8, 1), new AtPermanentIdReq());
-        DecodeResult<EapSimTypeData> decodeResult =
-                new DecodeResult<>(new EapSimTypeData(EAP_SIM_START, attributes));
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        mEapSimMethodStateMachine.process(eapMessage);
-        assertTrue(mEapSimMethodStateMachine.getState() instanceof StartState);
-
-        // decoded in CreatedState and StartState
-        verify(mMockEapSimTypeDataDecoder, times(2)).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockEapSimTypeDataDecoder);
-    }
-
-    @Test
-    public void testProcessIncorrectEapMethodType() throws Exception {
-        EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapResult result = mEapSimMethodStateMachine.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachineTest.java
deleted file mode 100644
index ac1d01c..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimMethodStateMachineTest.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig.EapSimConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.CreatedState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-public class EapSimMethodStateMachineTest {
-    private static final int SUB_ID = 1;
-    private static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566");
-
-    // EAP-Identity = hex("test@android.net")
-    protected static final byte[] EAP_IDENTITY_BYTES =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    private TelephonyManager mMockTelephonyManager;
-    private EapSimTypeDataDecoder mMockEapSimTypeDataDecoder;
-
-    private EapSimConfig mEapSimConfig = new EapSimConfig(SUB_ID, APPTYPE_USIM);
-    private EapSimMethodStateMachine mEapSimMethodStateMachine;
-
-
-    @Before
-    public void setUp() {
-        mMockTelephonyManager = mock(TelephonyManager.class);
-        mMockEapSimTypeDataDecoder = mock(EapSimTypeDataDecoder.class);
-
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-
-        mEapSimMethodStateMachine =
-                new EapSimMethodStateMachine(
-                        mMockTelephonyManager,
-                        EAP_IDENTITY_BYTES,
-                        mEapSimConfig,
-                        new SecureRandom(),
-                        mMockEapSimTypeDataDecoder);
-
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-    }
-
-    @Test
-    public void testEapSimMethodStateMachineStartState() {
-        assertTrue(mEapSimMethodStateMachine.getState() instanceof CreatedState);
-    }
-
-    @Test
-    public void testGetMethod() {
-        assertEquals(EAP_TYPE_SIM, mEapSimMethodStateMachine.getEapMethod());
-    }
-
-    @Test
-    public void testEapSimFailsOnMultipleSimNotifications() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        // First EAP-SIM/Notification
-        EapSimTypeData notificationTypeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE)));
-        DecodeResult<EapSimTypeData> decodeResult = new DecodeResult<>(notificationTypeData);
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapSimMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE, eapResponse.packet);
-        verify(mMockEapSimTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder);
-
-        // Transition to StartState
-        decodeResult =
-                new DecodeResult<>(
-                        new EapSimTypeData(EAP_SIM_START, Arrays.asList(new AtVersionList(8, 1))));
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        eapResponse = (EapResponse) mEapSimMethodStateMachine.process(eapMessage);
-        assertFalse(
-                "EAP-Request/SIM-Start returned a Client-Error response",
-                Arrays.equals(EAP_SIM_CLIENT_ERROR_UNABLE_TO_PROCESS, eapResponse.packet));
-
-        // decoded in: previous 1 time + in CreatedState and StartState
-        verify(mMockEapSimTypeDataDecoder, times(3)).decode(eq(DUMMY_EAP_TYPE_DATA));
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder);
-
-        // Second EAP-SIM/Notification
-        decodeResult = new EapSimAkaTypeData.DecodeResult<>(notificationTypeData);
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapError eapError = (EapError) mEapSimMethodStateMachine.process(eapMessage);
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-
-        // decoded previous 3 times + 1
-        verify(mMockEapSimTypeDataDecoder, times(4)).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStartStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStartStateTest.java
deleted file mode 100644
index ccb746a..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStartStateTest.java
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.message.EapData.EAP_IDENTITY;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_IDENTITY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_RESPONSE_WITHOUT_IDENTITY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.IMSI;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ANY_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_ENCR_DATA;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_IV;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_MAC;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_PERMANENT_ID_REQ;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.EAP_AT_VERSION_LIST;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_START;
-import static com.android.internal.net.eap.message.simaka.attributes.EapTestAttributeDefinitions.NONCE_MT;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.exceptions.simaka.EapSimAkaIdentityUnavailableException;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtAnyIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtIdentity;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtMac;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNonceMt;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtPermanentIdReq;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtVersionList;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.FinalState;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.ChallengeState;
-import com.android.internal.net.eap.statemachine.EapSimMethodStateMachine.StartState;
-import com.android.internal.net.utils.Log;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-
-public class EapSimStartStateTest extends EapSimStateTest {
-
-    private StartState mStartState;
-    private LinkedHashMap<Integer, EapSimAkaAttribute> mAttributes;
-
-    @Before
-    public void setUp() {
-        super.setUp();
-
-        AtNonceMt atNonceMt = null;
-        try {
-            atNonceMt = new AtNonceMt(NONCE_MT);
-        } catch (Exception e) {
-            fail("Failed to create AtNonceMt attribute in setUp()");
-        }
-
-        mStartState = mEapSimMethodStateMachine.new StartState(atNonceMt);
-        mEapSimMethodStateMachine.transitionTo(mStartState);
-
-        mAttributes = new LinkedHashMap<>();
-    }
-
-    @Test
-    public void testProcessSuccess() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_SUCCESS, ID_INT, null);
-        EapResult result = mStartState.process(input);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessFailure() throws Exception {
-        EapMessage input = new EapMessage(EAP_CODE_FAILURE, ID_INT, null);
-        EapResult result = mStartState.process(input);
-        assertTrue(mEapSimMethodStateMachine.getState() instanceof FinalState);
-
-        assertTrue(result instanceof EapFailure);
-    }
-
-    @Test
-    public void testProcessIncorrectEapMethodType() throws Exception {
-        EapData eapData = new EapData(EAP_IDENTITY, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-
-        EapResult result = mStartState.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testIsValidStartAttributes() throws Exception {
-        mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1));
-        mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq());
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        assertTrue(mStartState.isValidStartAttributes(eapSimTypeData));
-    }
-
-    @Test
-    public void testIsValidStartAttributesMissingVersionList() throws Exception {
-        mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq());
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        assertFalse(mStartState.isValidStartAttributes(eapSimTypeData));
-    }
-
-    @Test
-    public void testIsValidStartAttributesMultipleIdRequests() throws Exception {
-        mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1));
-        mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq());
-        mAttributes.put(EAP_AT_ANY_ID_REQ, new AtAnyIdReq());
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        assertFalse(mStartState.isValidStartAttributes(eapSimTypeData));
-    }
-
-    @Test
-    public void testIsValidStartAttributesInvalidAttributes() throws Exception {
-        mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1));
-        mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq());
-        mAttributes.put(EAP_AT_MAC, new AtMac());
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        assertFalse(mStartState.isValidStartAttributes(eapSimTypeData));
-
-        mAttributes.remove(EAP_AT_MAC);
-        mAttributes.put(EAP_AT_IV, null); // just need <K, V> pair in the map
-        eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        assertFalse(mStartState.isValidStartAttributes(eapSimTypeData));
-
-        mAttributes.remove(EAP_AT_IV);
-        mAttributes.put(EAP_AT_ENCR_DATA, null); // just need <K, V> pair in the map
-        eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        assertFalse(mStartState.isValidStartAttributes(eapSimTypeData));
-    }
-
-    @Test
-    public void testAddIdentityAttributeToResponse() throws Exception {
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(
-                EAP_SIM_START, Arrays.asList(new AtPermanentIdReq()));
-
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(IMSI);
-
-        AtIdentity atIdentity = mStartState.getIdentityResponse(eapSimTypeData);
-        assertArrayEquals(EAP_SIM_IDENTITY.getBytes(), mStartState.mIdentity);
-        verify(mMockTelephonyManager).getSubscriberId();
-        assertArrayEquals(EAP_SIM_IDENTITY.getBytes(), atIdentity.identity);
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testAddIdentityAttributeToResponseImsiUnavailable() throws Exception {
-        EapMessage eapMessage = new EapMessage(
-                EAP_CODE_REQUEST,
-                ID_INT,
-                new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA));
-        mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1));
-        mAttributes.put(EAP_AT_PERMANENT_ID_REQ, new AtPermanentIdReq());
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, mAttributes);
-        DecodeResult decodeResult = new DecodeResult(eapSimTypeData);
-
-        when(mMockEapSimTypeDataDecoder.decode(DUMMY_EAP_TYPE_DATA)).thenReturn(decodeResult);
-        when(mMockTelephonyManager.getSubscriberId()).thenReturn(null);
-
-        EapResult result = mStartState.process(eapMessage);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapSimAkaIdentityUnavailableException);
-
-        verify(mMockTelephonyManager).getSubscriberId();
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testAddIdentityAttributeToResponseNoIdRequest() throws Exception {
-        EapSimTypeData eapSimTypeData = new EapSimTypeData(EAP_SIM_START, Arrays.asList());
-
-        AtIdentity atIdentity = mStartState.getIdentityResponse(eapSimTypeData);
-        assertNull(atIdentity);
-        verifyNoMoreInteractions(mMockTelephonyManager);
-    }
-
-    @Test
-    public void testProcessWithoutIdentityRequest() throws Exception {
-        EapMessage eapMessage =
-                new EapMessage(
-                        EAP_CODE_REQUEST, ID_INT, new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA));
-
-        // Send EAP-SIM/Start message without Identity request
-        mAttributes.put(EAP_AT_VERSION_LIST, new AtVersionList(8, 1));
-        DecodeResult eapSimStartDecodeResult =
-                new DecodeResult(new EapSimTypeData(EAP_SIM_START, mAttributes));
-        when(mMockEapSimTypeDataDecoder.decode(DUMMY_EAP_TYPE_DATA))
-                .thenReturn(eapSimStartDecodeResult);
-
-        EapResult result = mEapSimMethodStateMachine.process(eapMessage);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(
-                Log.byteArrayToHexString(eapResponse.packet),
-                EAP_SIM_RESPONSE_WITHOUT_IDENTITY,
-                eapResponse.packet);
-
-        verify(mMockEapSimTypeDataDecoder).decode(eq(DUMMY_EAP_TYPE_DATA));
-
-        // Send EAP-SIM/Challenge message
-        DecodeResult eapSimChallengeDecodeResult =
-                new DecodeResult(new EapSimTypeData(EAP_SIM_CHALLENGE, new LinkedHashMap<>()));
-        when(mMockEapSimTypeDataDecoder.decode(DUMMY_EAP_TYPE_DATA))
-                .thenReturn(eapSimChallengeDecodeResult);
-
-        // We only care about the transition to ChallengeState - the response doesn't matter
-        mEapSimMethodStateMachine.process(eapMessage);
-        ChallengeState challengeState = (ChallengeState) mEapSimMethodStateMachine.getState();
-        assertArrayEquals(EAP_IDENTITY_BYTES, challengeState.mIdentity);
-
-        // verify decode called 3x times:
-        // 1. decode in EAP-SIM/Start test above
-        // 2. decode in EAP-SIM/Challenge test for StartState
-        // 3. decode in EAP-SIM/Challenge test for ChallengeState
-        verify(mMockEapSimTypeDataDecoder, times(3)).decode(eq(DUMMY_EAP_TYPE_DATA));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStateTest.java
deleted file mode 100644
index d8d1841..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapSimStateTest.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-import static com.android.internal.net.eap.message.EapData.EAP_NOTIFICATION;
-import static com.android.internal.net.eap.message.EapData.EAP_TYPE_SIM;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_CLIENT_ERROR_INSUFFICIENT_CHALLENGES;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SIM_NOTIFICATION_RESPONSE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification.GENERAL_FAILURE_PRE_CHALLENGE;
-import static com.android.internal.net.eap.message.simaka.EapSimTypeData.EAP_SIM_NOTIFICATION;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig.EapSimConfig;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.message.EapData;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtClientErrorCode;
-import com.android.internal.net.eap.message.simaka.EapSimAkaAttribute.AtNotification;
-import com.android.internal.net.eap.message.simaka.EapSimAkaTypeData.DecodeResult;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData;
-import com.android.internal.net.eap.message.simaka.EapSimTypeData.EapSimTypeDataDecoder;
-import com.android.internal.net.eap.statemachine.EapMethodStateMachine.EapMethodState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-import java.util.Arrays;
-
-public class EapSimStateTest {
-    protected static final int SUB_ID = 1;
-    protected static final String NOTIFICATION_MESSAGE = "test";
-    protected static final byte[] DUMMY_EAP_TYPE_DATA = hexStringToByteArray("112233445566");
-
-    // EAP-Identity = hex("test@android.net")
-    protected static final byte[] EAP_IDENTITY_BYTES =
-            hexStringToByteArray("7465737440616E64726F69642E6E6574");
-
-    protected TelephonyManager mMockTelephonyManager;
-    protected EapSimTypeDataDecoder mMockEapSimTypeDataDecoder;
-
-    protected EapSimConfig mEapSimConfig = new EapSimConfig(SUB_ID, APPTYPE_USIM);
-    protected EapSimMethodStateMachine mEapSimMethodStateMachine;
-
-    @Before
-    public void setUp() {
-        mMockTelephonyManager = mock(TelephonyManager.class);
-        mMockEapSimTypeDataDecoder = mock(EapSimTypeDataDecoder.class);
-
-        when(mMockTelephonyManager.createForSubscriptionId(SUB_ID))
-                .thenReturn(mMockTelephonyManager);
-
-        mEapSimMethodStateMachine =
-                new EapSimMethodStateMachine(
-                        mMockTelephonyManager,
-                        EAP_IDENTITY_BYTES,
-                        mEapSimConfig,
-                        new SecureRandom(),
-                        mMockEapSimTypeDataDecoder);
-
-        verify(mMockTelephonyManager).createForSubscriptionId(SUB_ID);
-    }
-
-    @Test
-    public void testProcessNotification() throws Exception {
-        EapData eapData = new EapData(EAP_NOTIFICATION, NOTIFICATION_MESSAGE.getBytes());
-        EapMessage notification = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preNotification = (EapMethodState) mEapSimMethodStateMachine.getState();
-
-        EapResult result = mEapSimMethodStateMachine.process(notification);
-        assertEquals(preNotification, mEapSimMethodStateMachine.getState());
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder);
-
-        assertTrue(result instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testProcessEapSimNotification() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preProcess = (EapMethodState) mEapSimMethodStateMachine.getState();
-        EapSimTypeData typeData =
-                new EapSimTypeData(
-                        EAP_SIM_NOTIFICATION,
-                        Arrays.asList(new AtNotification(GENERAL_FAILURE_PRE_CHALLENGE)));
-
-        DecodeResult<EapSimTypeData> decodeResult = new DecodeResult<>(typeData);
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResponse eapResponse = (EapResponse) mEapSimMethodStateMachine.process(eapMessage);
-        assertArrayEquals(EAP_SIM_NOTIFICATION_RESPONSE, eapResponse.packet);
-        assertEquals(preProcess, mEapSimMethodStateMachine.getState());
-        verify(mMockEapSimTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder);
-    }
-
-    @Test
-    public void testProcessInvalidDecodeResult() throws Exception {
-        EapData eapData = new EapData(EAP_TYPE_SIM, DUMMY_EAP_TYPE_DATA);
-        EapMessage eapMessage = new EapMessage(EAP_CODE_REQUEST, ID_INT, eapData);
-        EapMethodState preProcess = (EapMethodState) mEapSimMethodStateMachine.getState();
-
-        AtClientErrorCode atClientErrorCode = AtClientErrorCode.INSUFFICIENT_CHALLENGES;
-        DecodeResult<EapSimTypeData> decodeResult = new DecodeResult<>(atClientErrorCode);
-        when(mMockEapSimTypeDataDecoder.decode(eq(DUMMY_EAP_TYPE_DATA))).thenReturn(decodeResult);
-
-        EapResult result = mEapSimMethodStateMachine.process(eapMessage);
-        assertEquals(preProcess, mEapSimMethodStateMachine.getState());
-        verify(mMockEapSimTypeDataDecoder).decode(DUMMY_EAP_TYPE_DATA);
-        verifyNoMoreInteractions(mMockTelephonyManager, mMockEapSimTypeDataDecoder);
-
-        assertTrue(result instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_SIM_CLIENT_ERROR_INSUFFICIENT_CHALLENGES, eapResponse.packet);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateMachineTest.java
deleted file mode 100644
index 288fc85..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateMachineTest.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
-import static com.android.internal.net.eap.EapTestUtils.getDummyEapSessionConfig;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET;
-
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.statemachine.EapStateMachine.CreatedState;
-import com.android.internal.net.eap.statemachine.EapStateMachine.FailureState;
-import com.android.internal.net.eap.statemachine.EapStateMachine.SuccessState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-
-public class EapStateMachineTest {
-    private Context mContext;
-    private EapSessionConfig mEapSessionConfig;
-
-    @Before
-    public void setUp() {
-        mContext = getInstrumentation().getContext();
-        mEapSessionConfig = getDummyEapSessionConfig();
-    }
-
-    @Test
-    public void testEapStateMachineStartState() {
-        EapStateMachine eapStateMachine =
-                new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom());
-        assertTrue(eapStateMachine.getState() instanceof CreatedState);
-    }
-
-    @Test
-    public void testSuccessStateProcessFails() {
-        SuccessState successState =
-                new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom())
-                .new SuccessState();
-        EapResult result = successState.process(EAP_SUCCESS_PACKET);
-        assertTrue(result instanceof EapError);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testFailureStateProcessFails() {
-        FailureState failureState =
-                new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom())
-                .new FailureState();
-        EapResult result = failureState.process(EAP_SUCCESS_PACKET);
-        assertTrue(result instanceof EapError);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateTest.java
deleted file mode 100644
index 0193cb4..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/EapStateTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static androidx.test.InstrumentationRegistry.getInstrumentation;
-
-import static com.android.internal.net.eap.EapTestUtils.getDummyEapSimSessionConfig;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_MD5_CHALLENGE;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NAK_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.REQUEST_UNSUPPORTED_TYPE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.SHORT_PACKET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-
-import android.content.Context;
-import android.net.eap.EapSessionConfig;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.exceptions.EapInvalidPacketLengthException;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.statemachine.EapStateMachine.EapState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-
-/**
- * EapStateTest is a test template for testing EapState implementations.
- *
- * <p>Specifically, testing for CreatedState, IdentityState, and MethodState should subclass
- * EapStateTest
- */
-public class EapStateTest {
-    protected Context mContext;
-    protected EapSessionConfig mEapSessionConfig;
-    protected EapStateMachine mEapStateMachine;
-    protected EapState mEapState;
-
-    @Before
-    public void setUp() {
-        mContext = getInstrumentation().getContext();
-        mEapSessionConfig = getDummyEapSimSessionConfig();
-        mEapStateMachine = new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom());
-
-        // this EapState definition is used to make sure all non-Success/Failure EAP states
-        // produce the same results for error cases.
-        mEapState = mEapStateMachine.new EapState() {
-            @Override
-            public EapResult process(byte[] msg) {
-                return decode(msg).eapResult;
-            }
-        };
-    }
-
-    @Test
-    public void testProcessNullPacket() {
-        EapResult result = mEapState.process(null);
-        assertTrue(result instanceof EapError);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof IllegalArgumentException);
-    }
-
-    @Test
-    public void testProcessUnsupportedEapDataType() {
-        EapResult result = mEapState.process(REQUEST_UNSUPPORTED_TYPE_PACKET);
-        assertTrue(result instanceof EapResponse);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testProcessDecodeFailure() {
-        EapResult result = mEapState.process(SHORT_PACKET);
-        assertTrue(result instanceof EapError);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidPacketLengthException);
-    }
-
-    @Test
-    public void testProcessResponse() {
-        EapResult result = mEapState.process(EAP_RESPONSE_NOTIFICATION_PACKET);
-        assertTrue(result instanceof EapError);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessNakRequest() {
-        EapResult result = mEapState.process(EAP_REQUEST_NAK_PACKET);
-        assertTrue(result instanceof EapError);
-
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-    }
-
-    @Test
-    public void testProcessMd5Challenge() {
-        EapResult result = mEapState.process(EAP_REQUEST_MD5_CHALLENGE);
-        assertTrue(result instanceof EapResponse);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/IdentityStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/IdentityStateTest.java
deleted file mode 100644
index abe4e82..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/IdentityStateTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static com.android.internal.net.eap.EapTestUtils.getDummyEapSessionConfig;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_IDENTITY;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_IDENTITY_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_IDENTITY_DEFAULT_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_IDENTITY_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.statemachine.EapStateMachine.MethodState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.SecureRandom;
-
-public class IdentityStateTest extends EapStateTest {
-    private EapStateMachine mEapStateMachineSpy;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-
-        mEapStateMachineSpy = spy(mEapStateMachine);
-        mEapState = mEapStateMachineSpy.new IdentityState();
-    }
-
-    @Test
-    public void testProcess() {
-        mEapSessionConfig = getDummyEapSessionConfig(EAP_IDENTITY);
-        mEapStateMachineSpy = spy(
-                new EapStateMachine(mContext, mEapSessionConfig, new SecureRandom()));
-        mEapState = mEapStateMachineSpy.new IdentityState();
-
-        EapResult eapResult = mEapState.process(EAP_REQUEST_IDENTITY_PACKET);
-
-        assertTrue(eapResult instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) eapResult;
-        assertArrayEquals(EAP_RESPONSE_IDENTITY_PACKET, eapResponse.packet);
-        verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any());
-    }
-
-    @Test
-    public void testProcessDefaultIdentity() {
-        EapResult eapResult = mEapState.process(EAP_REQUEST_IDENTITY_PACKET);
-
-        assertTrue(eapResult instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) eapResult;
-        assertArrayEquals(EAP_RESPONSE_IDENTITY_DEFAULT_PACKET, eapResponse.packet);
-        verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any());
-    }
-
-    @Test
-    public void testProcessNotificationRequest() {
-        EapResult eapResult = mEapState.process(EAP_REQUEST_NOTIFICATION_PACKET);
-
-        // state shouldn't change after Notification request
-        assertTrue(eapResult instanceof EapResponse);
-        EapResponse eapResponse = (EapResponse) eapResult;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-        verify(mEapStateMachineSpy, never()).transitionAndProcess(any(), any());
-    }
-
-    @Test
-    public void testProcessSimStart() {
-        mEapState.process(EAP_REQUEST_SIM_START_PACKET);
-
-        // EapStateMachine should change to MethodState for method-type packet
-        verify(mEapStateMachineSpy).transitionAndProcess(
-                any(MethodState.class), eq(EAP_REQUEST_SIM_START_PACKET));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/MethodStateTest.java b/tests/iketests/src/java/com/android/internal/net/eap/statemachine/MethodStateTest.java
deleted file mode 100644
index 9df06e5..0000000
--- a/tests/iketests/src/java/com/android/internal/net/eap/statemachine/MethodStateTest.java
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.eap.statemachine;
-
-import static android.telephony.TelephonyManager.APPTYPE_USIM;
-
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_FAILURE;
-import static com.android.internal.net.eap.message.EapMessage.EAP_CODE_SUCCESS;
-import static com.android.internal.net.eap.message.EapMessage.EAP_HEADER_LENGTH;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_AKA_PRIME_REQUEST;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_FAILURE_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_AKA;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_IDENTITY_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_MSCHAP_V2;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_REQUEST_SIM_START_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NAK_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_RESPONSE_NOTIFICATION_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EAP_SUCCESS_PACKET;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.EMSK;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.ID_INT;
-import static com.android.internal.net.eap.message.EapTestMessageDefinitions.MSK;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.net.eap.EapSessionConfig;
-
-import com.android.internal.net.eap.EapResult;
-import com.android.internal.net.eap.EapResult.EapError;
-import com.android.internal.net.eap.EapResult.EapFailure;
-import com.android.internal.net.eap.EapResult.EapResponse;
-import com.android.internal.net.eap.EapResult.EapSuccess;
-import com.android.internal.net.eap.exceptions.EapInvalidRequestException;
-import com.android.internal.net.eap.message.EapMessage;
-import com.android.internal.net.eap.statemachine.EapStateMachine.FailureState;
-import com.android.internal.net.eap.statemachine.EapStateMachine.MethodState;
-import com.android.internal.net.eap.statemachine.EapStateMachine.SuccessState;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentMatcher;
-
-import java.security.SecureRandom;
-
-public class MethodStateTest extends EapStateTest {
-    private static final String USERNAME = "username";
-    private static final String PASSWORD = "password";
-    private static final String NETWORK_NAME = "android.net";
-    private static final boolean ALLOW_MISMATCHED_NETWORK_NAMES = true;
-
-    @Before
-    @Override
-    public void setUp() {
-        super.setUp();
-        mEapState = mEapStateMachine.new MethodState();
-        mEapStateMachine.transitionTo(mEapState);
-    }
-
-    @Test
-    public void testProcessUnsupportedEapType() {
-        mEapState = mEapStateMachine.new MethodState();
-        EapResult result = mEapState.process(EAP_REQUEST_IDENTITY_PACKET);
-
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NAK_PACKET, eapResponse.packet);
-    }
-
-    @Test
-    public void testProcessTransitionsToEapSim() {
-        mEapStateMachine.process(EAP_REQUEST_SIM_START_PACKET);
-
-        assertTrue(mEapStateMachine.getState() instanceof MethodState);
-        MethodState methodState = (MethodState) mEapStateMachine.getState();
-        assertTrue(methodState.mEapMethodStateMachine instanceof EapSimMethodStateMachine);
-    }
-
-    @Test
-    public void testProcessTransitionToEapAka() {
-        // make EapStateMachine with EAP-AKA configurations
-        EapSessionConfig eapSessionConfig = new EapSessionConfig.Builder()
-                .setEapAkaConfig(0, APPTYPE_USIM).build();
-        mEapStateMachine = new EapStateMachine(mContext, eapSessionConfig, new SecureRandom());
-
-        mEapStateMachine.process(EAP_REQUEST_AKA);
-
-        assertTrue(mEapStateMachine.getState() instanceof MethodState);
-        MethodState methodState = (MethodState) mEapStateMachine.getState();
-        assertTrue(methodState.mEapMethodStateMachine instanceof EapAkaMethodStateMachine);
-    }
-
-    @Test
-    public void testProcessTransitionToEapAkaPrime() {
-        // make EapStateMachine with EAP-AKA' configurations
-        EapSessionConfig eapSessionConfig =
-                new EapSessionConfig.Builder()
-                        .setEapAkaPrimeConfig(
-                                0, APPTYPE_USIM, NETWORK_NAME, ALLOW_MISMATCHED_NETWORK_NAMES)
-                        .build();
-        mEapStateMachine = new EapStateMachine(mContext, eapSessionConfig, new SecureRandom());
-
-        mEapStateMachine.process(EAP_AKA_PRIME_REQUEST);
-
-        assertTrue(mEapStateMachine.getState() instanceof MethodState);
-        MethodState methodState = (MethodState) mEapStateMachine.getState();
-        assertTrue(methodState.mEapMethodStateMachine instanceof EapAkaPrimeMethodStateMachine);
-    }
-
-    @Test
-    public void testProcessTransitionToEapMsChapV2() {
-        // make EapStateMachine with EAP MSCHAPv2 configurations
-        EapSessionConfig eapSessionConfig =
-                new EapSessionConfig.Builder().setEapMsChapV2Config(USERNAME, PASSWORD).build();
-        mEapStateMachine = new EapStateMachine(mContext, eapSessionConfig, new SecureRandom());
-
-        mEapStateMachine.process(EAP_REQUEST_MSCHAP_V2);
-
-        assertTrue(mEapStateMachine.getState() instanceof MethodState);
-        MethodState methodState = (MethodState) mEapStateMachine.getState();
-        assertTrue(methodState.mEapMethodStateMachine instanceof EapMsChapV2MethodStateMachine);
-    }
-
-    @Test
-    public void testProcessTransitionToSuccessState() {
-        EapSuccess eapSuccess = new EapSuccess(MSK, EMSK);
-
-        ArgumentMatcher<EapMessage> eapSuccessMatcher = msg ->
-                msg.eapCode == EAP_CODE_SUCCESS
-                        && msg.eapIdentifier == ID_INT
-                        && msg.eapLength == EAP_HEADER_LENGTH
-                        && msg.eapData == null;
-
-        EapMethodStateMachine mockEapMethodStateMachine = mock(EapMethodStateMachine.class);
-        when(mockEapMethodStateMachine.process(argThat(eapSuccessMatcher))).thenReturn(eapSuccess);
-        ((MethodState) mEapState).mEapMethodStateMachine = mockEapMethodStateMachine;
-
-        mEapState.process(EAP_SUCCESS_PACKET);
-        verify(mockEapMethodStateMachine).process(argThat(eapSuccessMatcher));
-        assertTrue(mEapStateMachine.getState() instanceof SuccessState);
-        verifyNoMoreInteractions(mockEapMethodStateMachine);
-    }
-
-    @Test
-    public void testProcessTransitionToFailureState() {
-        EapFailure eapFailure = new EapFailure();
-
-        ArgumentMatcher<EapMessage> eapSuccessMatcher = msg ->
-                msg.eapCode == EAP_CODE_FAILURE
-                        && msg.eapIdentifier == ID_INT
-                        && msg.eapLength == EAP_HEADER_LENGTH
-                        && msg.eapData == null;
-
-        EapMethodStateMachine mockEapMethodStateMachine = mock(EapMethodStateMachine.class);
-        when(mockEapMethodStateMachine.process(argThat(eapSuccessMatcher))).thenReturn(eapFailure);
-        ((MethodState) mEapState).mEapMethodStateMachine = mockEapMethodStateMachine;
-
-        mEapState.process(EAP_FAILURE_PACKET);
-        verify(mockEapMethodStateMachine).process(argThat(eapSuccessMatcher));
-        assertTrue(mEapStateMachine.getState() instanceof FailureState);
-        verifyNoMoreInteractions(mockEapMethodStateMachine);
-    }
-
-    @Test
-    public void testProcessEapFailureWithNoEapMethodState() {
-        EapResult result = mEapStateMachine.process(EAP_FAILURE_PACKET);
-        assertTrue(result instanceof EapFailure);
-        assertTrue(mEapStateMachine.getState() instanceof FailureState);
-    }
-
-    @Test
-    public void testProcessEapSuccessWithNoEapMethodState() {
-        EapResult result = mEapStateMachine.process(EAP_SUCCESS_PACKET);
-        EapError eapError = (EapError) result;
-        assertTrue(eapError.cause instanceof EapInvalidRequestException);
-        assertTrue(mEapStateMachine.getState() instanceof MethodState);
-    }
-
-    @Test
-    public void testProcessEapNotificationWithNoEapMethodState() {
-        EapResult result = mEapStateMachine.process(EAP_REQUEST_NOTIFICATION_PACKET);
-        EapResponse eapResponse = (EapResponse) result;
-        assertArrayEquals(EAP_RESPONSE_NOTIFICATION_PACKET, eapResponse.packet);
-        assertTrue(mEapStateMachine.getState() instanceof MethodState);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineTest.java
deleted file mode 100644
index f6c32ee..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/ChildSessionStateMachineTest.java
+++ /dev/null
@@ -1,1646 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
-import static android.system.OsConstants.AF_INET;
-
-import static com.android.internal.net.ipsec.ike.ChildSessionStateMachine.CMD_FORCE_TRANSITION;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_CP;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_DELETE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_KE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NONCE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_SA;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_TS_INITIATOR;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_TS_RESPONDER;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_ESP;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.argThat;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.IpSecTransform;
-import android.net.LinkAddress;
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionConfiguration;
-import android.net.ipsec.ike.ChildSessionOptions;
-import android.net.ipsec.ike.IkeManager;
-import android.net.ipsec.ike.IkeTrafficSelector;
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.TunnelModeChildSessionOptions;
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeInternalException;
-import android.os.test.TestLooper;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.CreateChildSaHelper;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.IChildSessionSmCallback;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecord;
-import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecordConfig;
-import com.android.internal.net.ipsec.ike.SaRecord.ISaRecordHelper;
-import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidKeException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
-import com.android.internal.net.ipsec.ike.message.IkeDeletePayload;
-import com.android.internal.net.ipsec.ike.message.IkeKePayload;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeNoncePayload;
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.message.IkeTestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeTsPayload;
-import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
-import com.android.internal.net.utils.Log;
-import com.android.server.IpSecService;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
-
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.security.GeneralSecurityException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-public final class ChildSessionStateMachineTest {
-    private static final String TAG = "ChildSessionStateMachineTest";
-
-    private static final Inet4Address LOCAL_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private static final Inet4Address REMOTE_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-    private static final Inet4Address INTERNAL_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("203.0.113.100"));
-
-    private static final int IPV4_PREFIX_LEN = 32;
-
-    private static final String IKE_AUTH_RESP_SA_PAYLOAD =
-            "2c00002c0000002801030403cae7019f0300000c0100000c800e0080"
-                    + "03000008030000020000000805000000";
-    private static final String REKEY_CHILD_RESP_SA_PAYLOAD =
-            "2800002c0000002801030403cd1736b30300000c0100000c800e0080"
-                    + "03000008030000020000000805000000";
-    private static final String REKEY_CHILD_REQ_SA_PAYLOAD =
-            "2800002c0000002801030403c88336490300000c0100000c800e0080"
-                    + "03000008030000020000000805000000";
-    private static final String REKEY_CHILD_UNACCEPTABLE_REQ_SA_PAYLOAD =
-            "2800002c0000002801030403c88336490300000c0100000c800e00c0"
-                    + "03000008030000020000000805000000";
-
-    private static final int CURRENT_CHILD_SA_SPI_IN = 0x2ad4c0a2;
-    private static final int CURRENT_CHILD_SA_SPI_OUT = 0xcae7019f;
-
-    private static final int LOCAL_INIT_NEW_CHILD_SA_SPI_IN = 0x57a09b0f;
-    private static final int LOCAL_INIT_NEW_CHILD_SA_SPI_OUT = 0xcd1736b3;
-
-    private static final int REMOTE_INIT_NEW_CHILD_SA_SPI_IN = 0xd2d01795;
-    private static final int REMOTE_INIT_NEW_CHILD_SA_SPI_OUT = 0xc8833649;
-
-    private static final String IKE_SK_D_HEX_STRING = "C86B56EFCF684DCC2877578AEF3137167FE0EBF6";
-    private static final byte[] SK_D = TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING);
-
-    private static final int KEY_LEN_IKE_SKD = 20;
-
-    private IkeMacPrf mIkePrf;
-
-    private Context mContext;
-    private IpSecService mMockIpSecService;
-    private IpSecManager mMockIpSecManager;
-    private UdpEncapsulationSocket mMockUdpEncapSocket;
-
-    private TestLooper mLooper;
-    private ChildSessionStateMachine mChildSessionStateMachine;
-
-    private List<IkePayload> mFirstSaReqPayloads = new LinkedList<>();
-    private List<IkePayload> mFirstSaRespPayloads = new LinkedList<>();
-
-    private ChildSaRecord mSpyCurrentChildSaRecord;
-    private ChildSaRecord mSpyLocalInitNewChildSaRecord;
-    private ChildSaRecord mSpyRemoteInitNewChildSaRecord;
-
-    private Log mSpyIkeLog;
-
-    private ISaRecordHelper mMockSaRecordHelper;
-
-    private ChildSessionOptions mChildSessionOptions;
-    private EncryptionTransform mChildEncryptionTransform;
-    private IntegrityTransform mChildIntegrityTransform;
-    private DhGroupTransform mChildDhGroupTransform;
-
-    private ChildSaProposal mMockNegotiatedProposal;
-
-    private Executor mSpyUserCbExecutor;
-    private ChildSessionCallback mMockChildSessionCallback;
-    private IChildSessionSmCallback mMockChildSessionSmCallback;
-
-    private ArgumentCaptor<ChildSaRecordConfig> mChildSaRecordConfigCaptor =
-            ArgumentCaptor.forClass(ChildSaRecordConfig.class);
-    private ArgumentCaptor<List<IkePayload>> mPayloadListCaptor =
-            ArgumentCaptor.forClass(List.class);
-    private ArgumentCaptor<ChildSessionConfiguration> mChildConfigCaptor =
-            ArgumentCaptor.forClass(ChildSessionConfiguration.class);
-
-    private ArgumentMatcher<ChildLocalRequest> mRekeyChildLocalReqMatcher =
-            (argument) -> {
-                return CMD_LOCAL_REQUEST_REKEY_CHILD == argument.procedureType
-                        && mMockChildSessionCallback == argument.childSessionCallback;
-            };
-
-    public ChildSessionStateMachineTest() {
-        mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class);
-        mMockChildSessionSmCallback = mock(IChildSessionSmCallback.class);
-
-        mChildEncryptionTransform =
-                new EncryptionTransform(
-                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128);
-        mChildIntegrityTransform =
-                new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96);
-
-        mChildDhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP);
-    }
-
-    @Before
-    public void setup() throws Exception {
-        mSpyIkeLog = TestUtils.makeSpyLogThrowExceptionForWtf(TAG);
-        IkeManager.setIkeLog(mSpyIkeLog);
-
-        mIkePrf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-
-        mContext = InstrumentationRegistry.getContext();
-        mMockIpSecService = mock(IpSecService.class);
-        mMockIpSecManager = new IpSecManager(mContext, mMockIpSecService);
-        mMockUdpEncapSocket = mock(UdpEncapsulationSocket.class);
-
-        mMockNegotiatedProposal = mock(ChildSaProposal.class);
-
-        mSpyUserCbExecutor =
-                spy(
-                        (command) -> {
-                            command.run();
-                        });
-
-        mMockChildSessionCallback = mock(ChildSessionCallback.class);
-        mChildSessionOptions = buildChildSessionOptions();
-
-        // Setup thread and looper
-        mLooper = new TestLooper();
-        mChildSessionStateMachine =
-                new ChildSessionStateMachine(
-                        mLooper.getLooper(),
-                        mContext,
-                        mMockIpSecManager,
-                        mChildSessionOptions,
-                        mSpyUserCbExecutor,
-                        mMockChildSessionCallback,
-                        mMockChildSessionSmCallback);
-        mChildSessionStateMachine.setDbg(true);
-        SaRecord.setSaRecordHelper(mMockSaRecordHelper);
-
-        setUpFirstSaNegoPayloadLists();
-        setUpChildSaRecords();
-
-        mChildSessionStateMachine.start();
-    }
-
-    @After
-    public void tearDown() {
-        mChildSessionStateMachine.setDbg(false);
-        IkeManager.resetIkeLog();
-        SaRecord.setSaRecordHelper(new SaRecordHelper());
-    }
-
-    private ChildSaProposal buildSaProposal() throws Exception {
-        return new ChildSaProposal.Builder()
-                .addEncryptionAlgorithm(
-                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
-                .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
-                .build();
-    }
-
-    private ChildSessionOptions buildChildSessionOptions() throws Exception {
-        return new TunnelModeChildSessionOptions.Builder()
-                .addSaProposal(buildSaProposal())
-                .addInternalAddressRequest(AF_INET, 1)
-                .addInternalAddressRequest(INTERNAL_ADDRESS, IPV4_PREFIX_LEN)
-                .build();
-    }
-
-    private void setUpChildSaRecords() {
-        mSpyCurrentChildSaRecord =
-                makeSpyChildSaRecord(CURRENT_CHILD_SA_SPI_IN, CURRENT_CHILD_SA_SPI_OUT);
-        mSpyLocalInitNewChildSaRecord =
-                makeSpyChildSaRecord(
-                        LOCAL_INIT_NEW_CHILD_SA_SPI_IN, LOCAL_INIT_NEW_CHILD_SA_SPI_OUT);
-        mSpyRemoteInitNewChildSaRecord =
-                makeSpyChildSaRecord(
-                        REMOTE_INIT_NEW_CHILD_SA_SPI_IN, REMOTE_INIT_NEW_CHILD_SA_SPI_OUT);
-    }
-
-    private void setUpSpiResource(InetAddress address, int spiRequested) throws Exception {
-        when(mMockIpSecService.allocateSecurityParameterIndex(
-                        eq(address.getHostAddress()), anyInt(), anyObject()))
-                .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(spiRequested));
-    }
-
-    private void setUpFirstSaNegoPayloadLists() throws Exception {
-        // Build locally generated SA payload that has its SPI resource allocated.
-        setUpSpiResource(LOCAL_ADDRESS, CURRENT_CHILD_SA_SPI_IN);
-        IkeSaPayload reqSaPayload =
-                IkeSaPayload.createChildSaRequestPayload(
-                        mChildSessionOptions.getSaProposals(), mMockIpSecManager, LOCAL_ADDRESS);
-        mFirstSaReqPayloads.add(reqSaPayload);
-
-        // Build a remotely generated SA payload whoes SPI resource has not been allocated.
-        setUpSpiResource(REMOTE_ADDRESS, CURRENT_CHILD_SA_SPI_OUT);
-        IkeSaPayload respSaPayload =
-                (IkeSaPayload)
-                        (IkeTestUtils.hexStringToIkePayload(
-                                IkePayload.PAYLOAD_TYPE_SA, true, IKE_AUTH_RESP_SA_PAYLOAD));
-        mFirstSaRespPayloads.add(respSaPayload);
-
-        // Build TS Payloads
-        IkeTsPayload tsInitPayload =
-                new IkeTsPayload(
-                        true /*isInitiator*/, mChildSessionOptions.getLocalTrafficSelectors());
-        IkeTsPayload tsRespPayload =
-                new IkeTsPayload(
-                        false /*isInitiator*/, mChildSessionOptions.getRemoteTrafficSelectors());
-
-        mFirstSaReqPayloads.add(tsInitPayload);
-        mFirstSaReqPayloads.add(tsRespPayload);
-        mFirstSaRespPayloads.add(tsInitPayload);
-        mFirstSaRespPayloads.add(tsRespPayload);
-
-        // Build Nonce Payloads
-        mFirstSaReqPayloads.add(new IkeNoncePayload());
-        mFirstSaRespPayloads.add(new IkeNoncePayload());
-
-        // Build Config Request Payload
-        List<ConfigAttribute> attrReqList = new LinkedList<>();
-        attrReqList.add(new ConfigAttributeIpv4Address(INTERNAL_ADDRESS));
-        attrReqList.add(new ConfigAttributeIpv4Netmask());
-        mFirstSaReqPayloads.add(new IkeConfigPayload(false /*isReply*/, attrReqList));
-
-        // Build Config Reply Payload
-        List<ConfigAttribute> attrRespList = new LinkedList<>();
-        attrRespList.add(new ConfigAttributeIpv4Address(INTERNAL_ADDRESS));
-        mFirstSaRespPayloads.add(new IkeConfigPayload(true /*isReply*/, attrRespList));
-    }
-
-    private ChildSaRecord makeSpyChildSaRecord(int inboundSpi, int outboundSpi) {
-        ChildSaRecord child =
-                spy(
-                        new ChildSaRecord(
-                                inboundSpi,
-                                outboundSpi,
-                                true /*localInit*/,
-                                null,
-                                null,
-                                null,
-                                null,
-                                null,
-                                null,
-                                mock(IpSecTransform.class),
-                                mock(IpSecTransform.class),
-                                mock(ChildLocalRequest.class)));
-        doNothing().when(child).close();
-        return child;
-    }
-
-    private void quitAndVerify() {
-        mChildSessionStateMachine.mCurrentChildSaRecord = null;
-        mChildSessionStateMachine.mLocalInitNewChildSaRecord = null;
-        mChildSessionStateMachine.mRemoteInitNewChildSaRecord = null;
-
-        reset(mMockChildSessionSmCallback);
-        mChildSessionStateMachine.quit();
-        mLooper.dispatchAll();
-
-        verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine);
-        verify(mMockChildSessionSmCallback).onChildSessionClosed(mMockChildSessionCallback);
-    }
-
-    private void verifyChildSaRecordConfig(
-            ChildSaRecordConfig childSaRecordConfig,
-            int initSpi,
-            int respSpi,
-            boolean isLocalInit) {
-        assertEquals(mContext, childSaRecordConfig.context);
-        assertEquals(initSpi, childSaRecordConfig.initSpi.getSpi());
-        assertEquals(respSpi, childSaRecordConfig.respSpi.getSpi());
-
-        if (isLocalInit) {
-            assertEquals(LOCAL_ADDRESS, childSaRecordConfig.initAddress);
-            assertEquals(REMOTE_ADDRESS, childSaRecordConfig.respAddress);
-        } else {
-            assertEquals(REMOTE_ADDRESS, childSaRecordConfig.initAddress);
-            assertEquals(LOCAL_ADDRESS, childSaRecordConfig.respAddress);
-        }
-
-        assertEquals(mMockUdpEncapSocket, childSaRecordConfig.udpEncapSocket);
-        assertEquals(mIkePrf, childSaRecordConfig.ikePrf);
-        assertArrayEquals(SK_D, childSaRecordConfig.skD);
-        assertFalse(childSaRecordConfig.isTransport);
-        assertEquals(isLocalInit, childSaRecordConfig.isLocalInit);
-        assertTrue(childSaRecordConfig.hasIntegrityAlgo);
-        assertEquals(
-                CMD_LOCAL_REQUEST_REKEY_CHILD, childSaRecordConfig.futureRekeyEvent.procedureType);
-        assertEquals(
-                mMockChildSessionCallback,
-                childSaRecordConfig.futureRekeyEvent.childSessionCallback);
-    }
-
-    private void verifyNotifyUsersCreateIpSecSa(
-            ChildSaRecord childSaRecord, boolean expectInbound) {
-        IpSecTransform transform =
-                expectInbound
-                        ? childSaRecord.getInboundIpSecTransform()
-                        : childSaRecord.getOutboundIpSecTransform();
-        int direction = expectInbound ? IpSecManager.DIRECTION_IN : IpSecManager.DIRECTION_OUT;
-
-        verify(mMockChildSessionCallback).onIpSecTransformCreated(eq(transform), eq(direction));
-    }
-
-    private void verifyInitCreateChildResp(
-            List<IkePayload> reqPayloads, List<IkePayload> respPayloads) throws Exception {
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(
-                        mSpyCurrentChildSaRecord.getRemoteSpi(), mChildSessionStateMachine);
-        verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine);
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-
-        // Validate negotiated SA proposal.
-        ChildSaProposal negotiatedProposal = mChildSessionStateMachine.mSaProposal;
-        assertNotNull(negotiatedProposal);
-        assertEquals(
-                new EncryptionTransform[] {mChildEncryptionTransform},
-                negotiatedProposal.getEncryptionTransforms());
-        assertEquals(
-                new IntegrityTransform[] {mChildIntegrityTransform},
-                negotiatedProposal.getIntegrityTransforms());
-
-        // Validate current ChildSaRecord
-        verify(mMockSaRecordHelper)
-                .makeChildSaRecord(
-                        eq(reqPayloads), eq(respPayloads), mChildSaRecordConfigCaptor.capture());
-        ChildSaRecordConfig childSaRecordConfig = mChildSaRecordConfigCaptor.getValue();
-
-        verifyChildSaRecordConfig(
-                childSaRecordConfig,
-                CURRENT_CHILD_SA_SPI_IN,
-                CURRENT_CHILD_SA_SPI_OUT,
-                true /*isLocalInit*/);
-
-        assertEquals(mSpyCurrentChildSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord);
-
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine));
-        verify(mMockChildSessionSmCallback)
-                .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong());
-        verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine);
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-
-        // Verify users have been notified
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verifyNotifyUsersCreateIpSecSa(mSpyCurrentChildSaRecord, true /*expectInbound*/);
-        verifyNotifyUsersCreateIpSecSa(mSpyCurrentChildSaRecord, false /*expectInbound*/);
-        verify(mMockChildSessionCallback).onOpened(mChildConfigCaptor.capture());
-
-        // Verify Child Session Configuration
-        ChildSessionConfiguration sessionConfig = mChildConfigCaptor.getValue();
-        verifyTsList(
-                Arrays.asList(mChildSessionOptions.getLocalTrafficSelectors()),
-                sessionConfig.getInboundTrafficSelectors());
-        verifyTsList(
-                Arrays.asList(mChildSessionOptions.getRemoteTrafficSelectors()),
-                sessionConfig.getOutboundTrafficSelectors());
-
-        List<LinkAddress> addrList = sessionConfig.getInternalAddressList();
-        assertEquals(1, addrList.size());
-        assertEquals(INTERNAL_ADDRESS, addrList.get(0).getAddress());
-        assertEquals(IPV4_PREFIX_LEN, addrList.get(0).getPrefixLength());
-    }
-
-    private void verifyTsList(
-            List<IkeTrafficSelector> expectedList, List<IkeTrafficSelector> tsList) {
-        assertEquals(expectedList.size(), tsList.size());
-        for (int i = 0; i < expectedList.size(); i++) {
-            assertEquals(expectedList.get(i), tsList.get(i));
-        }
-    }
-
-    @Test
-    public void testCreateFirstChild() throws Exception {
-        when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any()))
-                .thenReturn(mSpyCurrentChildSaRecord);
-
-        mChildSessionStateMachine.handleFirstChildExchange(
-                mFirstSaReqPayloads,
-                mFirstSaRespPayloads,
-                LOCAL_ADDRESS,
-                REMOTE_ADDRESS,
-                mMockUdpEncapSocket,
-                mIkePrf,
-                SK_D);
-        mLooper.dispatchAll();
-
-        verifyInitCreateChildResp(mFirstSaReqPayloads, mFirstSaRespPayloads);
-
-        quitAndVerify();
-    }
-
-    private void verifyOutboundCreatePayloadTypes(
-            List<IkePayload> outboundPayloads, boolean isRekey) {
-        assertNotNull(
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_SA, IkeSaPayload.class, outboundPayloads));
-        assertNotNull(
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class, outboundPayloads));
-        assertNotNull(
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class, outboundPayloads));
-        assertNotNull(
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_NONCE, IkeNoncePayload.class, outboundPayloads));
-        assertNull(
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_KE, IkeKePayload.class, outboundPayloads));
-
-        IkeConfigPayload configPayload =
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_CP, IkeConfigPayload.class, outboundPayloads);
-        if (isRekey) {
-            assertNull(configPayload);
-        } else {
-            assertNotNull(configPayload);
-            assertEquals(IkeConfigPayload.CONFIG_TYPE_REQUEST, configPayload.configType);
-        }
-    }
-
-    @Test
-    public void testCreateChild() throws Exception {
-        when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any()))
-                .thenReturn(mSpyCurrentChildSaRecord);
-
-        mChildSessionStateMachine.createChildSession(
-                LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D);
-        mLooper.dispatchAll();
-
-        // Validate outbound payload list
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_CREATE_CHILD_SA),
-                        eq(false),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-
-        List<IkePayload> reqPayloadList = mPayloadListCaptor.getValue();
-        verifyOutboundCreatePayloadTypes(reqPayloadList, false /*isRekey*/);
-        assertTrue(
-                IkePayload.getPayloadListForTypeInProvidedList(
-                                PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, reqPayloadList)
-                        .isEmpty());
-
-        mChildSessionStateMachine.receiveResponse(
-                EXCHANGE_TYPE_CREATE_CHILD_SA, mFirstSaRespPayloads);
-        mLooper.dispatchAll();
-
-        verifyInitCreateChildResp(reqPayloadList, mFirstSaRespPayloads);
-
-        quitAndVerify();
-    }
-
-    private <T extends IkeException> void verifyHandleFatalErrorAndQuit(Class<T> exceptionClass) {
-        assertNull(mChildSessionStateMachine.getCurrentState());
-        verify(mMockChildSessionSmCallback).onProcedureFinished(mChildSessionStateMachine);
-        verify(mMockChildSessionSmCallback).onChildSessionClosed(mMockChildSessionCallback);
-
-        verify(mMockChildSessionCallback).onClosedExceptionally(any(exceptionClass));
-    }
-
-    @Test
-    public void testCreateChildHandlesErrorNotifyResp() throws Exception {
-        // Send out Create request
-        mChildSessionStateMachine.createChildSession(
-                LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D);
-        mLooper.dispatchAll();
-
-        // Receive error notification in Create response
-        IkeNotifyPayload notifyPayload = new IkeNotifyPayload(ERROR_TYPE_NO_PROPOSAL_CHOSEN);
-        List<IkePayload> respPayloads = new LinkedList<>();
-        respPayloads.add(notifyPayload);
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads);
-        mLooper.dispatchAll();
-
-        // Verify no SPI for provisional Child was registered.
-        verify(mMockChildSessionSmCallback, never())
-                .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine));
-
-        // Verify user was notified and state machine has quit.
-        verifyHandleFatalErrorAndQuit(NoValidProposalChosenException.class);
-    }
-
-    @Test
-    public void testCreateChildHandlesRespWithMissingPayload() throws Exception {
-        // Send out Create request
-        mChildSessionStateMachine.createChildSession(
-                LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D);
-        mLooper.dispatchAll();
-
-        // Receive response with no Nonce Payload
-        List<IkePayload> respPayloads = new LinkedList<>();
-        for (IkePayload payload : mFirstSaRespPayloads) {
-            if (IkePayload.PAYLOAD_TYPE_NONCE == payload.payloadType) continue;
-            respPayloads.add(payload);
-        }
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads);
-        mLooper.dispatchAll();
-
-        // Verify SPI for provisional Child was registered and unregistered.
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(CURRENT_CHILD_SA_SPI_OUT, mChildSessionStateMachine);
-        verify(mMockChildSessionSmCallback).onChildSaDeleted(CURRENT_CHILD_SA_SPI_OUT);
-
-        // Verify user was notified and state machine has quit.
-        verifyHandleFatalErrorAndQuit(InvalidSyntaxException.class);
-    }
-
-    @Test
-    public void testCreateChildHandlesKeyCalculationFail() throws Exception {
-        // Throw exception when building ChildSaRecord
-        when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any()))
-                .thenThrow(
-                        new GeneralSecurityException("testCreateChildHandlesKeyCalculationFail"));
-
-        // Send out and receive Create Child message
-        mChildSessionStateMachine.createChildSession(
-                LOCAL_ADDRESS, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D);
-        mLooper.dispatchAll();
-        mChildSessionStateMachine.receiveResponse(
-                EXCHANGE_TYPE_CREATE_CHILD_SA, mFirstSaRespPayloads);
-        mLooper.dispatchAll();
-
-        // Verify SPI for provisional Child was registered and unregistered.
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(CURRENT_CHILD_SA_SPI_OUT, mChildSessionStateMachine);
-        verify(mMockChildSessionSmCallback).onChildSaDeleted(CURRENT_CHILD_SA_SPI_OUT);
-
-        // Verify user was notified and state machine has quit.
-        verifyHandleFatalErrorAndQuit(IkeInternalException.class);
-    }
-
-    private void setupIdleStateMachine() throws Exception {
-        mChildSessionStateMachine.mLocalAddress = LOCAL_ADDRESS;
-        mChildSessionStateMachine.mRemoteAddress = REMOTE_ADDRESS;
-        mChildSessionStateMachine.mUdpEncapSocket = mMockUdpEncapSocket;
-        mChildSessionStateMachine.mIkePrf = mIkePrf;
-        mChildSessionStateMachine.mSkD = SK_D;
-
-        mChildSessionStateMachine.mSaProposal = buildSaProposal();
-        mChildSessionStateMachine.mChildCipher = mock(IkeCipher.class);
-        mChildSessionStateMachine.mChildIntegrity = mock(IkeMacIntegrity.class);
-        mChildSessionStateMachine.mLocalTs = mChildSessionOptions.getLocalTrafficSelectors();
-        mChildSessionStateMachine.mRemoteTs = mChildSessionOptions.getRemoteTrafficSelectors();
-
-        mChildSessionStateMachine.mCurrentChildSaRecord = mSpyCurrentChildSaRecord;
-
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-    }
-
-    private List<IkePayload> makeDeletePayloads(int spi) {
-        List<IkePayload> inboundPayloads = new ArrayList<>(1);
-        inboundPayloads.add(new IkeDeletePayload(new int[] {spi}));
-        return inboundPayloads;
-    }
-
-    private void verifyOutboundDeletePayload(int expectedSpi, boolean isResp) {
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_INFORMATIONAL),
-                        eq(isResp),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-
-        List<IkePayload> outPayloadList = mPayloadListCaptor.getValue();
-        assertEquals(1, outPayloadList.size());
-
-        List<IkeDeletePayload> deletePayloads =
-                IkePayload.getPayloadListForTypeInProvidedList(
-                        PAYLOAD_TYPE_DELETE, IkeDeletePayload.class, outPayloadList);
-        assertEquals(1, deletePayloads.size());
-        IkeDeletePayload deletePayload = deletePayloads.get(0);
-        assertEquals(expectedSpi, deletePayload.spisToDelete[0]);
-    }
-
-    private void verifyNotifyUserDeleteChildSa(ChildSaRecord childSaRecord) {
-        verify(mMockChildSessionCallback)
-                .onIpSecTransformDeleted(
-                        eq(childSaRecord.getInboundIpSecTransform()),
-                        eq(IpSecManager.DIRECTION_IN));
-        verify(mMockChildSessionCallback)
-                .onIpSecTransformDeleted(
-                        eq(childSaRecord.getOutboundIpSecTransform()),
-                        eq(IpSecManager.DIRECTION_OUT));
-    }
-
-    private void verifyNotifyUsersDeleteSession() {
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockChildSessionCallback).onClosed();
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-    }
-
-    @Test
-    public void testDeleteChildLocal() throws Exception {
-        setupIdleStateMachine();
-
-        // Test initiating Delete request
-        mChildSessionStateMachine.deleteChildSession();
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.DeleteChildLocalDelete);
-        verifyOutboundDeletePayload(mSpyCurrentChildSaRecord.getLocalSpi(), false /*isResp*/);
-
-        // Test receiving Delete response
-        mChildSessionStateMachine.receiveResponse(
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-
-        verifyNotifyUsersDeleteSession();
-    }
-
-    @Test
-    public void testDeleteChildLocalHandlesInvalidResp() throws Exception {
-        setupIdleStateMachine();
-
-        // Test initiating Delete request
-        mChildSessionStateMachine.deleteChildSession();
-        mLooper.dispatchAll();
-
-        // Test receiving response with no Delete Payload
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_INFORMATIONAL, new LinkedList<>());
-        mLooper.dispatchAll();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-        verify(mMockChildSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-    }
-
-    @Test
-    public void testDeleteChildLocalInInitial() throws Exception {
-        mChildSessionStateMachine.deleteChildSession();
-        mLooper.dispatchAll();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockChildSessionCallback).onClosed();
-    }
-
-    @Test
-    public void testSimultaneousDeleteChild() throws Exception {
-        setupIdleStateMachine();
-
-        mChildSessionStateMachine.deleteChildSession();
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_INFORMATIONAL),
-                        eq(true),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-        List<IkePayload> respPayloadList = mPayloadListCaptor.getValue();
-        assertTrue(respPayloadList.isEmpty());
-
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_INFORMATIONAL, new LinkedList<>());
-        mLooper.dispatchAll();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-
-        verifyNotifyUsersDeleteSession();
-    }
-
-    @Test
-    public void testReplyRekeyRequestDuringDeletion() throws Exception {
-        setupIdleStateMachine();
-
-        mChildSessionStateMachine.deleteChildSession();
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, mock(List.class));
-        mLooper.dispatchAll();
-
-        // Verify outbound response to Rekey Child request
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_INFORMATIONAL),
-                        eq(true),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-        List<IkePayload> respPayloadList = mPayloadListCaptor.getValue();
-        assertEquals(1, respPayloadList.size());
-
-        IkeNotifyPayload notifyPayload = (IkeNotifyPayload) respPayloadList.get(0);
-        assertEquals(ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType);
-        assertEquals(0, notifyPayload.notifyData.length);
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.DeleteChildLocalDelete);
-    }
-
-    @Test
-    public void testDeleteChildRemote() throws Exception {
-        setupIdleStateMachine();
-
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-        // Verify response
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_INFORMATIONAL),
-                        eq(true),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-        List<IkePayload> respPayloadList = mPayloadListCaptor.getValue();
-
-        assertEquals(1, respPayloadList.size());
-        assertArrayEquals(
-                new int[] {mSpyCurrentChildSaRecord.getLocalSpi()},
-                ((IkeDeletePayload) respPayloadList.get(0)).spisToDelete);
-
-        verifyNotifyUsersDeleteSession();
-    }
-
-    private void verifyOutboundRekeySaPayload(List<IkePayload> outboundPayloads, boolean isResp) {
-        IkeSaPayload saPayload =
-                IkePayload.getPayloadForTypeInProvidedList(
-                        PAYLOAD_TYPE_SA, IkeSaPayload.class, outboundPayloads);
-        assertEquals(isResp, saPayload.isSaResponse);
-        assertEquals(1, saPayload.proposalList.size());
-
-        IkeSaPayload.ChildProposal proposal =
-                (IkeSaPayload.ChildProposal) saPayload.proposalList.get(0);
-        assertEquals(1, proposal.number); // Must be 1-indexed
-        assertEquals(mChildSessionStateMachine.mSaProposal, proposal.saProposal);
-    }
-
-    private void verifyOutboundRekeyNotifyPayload(List<IkePayload> outboundPayloads) {
-        List<IkeNotifyPayload> notifyPayloads =
-                IkePayload.getPayloadListForTypeInProvidedList(
-                        PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, outboundPayloads);
-        assertEquals(1, notifyPayloads.size());
-        IkeNotifyPayload notifyPayload = notifyPayloads.get(0);
-        assertEquals(NOTIFY_TYPE_REKEY_SA, notifyPayload.notifyType);
-        assertEquals(PROTOCOL_ID_ESP, notifyPayload.protocolId);
-        assertEquals(mSpyCurrentChildSaRecord.getLocalSpi(), notifyPayload.spi);
-    }
-
-    @Test
-    public void testRekeyChildLocalCreateSendsRequest() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mChildSessionStateMachine.rekeyChildSession();
-        mLooper.dispatchAll();
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildLocalCreate);
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_CREATE_CHILD_SA),
-                        eq(false),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-
-        // Verify outbound payload list
-        List<IkePayload> reqPayloadList = mPayloadListCaptor.getValue();
-        verifyOutboundCreatePayloadTypes(reqPayloadList, true /*isRekey*/);
-
-        verifyOutboundRekeySaPayload(reqPayloadList, false /*isResp*/);
-        verifyOutboundRekeyNotifyPayload(reqPayloadList);
-    }
-
-    private List<IkePayload> makeInboundRekeyChildPayloads(
-            int remoteSpi, String inboundSaHexString, boolean isLocalInitRekey) throws Exception {
-        List<IkePayload> inboundPayloads = new LinkedList<>();
-
-        IkeSaPayload saPayload =
-                (IkeSaPayload)
-                        (IkeTestUtils.hexStringToIkePayload(
-                                IkePayload.PAYLOAD_TYPE_SA, true, inboundSaHexString));
-        inboundPayloads.add(saPayload);
-
-        // Build TS Payloads
-        IkeTrafficSelector[] initTs =
-                isLocalInitRekey
-                        ? mChildSessionStateMachine.mLocalTs
-                        : mChildSessionStateMachine.mRemoteTs;
-        IkeTrafficSelector[] respTs =
-                isLocalInitRekey
-                        ? mChildSessionStateMachine.mRemoteTs
-                        : mChildSessionStateMachine.mLocalTs;
-        inboundPayloads.add(new IkeTsPayload(true /*isInitiator*/, initTs));
-        inboundPayloads.add(new IkeTsPayload(false /*isInitiator*/, respTs));
-
-        // Build Nonce Payloads
-        inboundPayloads.add(new IkeNoncePayload());
-
-        if (isLocalInitRekey) {
-            // Rekey-Create response without Notify-Rekey payload is valid.
-            return inboundPayloads;
-        }
-
-        // Build Rekey-Notification
-        inboundPayloads.add(
-                new IkeNotifyPayload(
-                        PROTOCOL_ID_ESP,
-                        mSpyCurrentChildSaRecord.getRemoteSpi(),
-                        NOTIFY_TYPE_REKEY_SA,
-                        new byte[0]));
-
-        return inboundPayloads;
-    }
-
-    @Test
-    public void testRekeyChildLocalCreateValidatesResponse() throws Exception {
-        setupIdleStateMachine();
-        setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN);
-        setUpSpiResource(REMOTE_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_OUT);
-
-        // Send Rekey-Create request
-        mChildSessionStateMachine.rekeyChildSession();
-        mLooper.dispatchAll();
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildLocalCreate);
-
-        // Prepare "rekeyed" SA and receive Rekey response
-        List<IkePayload> rekeyRespPayloads =
-                makeInboundRekeyChildPayloads(
-                        LOCAL_INIT_NEW_CHILD_SA_SPI_OUT,
-                        REKEY_CHILD_RESP_SA_PAYLOAD,
-                        true /*isLocalInitRekey*/);
-        when(mMockSaRecordHelper.makeChildSaRecord(
-                        any(List.class), eq(rekeyRespPayloads), any(ChildSaRecordConfig.class)))
-                .thenReturn(mSpyLocalInitNewChildSaRecord);
-
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyRespPayloads);
-        mLooper.dispatchAll();
-
-        // Verify state transition
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildLocalDelete);
-
-        // Verify newly created ChildSaRecord
-        assertEquals(
-                mSpyLocalInitNewChildSaRecord,
-                mChildSessionStateMachine.mLocalInitNewChildSaRecord);
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(
-                        eq(mSpyLocalInitNewChildSaRecord.getRemoteSpi()),
-                        eq(mChildSessionStateMachine));
-        verify(mMockChildSessionSmCallback)
-                .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong());
-
-        verify(mMockSaRecordHelper)
-                .makeChildSaRecord(
-                        any(List.class),
-                        eq(rekeyRespPayloads),
-                        mChildSaRecordConfigCaptor.capture());
-        ChildSaRecordConfig childSaRecordConfig = mChildSaRecordConfigCaptor.getValue();
-        verifyChildSaRecordConfig(
-                childSaRecordConfig,
-                LOCAL_INIT_NEW_CHILD_SA_SPI_IN,
-                LOCAL_INIT_NEW_CHILD_SA_SPI_OUT,
-                true /*isLocalInit*/);
-
-        // Verify users have been notified
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verifyNotifyUsersCreateIpSecSa(mSpyLocalInitNewChildSaRecord, true /*expectInbound*/);
-        verifyNotifyUsersCreateIpSecSa(mSpyLocalInitNewChildSaRecord, false /*expectInbound*/);
-    }
-
-    @Test
-    public void testRekeyLocalCreateHandlesErrorNotifyResp() throws Exception {
-        setupIdleStateMachine();
-        setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN);
-
-        // Send Rekey-Create request
-        mChildSessionStateMachine.rekeyChildSession();
-        mLooper.dispatchAll();
-
-        // Receive error notification in Create response
-        IkeNotifyPayload notifyPayload = new IkeNotifyPayload(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE);
-        List<IkePayload> respPayloads = new LinkedList<>();
-        respPayloads.add(notifyPayload);
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads);
-        mLooper.dispatchAll();
-
-        // Verify rekey has been rescheduled and Child Session is alive
-        verify(mMockChildSessionSmCallback)
-                .scheduleRetryLocalRequest(
-                        (ChildLocalRequest) mSpyCurrentChildSaRecord.getFutureRekeyEvent());
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-
-        // Verify no SPI for provisional Child was registered.
-        verify(mMockChildSessionSmCallback, never())
-                .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine));
-    }
-
-    @Test
-    public void testRekeyLocalCreateHandlesRespWithMissingPayload() throws Exception {
-        setupIdleStateMachine();
-        setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN);
-        reset(mMockChildSessionSmCallback);
-
-        // Send Rekey-Create request
-        mChildSessionStateMachine.rekeyChildSession();
-        mLooper.dispatchAll();
-
-        // Receive response with no SA Payload
-        List<IkePayload> validRekeyRespPayloads =
-                makeInboundRekeyChildPayloads(
-                        LOCAL_INIT_NEW_CHILD_SA_SPI_OUT,
-                        REKEY_CHILD_RESP_SA_PAYLOAD,
-                        true /*isLocalInitRekey*/);
-        List<IkePayload> respPayloads = new LinkedList<>();
-        for (IkePayload payload : validRekeyRespPayloads) {
-            if (IkePayload.PAYLOAD_TYPE_SA == payload.payloadType) continue;
-            respPayloads.add(payload);
-        }
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, respPayloads);
-        mLooper.dispatchAll();
-
-        // Verify user was notified and state machine has quit.
-        verifyHandleFatalErrorAndQuit(InvalidSyntaxException.class);
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-
-        // Verify no SPI for provisional Child was registered.
-        verify(mMockChildSessionSmCallback, never())
-                .onChildSaCreated(anyInt(), eq(mChildSessionStateMachine));
-
-        // Verify retry was not scheduled
-        verify(mMockChildSessionSmCallback, never()).scheduleRetryLocalRequest(any());
-    }
-
-    @Test
-    public void testRekeyLocalCreateChildHandlesKeyCalculationFail() throws Exception {
-        // Throw exception when building ChildSaRecord
-        when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any()))
-                .thenThrow(
-                        new GeneralSecurityException(
-                                "testRekeyCreateChildHandlesKeyCalculationFail"));
-
-        // Setup for rekey negotiation
-        setupIdleStateMachine();
-        setUpSpiResource(LOCAL_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_IN);
-        setUpSpiResource(REMOTE_ADDRESS, LOCAL_INIT_NEW_CHILD_SA_SPI_OUT);
-        reset(mMockChildSessionSmCallback);
-
-        // Send Rekey-Create request
-        mChildSessionStateMachine.rekeyChildSession();
-        mLooper.dispatchAll();
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildLocalCreate);
-
-        // Receive Rekey response
-        List<IkePayload> rekeyRespPayloads =
-                makeInboundRekeyChildPayloads(
-                        LOCAL_INIT_NEW_CHILD_SA_SPI_OUT,
-                        REKEY_CHILD_RESP_SA_PAYLOAD,
-                        true /*isLocalInitRekey*/);
-        mChildSessionStateMachine.receiveResponse(EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyRespPayloads);
-        mLooper.dispatchAll();
-
-        // Verify user was notified and state machine has quit.
-        verifyHandleFatalErrorAndQuit(IkeInternalException.class);
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-
-        // Verify SPI for provisional Child was registered and unregistered.
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(LOCAL_INIT_NEW_CHILD_SA_SPI_OUT, mChildSessionStateMachine);
-        verify(mMockChildSessionSmCallback).onChildSaDeleted(LOCAL_INIT_NEW_CHILD_SA_SPI_OUT);
-
-        // Verify retry was not scheduled
-        verify(mMockChildSessionSmCallback, never()).scheduleRetryLocalRequest(any());
-    }
-
-    @Test
-    public void testRekeyChildLocalDeleteSendsRequest() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildLocalDelete
-        mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete);
-        mLooper.dispatchAll();
-
-        // Verify outbound delete request
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildLocalDelete);
-        verifyOutboundDeletePayload(mSpyCurrentChildSaRecord.getLocalSpi(), false /*isResp*/);
-
-        assertEquals(mSpyCurrentChildSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord);
-        assertEquals(
-                mSpyLocalInitNewChildSaRecord, mChildSessionStateMachine.mChildSaRecordSurviving);
-    }
-
-    void verifyChildSaUpdated(ChildSaRecord oldSaRecord, ChildSaRecord newSaRecord) {
-        verify(mMockChildSessionSmCallback).onChildSaDeleted(oldSaRecord.getRemoteSpi());
-        verify(oldSaRecord).close();
-
-        assertNull(mChildSessionStateMachine.mChildSaRecordSurviving);
-        assertEquals(newSaRecord, mChildSessionStateMachine.mCurrentChildSaRecord);
-    }
-
-    @Test
-    public void testRekeyChildLocalDeleteValidatesResponse() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildLocalDelete
-        mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete);
-        mLooper.dispatchAll();
-
-        // Test receiving Delete response
-        mChildSessionStateMachine.receiveResponse(
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-
-        // First invoked in #setupIdleStateMachine
-        verify(mMockChildSessionSmCallback, times(2))
-                .onProcedureFinished(mChildSessionStateMachine);
-
-        verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyLocalInitNewChildSaRecord);
-
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockChildSessionCallback, never()).onClosed();
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-    }
-
-    @Test
-    public void testRekeyChildLocalDeleteHandlesInvalidResp() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildLocalDelete
-        mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete);
-        mLooper.dispatchAll();
-
-        // Test receiving Delete response with missing Delete payload
-        mChildSessionStateMachine.receiveResponse(
-                EXCHANGE_TYPE_INFORMATIONAL, new ArrayList<IkePayload>());
-        mLooper.dispatchAll();
-
-        // Verify rekey has finished
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-        verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyLocalInitNewChildSaRecord);
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-
-        // First invoked in #setupIdleStateMachine
-        verify(mMockChildSessionSmCallback, times(2))
-                .onProcedureFinished(mChildSessionStateMachine);
-    }
-
-    @Test
-    public void testRekeyChildRemoteCreate() throws Exception {
-        setupIdleStateMachine();
-
-        // Setup for new Child SA negotiation.
-        setUpSpiResource(LOCAL_ADDRESS, REMOTE_INIT_NEW_CHILD_SA_SPI_IN);
-        setUpSpiResource(REMOTE_ADDRESS, REMOTE_INIT_NEW_CHILD_SA_SPI_OUT);
-
-        List<IkePayload> rekeyReqPayloads =
-                makeInboundRekeyChildPayloads(
-                        REMOTE_INIT_NEW_CHILD_SA_SPI_OUT,
-                        REKEY_CHILD_REQ_SA_PAYLOAD,
-                        false /*isLocalInitRekey*/);
-        when(mMockSaRecordHelper.makeChildSaRecord(
-                        eq(rekeyReqPayloads), any(List.class), any(ChildSaRecordConfig.class)))
-                .thenReturn(mSpyRemoteInitNewChildSaRecord);
-
-        // Receive rekey Child request
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildRemoteDelete);
-
-        // Verify outbound rekey response
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(EXCHANGE_TYPE_CREATE_CHILD_SA),
-                        eq(true),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-        List<IkePayload> respPayloadList = mPayloadListCaptor.getValue();
-        verifyOutboundCreatePayloadTypes(respPayloadList, true /*isRekey*/);
-
-        verifyOutboundRekeySaPayload(respPayloadList, true /*isResp*/);
-        verifyOutboundRekeyNotifyPayload(respPayloadList);
-
-        // Verify new Child SA
-        assertEquals(
-                mSpyRemoteInitNewChildSaRecord,
-                mChildSessionStateMachine.mRemoteInitNewChildSaRecord);
-
-        verify(mMockChildSessionSmCallback)
-                .onChildSaCreated(
-                        eq(mSpyRemoteInitNewChildSaRecord.getRemoteSpi()),
-                        eq(mChildSessionStateMachine));
-        verify(mMockChildSessionSmCallback)
-                .scheduleLocalRequest(argThat(mRekeyChildLocalReqMatcher), anyLong());
-
-        verify(mMockSaRecordHelper)
-                .makeChildSaRecord(
-                        eq(rekeyReqPayloads),
-                        any(List.class),
-                        mChildSaRecordConfigCaptor.capture());
-        ChildSaRecordConfig childSaRecordConfig = mChildSaRecordConfigCaptor.getValue();
-        verifyChildSaRecordConfig(
-                childSaRecordConfig,
-                REMOTE_INIT_NEW_CHILD_SA_SPI_OUT,
-                REMOTE_INIT_NEW_CHILD_SA_SPI_IN,
-                false /*isLocalInit*/);
-
-        // Verify that users are notified the creation of new inbound IpSecTransform
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, true /*expectInbound*/);
-    }
-
-    private void verifyOutboundErrorNotify(int exchangeType, int errorCode) {
-        verify(mMockChildSessionSmCallback)
-                .onOutboundPayloadsReady(
-                        eq(exchangeType),
-                        eq(true),
-                        mPayloadListCaptor.capture(),
-                        eq(mChildSessionStateMachine));
-        List<IkePayload> respPayloadList = mPayloadListCaptor.getValue();
-
-        assertEquals(1, respPayloadList.size());
-        IkePayload payload = respPayloadList.get(0);
-        assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType);
-        assertEquals(errorCode, ((IkeNotifyPayload) payload).notifyType);
-    }
-
-    @Test
-    public void testRekeyChildRemoteCreateHandlesInvalidReq() throws Exception {
-        setupIdleStateMachine();
-
-        List<IkePayload> rekeyReqPayloads =
-                makeInboundRekeyChildPayloads(
-                        REMOTE_INIT_NEW_CHILD_SA_SPI_OUT,
-                        REKEY_CHILD_UNACCEPTABLE_REQ_SA_PAYLOAD,
-                        false /*isLocalInitRekey*/);
-
-        // Receive rekey Child request
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads);
-        mLooper.dispatchAll();
-
-        // Verify error notification was sent and state machind was back to Idle
-        verifyOutboundErrorNotify(EXCHANGE_TYPE_CREATE_CHILD_SA, ERROR_TYPE_NO_PROPOSAL_CHOSEN);
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testRekeyChildRemoteCreateSaCreationFail() throws Exception {
-        // Throw exception when building ChildSaRecord
-        when(mMockSaRecordHelper.makeChildSaRecord(any(), any(), any()))
-                .thenThrow(
-                        new GeneralSecurityException("testRekeyChildRemoteCreateSaCreationFail"));
-
-        setupIdleStateMachine();
-
-        List<IkePayload> rekeyReqPayloads =
-                makeInboundRekeyChildPayloads(
-                        REMOTE_INIT_NEW_CHILD_SA_SPI_OUT,
-                        REKEY_CHILD_REQ_SA_PAYLOAD,
-                        false /*isLocalInitRekey*/);
-
-        // Receive rekey Child request
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_REKEY_CHILD, EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyReqPayloads);
-        mLooper.dispatchAll();
-
-        // Verify error notification was sent and state machind was back to Idle
-        verifyOutboundErrorNotify(EXCHANGE_TYPE_CREATE_CHILD_SA, ERROR_TYPE_NO_PROPOSAL_CHOSEN);
-
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testRekeyChildRemoteDelete() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildRemoteDelete
-        mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete);
-
-        // Test receiving Delete request
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyCurrentChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        // Verify outbound Delete response
-        verifyOutboundDeletePayload(mSpyCurrentChildSaRecord.getLocalSpi(), true /*isResp*/);
-
-        // Verify Child SA has been updated
-        verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyRemoteInitNewChildSaRecord);
-
-        // Verify procedure has been finished. #onProcedureFinished was first invoked in
-        // #setupIdleStateMachine
-        verify(mMockChildSessionSmCallback, times(2))
-                .onProcedureFinished(mChildSessionStateMachine);
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-
-        verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class));
-
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-        verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/);
-        verify(mMockChildSessionCallback, never()).onClosed();
-    }
-
-    @Test
-    public void testRekeyChildLocalDeleteWithReqForNewSa() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildLocalDelete
-        mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete);
-        mLooper.dispatchAll();
-
-        // Test receiving Delete new Child SA request
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyLocalInitNewChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        // Verify outbound Delete response on new Child SA
-        verifyOutboundDeletePayload(mSpyLocalInitNewChildSaRecord.getLocalSpi(), true /*isResp*/);
-        verify(mMockChildSessionSmCallback)
-                .onChildSaDeleted(mSpyLocalInitNewChildSaRecord.getRemoteSpi());
-        verify(mSpyLocalInitNewChildSaRecord).close();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-
-        verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class));
-
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-        verifyNotifyUserDeleteChildSa(mSpyLocalInitNewChildSaRecord);
-
-        verify(mMockChildSessionCallback).onClosed();
-    }
-
-    @Test
-    public void testRekeyChildRemoteDeleteWithReqForNewSa() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildRemoteDelete
-        mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Test receiving Delete new Child SA request
-        mChildSessionStateMachine.receiveRequest(
-                IKE_EXCHANGE_SUBTYPE_DELETE_CHILD,
-                EXCHANGE_TYPE_INFORMATIONAL,
-                makeDeletePayloads(mSpyRemoteInitNewChildSaRecord.getRemoteSpi()));
-        mLooper.dispatchAll();
-
-        // Verify outbound Delete response on new Child SA
-        verifyOutboundDeletePayload(mSpyRemoteInitNewChildSaRecord.getLocalSpi(), true /*isResp*/);
-        verify(mMockChildSessionSmCallback)
-                .onChildSaDeleted(mSpyRemoteInitNewChildSaRecord.getRemoteSpi());
-        verify(mSpyRemoteInitNewChildSaRecord).close();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-
-        verify(mSpyUserCbExecutor, times(3)).execute(any(Runnable.class));
-
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-        verifyNotifyUserDeleteChildSa(mSpyRemoteInitNewChildSaRecord);
-        verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/);
-
-        verify(mMockChildSessionCallback).onClosed();
-    }
-
-    @Test
-    public void testRekeyChildRemoteDeleteTimeout() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildRemoteDelete
-        mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete);
-        mLooper.dispatchAll();
-
-        mLooper.moveTimeForward(REKEY_DELETE_TIMEOUT_MS);
-        mLooper.dispatchAll();
-
-        // Verify no response sent.
-        verify(mMockChildSessionSmCallback, never())
-                .onOutboundPayloadsReady(anyInt(), anyBoolean(), any(List.class), anyObject());
-
-        // Verify Child SA has been renewed
-        verifyChildSaUpdated(mSpyCurrentChildSaRecord, mSpyRemoteInitNewChildSaRecord);
-
-        // Verify procedure has been finished. #onProcedureFinished was first invoked in
-        // #setupIdleStateMachine
-        verify(mMockChildSessionSmCallback, times(2))
-                .onProcedureFinished(mChildSessionStateMachine);
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.Idle);
-
-        verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class));
-
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-        verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/);
-
-        verify(mMockChildSessionCallback, never()).onClosed();
-    }
-
-    @Test
-    public void testRekeyChildRemoteDeleteExitAndRenter() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildRemoteDelete
-        mChildSessionStateMachine.mRemoteInitNewChildSaRecord = mSpyRemoteInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Trigger a timeout, and immediately re-enter remote-delete
-        mLooper.moveTimeForward(REKEY_DELETE_TIMEOUT_MS / 2 + 1);
-        mChildSessionStateMachine.sendMessage(ChildSessionStateMachine.TIMEOUT_REKEY_REMOTE_DELETE);
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Shift time forward
-        mLooper.moveTimeForward(REKEY_DELETE_TIMEOUT_MS / 2 + 1);
-        mLooper.dispatchAll();
-
-        // Verify final state has not changed - timeout was not triggered.
-        assertTrue(
-                mChildSessionStateMachine.getCurrentState()
-                        instanceof ChildSessionStateMachine.RekeyChildRemoteDelete);
-
-        verify(mSpyUserCbExecutor, times(2)).execute(any(Runnable.class));
-
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-        verifyNotifyUsersCreateIpSecSa(mSpyRemoteInitNewChildSaRecord, false /*expectInbound*/);
-
-        verify(mMockChildSessionCallback, never()).onClosed();
-    }
-
-    @Test
-    public void testCloseSessionNow() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyChildLocalDelete
-        mChildSessionStateMachine.mLocalInitNewChildSaRecord = mSpyLocalInitNewChildSaRecord;
-        mChildSessionStateMachine.sendMessage(
-                CMD_FORCE_TRANSITION, mChildSessionStateMachine.mRekeyChildLocalDelete);
-
-        mChildSessionStateMachine.killSession();
-        mLooper.dispatchAll();
-
-        assertNull(mChildSessionStateMachine.getCurrentState());
-
-        verify(mSpyUserCbExecutor, times(3)).execute(any(Runnable.class));
-
-        verifyNotifyUserDeleteChildSa(mSpyCurrentChildSaRecord);
-        verifyNotifyUserDeleteChildSa(mSpyLocalInitNewChildSaRecord);
-
-        verify(mMockChildSessionCallback).onClosed();
-    }
-
-    @Test
-    public void testValidateExpectKeExistCase() throws Exception {
-        when(mMockNegotiatedProposal.getDhGroupTransforms())
-                .thenReturn(new DhGroupTransform[] {mChildDhGroupTransform});
-        List<IkePayload> payloadList = new LinkedList<>();
-        payloadList.add(new IkeKePayload(SaProposal.DH_GROUP_1024_BIT_MODP));
-
-        CreateChildSaHelper.validateKePayloads(
-                payloadList, true /*isResp*/, mMockNegotiatedProposal);
-        CreateChildSaHelper.validateKePayloads(
-                payloadList, false /*isResp*/, mMockNegotiatedProposal);
-    }
-
-    @Test
-    public void testValidateExpectNoKeExistCase() throws Exception {
-        when(mMockNegotiatedProposal.getDhGroupTransforms()).thenReturn(new DhGroupTransform[0]);
-        List<IkePayload> payloadList = new LinkedList<>();
-
-        CreateChildSaHelper.validateKePayloads(
-                payloadList, true /*isResp*/, mMockNegotiatedProposal);
-        CreateChildSaHelper.validateKePayloads(
-                payloadList, false /*isResp*/, mMockNegotiatedProposal);
-    }
-
-    @Test
-    public void testThrowWhenKeMissing() throws Exception {
-        when(mMockNegotiatedProposal.getDhGroupTransforms())
-                .thenReturn(new DhGroupTransform[] {mChildDhGroupTransform});
-        List<IkePayload> payloadList = new LinkedList<>();
-
-        try {
-            CreateChildSaHelper.validateKePayloads(
-                    payloadList, true /*isResp*/, mMockNegotiatedProposal);
-            fail("Expected to fail due to the absence of KE Payload");
-        } catch (InvalidSyntaxException expected) {
-        }
-
-        try {
-            CreateChildSaHelper.validateKePayloads(
-                    payloadList, false /*isResp*/, mMockNegotiatedProposal);
-            fail("Expected to fail due to the absence of KE Payload");
-        } catch (InvalidKeException expected) {
-        }
-    }
-
-    @Test
-    public void testThrowWhenKeHasMismatchedDhGroup() throws Exception {
-        when(mMockNegotiatedProposal.getDhGroupTransforms())
-                .thenReturn(new DhGroupTransform[] {mChildDhGroupTransform});
-        List<IkePayload> payloadList = new LinkedList<>();
-        payloadList.add(new IkeKePayload(SaProposal.DH_GROUP_2048_BIT_MODP));
-
-        try {
-            CreateChildSaHelper.validateKePayloads(
-                    payloadList, true /*isResp*/, mMockNegotiatedProposal);
-            fail("Expected to fail due to mismatched DH Group");
-        } catch (InvalidSyntaxException expected) {
-        }
-
-        try {
-            CreateChildSaHelper.validateKePayloads(
-                    payloadList, false /*isResp*/, mMockNegotiatedProposal);
-            fail("Expected to fail due to mismatched DH Group");
-        } catch (InvalidKeException expected) {
-        }
-    }
-
-    @Test
-    public void testThrowForUnexpectedKe() throws Exception {
-        DhGroupTransform noneGroup = new DhGroupTransform(SaProposal.DH_GROUP_NONE);
-        when(mMockNegotiatedProposal.getDhGroupTransforms())
-                .thenReturn(new DhGroupTransform[] {noneGroup});
-        List<IkePayload> payloadList = new LinkedList<>();
-        payloadList.add(new IkeKePayload(SaProposal.DH_GROUP_2048_BIT_MODP));
-
-        try {
-            CreateChildSaHelper.validateKePayloads(
-                    payloadList, true /*isResp*/, mMockNegotiatedProposal);
-            fail("Expected to fail due to unexpected KE payload.");
-        } catch (InvalidSyntaxException expected) {
-        }
-
-        CreateChildSaHelper.validateKePayloads(
-                payloadList, false /*isResp*/, mMockNegotiatedProposal);
-    }
-
-    @Test
-    public void testHandleUnexpectedException() throws Exception {
-        Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG);
-        IkeManager.setIkeLog(spyIkeLog);
-
-        mChildSessionStateMachine.createChildSession(
-                null /*localAddress*/, REMOTE_ADDRESS, mMockUdpEncapSocket, mIkePrf, SK_D);
-        mLooper.dispatchAll();
-
-        verifyHandleFatalErrorAndQuit(IkeInternalException.class);
-        verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java
deleted file mode 100644
index 3406d01..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeLocalRequestSchedulerTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike;
-
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.IProcedureConsumer;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.InOrder;
-
-public final class IkeLocalRequestSchedulerTest {
-    private IkeLocalRequestScheduler mScheduler;
-
-    private IProcedureConsumer mMockConsumer;
-    private LocalRequest[] mMockRequestArray;
-
-    private ArgumentCaptor<LocalRequest> mLocalRequestCaptor =
-            ArgumentCaptor.forClass(LocalRequest.class);
-
-    @Before
-    public void setUp() {
-        mMockConsumer = mock(IProcedureConsumer.class);
-        mScheduler = new IkeLocalRequestScheduler(mMockConsumer);
-
-        mMockRequestArray = new LocalRequest[10];
-        for (int i = 0; i < mMockRequestArray.length; i++) {
-            mMockRequestArray[i] = mock(LocalRequest.class);
-        }
-    }
-
-    @Test
-    public void testAddMultipleRequestProcessOnlyOne() {
-        for (LocalRequest r : mMockRequestArray) mScheduler.addRequest(r);
-
-        // Verify that no procedure was preemptively pulled from the queue
-        verify(mMockConsumer, never()).onNewProcedureReady(any());
-
-        // Check that the onNewPrcedureReady called exactly once, on the first item
-        mScheduler.readyForNextProcedure();
-        verify(mMockConsumer, times(1)).onNewProcedureReady(any());
-        verify(mMockConsumer, times(1)).onNewProcedureReady(mMockRequestArray[0]);
-        for (int i = 1; i < mMockRequestArray.length; i++) {
-            verify(mMockConsumer, never()).onNewProcedureReady(mMockRequestArray[i]);
-        }
-    }
-
-    @Test
-    public void testProcessOrder() {
-        InOrder inOrder = inOrder(mMockConsumer);
-
-        for (LocalRequest r : mMockRequestArray) mScheduler.addRequest(r);
-        for (int i = 0; i < mMockRequestArray.length; i++) mScheduler.readyForNextProcedure();
-
-        for (LocalRequest r : mMockRequestArray) {
-            inOrder.verify(mMockConsumer).onNewProcedureReady(r);
-        }
-    }
-
-    @Test
-    public void testAddRequestToFrontProcessOrder() {
-        InOrder inOrder = inOrder(mMockConsumer);
-
-        LocalRequest[] mockHighPriorityRequestArray = new LocalRequest[10];
-        for (int i = 0; i < mockHighPriorityRequestArray.length; i++) {
-            mockHighPriorityRequestArray[i] = mock(LocalRequest.class);
-        }
-
-        for (LocalRequest r : mMockRequestArray) mScheduler.addRequest(r);
-        for (LocalRequest r : mockHighPriorityRequestArray) mScheduler.addRequestAtFront(r);
-
-        for (int i = 0; i < mockHighPriorityRequestArray.length + mMockRequestArray.length; i++) {
-            mScheduler.readyForNextProcedure();
-        }
-
-        // Verify processing order. mockHighPriorityRequestArray is processed in reverse order
-        for (int i = mockHighPriorityRequestArray.length - 1; i >= 0; i--) {
-            inOrder.verify(mMockConsumer).onNewProcedureReady(mockHighPriorityRequestArray[i]);
-        }
-        for (LocalRequest r : mMockRequestArray) {
-            inOrder.verify(mMockConsumer).onNewProcedureReady(r);
-        }
-    }
-
-    @Test
-    public void testDoNotProcessCanceledRequest() {
-        LocalRequest[] requestArray = new LocalRequest[4];
-
-        for (int i = 0; i < requestArray.length; i++) {
-            requestArray[i] = new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE);
-            mScheduler.addRequest(requestArray[i]);
-        }
-
-        mScheduler.readyForNextProcedure();
-        verify(mMockConsumer).onNewProcedureReady(eq(requestArray[0]));
-
-        requestArray[1].cancel();
-        mScheduler.readyForNextProcedure();
-        verify(mMockConsumer, never()).onNewProcedureReady(eq(requestArray[1]));
-        verify(mMockConsumer).onNewProcedureReady(eq(requestArray[2]));
-
-        mScheduler.readyForNextProcedure();
-        verify(mMockConsumer).onNewProcedureReady(eq(requestArray[3]));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
deleted file mode 100644
index 94f4d62..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/IkeSessionStateMachineTest.java
+++ /dev/null
@@ -1,4036 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_CHILD_SA_NOT_FOUND;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_ADDITIONAL_SAS;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
-
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_DELETE_CHILD;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IKE_EXCHANGE_SUBTYPE_REKEY_CHILD;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.RETRY_INTERVAL_MS;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.SA_SOFT_LIFETIME_MS;
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA;
-import static com.android.internal.net.ipsec.ike.message.IkeHeader.EXCHANGE_TYPE_INFORMATIONAL;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP;
-import static com.android.internal.net.ipsec.ike.message.IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_AUTH;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_SA;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.eap.EapSessionConfig;
-import android.net.ipsec.ike.ChildSaProposal;
-import android.net.ipsec.ike.ChildSessionCallback;
-import android.net.ipsec.ike.ChildSessionOptions;
-import android.net.ipsec.ike.IkeIpv4AddrIdentification;
-import android.net.ipsec.ike.IkeManager;
-import android.net.ipsec.ike.IkeSaProposal;
-import android.net.ipsec.ike.IkeSessionCallback;
-import android.net.ipsec.ike.IkeSessionOptions;
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.TransportModeChildSessionOptions;
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeInternalException;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.os.test.TestLooper;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.eap.EapAuthenticator;
-import com.android.internal.net.eap.IEapCallback;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachine.IChildSessionSmCallback;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.ChildSessionFactoryHelper;
-import com.android.internal.net.ipsec.ike.ChildSessionStateMachineFactory.IChildSessionFactoryHelper;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.ReceivedIkePacket;
-import com.android.internal.net.ipsec.ike.SaRecord.ISaRecordHelper;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecordConfig;
-import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.NoValidProposalChosenException;
-import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException;
-import com.android.internal.net.ipsec.ike.message.IkeAuthDigitalSignPayload;
-import com.android.internal.net.ipsec.ike.message.IkeAuthPayload;
-import com.android.internal.net.ipsec.ike.message.IkeAuthPskPayload;
-import com.android.internal.net.ipsec.ike.message.IkeCertX509CertPayload;
-import com.android.internal.net.ipsec.ike.message.IkeDeletePayload;
-import com.android.internal.net.ipsec.ike.message.IkeEapPayload;
-import com.android.internal.net.ipsec.ike.message.IkeHeader;
-import com.android.internal.net.ipsec.ike.message.IkeIdPayload;
-import com.android.internal.net.ipsec.ike.message.IkeInformationalPayload;
-import com.android.internal.net.ipsec.ike.message.IkeKePayload;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultOk;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultProtectedError;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultUnprotectedError;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.IIkeMessageHelper;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.IkeMessageHelper;
-import com.android.internal.net.ipsec.ike.message.IkeNoncePayload;
-import com.android.internal.net.ipsec.ike.message.IkeNotifyPayload;
-import com.android.internal.net.ipsec.ike.message.IkePayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.DhGroupTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSkfPayload;
-import com.android.internal.net.ipsec.ike.message.IkeTestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeTsPayload;
-import com.android.internal.net.ipsec.ike.testutils.CertUtils;
-import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
-import com.android.internal.net.ipsec.ike.utils.Retransmitter;
-import com.android.internal.net.ipsec.ike.utils.Retransmitter.IBackoffTimeoutCalculator;
-import com.android.internal.net.utils.Log;
-import com.android.internal.util.State;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.invocation.InvocationOnMock;
-
-import java.io.IOException;
-import java.net.Inet4Address;
-import java.security.GeneralSecurityException;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-public final class IkeSessionStateMachineTest {
-    private static final String TAG = "IkeSessionStateMachineTest";
-
-    private static final Inet4Address LOCAL_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private static final Inet4Address REMOTE_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("127.0.0.1"));
-
-    private static final String IKE_INIT_RESP_HEX_STRING =
-            "5f54bf6d8b48e6e1909232b3d1edcb5c21202220000000000000014c220000300000"
-                    + "002c010100040300000c0100000c800e008003000008030000020300000802000002"
-                    + "00000008040000022800008800020000fe014fefed55a4229928bfa3dad1ea6ffaca"
-                    + "abfb5f5bdd71790e99a192530e3f849d3a3d96dc6e0a7a10ff6f72a6162103ac573c"
-                    + "acd41d08b7a034cad8f5eab09c14ced5a9e4af5692dff028f21c1119dd75226b6af6"
-                    + "b2f009245369c9892cc5742e5c94a254ebff052470771fb2cb4f29a35d8953e18a1a"
-                    + "6c6fbc56acc188a5290000249756112ca539f5c25abacc7ee92b73091942a9c06950"
-                    + "f98848f1af1694c4ddff2900001c00004004c53f054b976a25d75fde72dbf1c7b6c8"
-                    + "c9aa9ca12900001c00004005b16d79b21c1bc89ca7350f42de805be0227e2ed62b00"
-                    + "00080000401400000014882fe56d6fd20dbc2251613b2ebe5beb";
-    private static final String IKE_SA_PAYLOAD_HEX_STRING =
-            "220000300000002c010100040300000c0100000c800e00800300000803000002030"
-                    + "00008020000020000000804000002";
-    private static final String IKE_REKEY_SA_PAYLOAD_HEX_STRING =
-            "22000038000000340101080400000000000000FF0300000c0100000c800e0080030"
-                    + "000080300000203000008020000020000000804000002";
-    private static final String IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING =
-            "22000038000000340101080400000000000000FF0300000c0100000c800e0080030"
-                    + "00008030000020300000802000002000000080400000e";
-    private static final int IKE_REKEY_SA_INITIATOR_SPI = 0xff;
-    private static final String KE_PAYLOAD_HEX_STRING =
-            "2800008800020000b4a2faf4bb54878ae21d638512ece55d9236fc50"
-                    + "46ab6cef82220f421f3ce6361faf36564ecb6d28798a94aa"
-                    + "d7b2b4b603ddeaaa5630adb9ece8ac37534036040610ebdd"
-                    + "92f46bef84f0be7db860351843858f8acf87056e272377f7"
-                    + "0c9f2d81e29c7b0ce4f291a3a72476bb0b278fd4b7b0a4c2"
-                    + "6bbeb08214c7071376079587";
-    private static final String NONCE_INIT_PAYLOAD_HEX_STRING =
-            "29000024c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412";
-    private static final String NONCE_RESP_PAYLOAD_HEX_STRING =
-            "290000249756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff";
-    private static final String NONCE_INIT_HEX_STRING =
-            "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c72cb4240eb5c46412";
-    private static final String NONCE_RESP_HEX_STRING =
-            "9756112ca539f5c25abacc7ee92b73091942a9c06950f98848f1af1694c4ddff";
-    private static final String NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING =
-            "2900001c00004004e54f73b7d83f6beb881eab2051d8663f421d10b0";
-    private static final String NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING =
-            "2b00001c00004005d915368ca036004cb578ae3e3fb268509aeab190";
-    private static final String FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING = "290000080000402e";
-    private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000";
-    private static final String NOTIFY_REKEY_IKE_PAYLOAD_HEX_STRING = "2100000800004009";
-    private static final String ID_PAYLOAD_INITIATOR_HEX_STRING =
-            "290000180200000031313233343536373839414243444546";
-    private static final String ID_PAYLOAD_RESPONDER_HEX_STRING = "2700000c010000007f000001";
-    private static final String PSK_AUTH_RESP_PAYLOAD_HEX_STRING =
-            "2100001c0200000058f36412e9b7b38df817a9f7779b7a008dacdd25";
-    private static final String GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING =
-            "300000580e0000000f300d06092a864886f70d01010b05006f76af4150d653c5d413"
-                    + "6b9f69d905849bf075c563e6d14ccda42361ec3e7d12c72e2dece5711ea1d952f7b8e"
-                    + "12c5d982aa4efdaeac36a02b222aa96242cc424";
-    private static final String CHILD_SA_PAYLOAD_HEX_STRING =
-            "2c00002c0000002801030403cae7019f0300000c0100000c800e008003000008030"
-                    + "000020000000805000000";
-    private static final String TS_INIT_PAYLOAD_HEX_STRING =
-            "2d00001801000000070000100000ffff00000000ffffffff";
-    private static final String TS_RESP_PAYLOAD_HEX_STRING =
-            "2900001801000000070000100000ffff000000000fffffff";
-
-    private static final String PSK_HEX_STRING = "6A756E69706572313233";
-
-    private static final String PRF_KEY_INIT_HEX_STRING =
-            "094787780EE466E2CB049FA327B43908BC57E485";
-    private static final String PRF_KEY_RESP_HEX_STRING =
-            "A30E6B08BE56C0E6BFF4744143C75219299E1BEB";
-
-    private static final byte[] EAP_DUMMY_MSG = "EAP Message".getBytes();
-
-    private static final int KEY_LEN_IKE_INTE = 20;
-    private static final int KEY_LEN_IKE_ENCR = 16;
-    private static final int KEY_LEN_IKE_PRF = 20;
-    private static final int KEY_LEN_IKE_SKD = KEY_LEN_IKE_PRF;
-
-    private static final int CHILD_SPI_LOCAL = 0x2ad4c0a2;
-    private static final int CHILD_SPI_REMOTE = 0xcae7019f;
-
-    private static final int DUMMY_UDP_ENCAP_RESOURCE_ID = 0x3234;
-    private static final int UDP_ENCAP_PORT = 34567;
-
-    private static final int EAP_SIM_SUB_ID = 1;
-
-    private static final int PAYLOAD_TYPE_UNSUPPORTED = 127;
-
-    private static final long RETRANSMIT_BACKOFF_TIMEOUT_MS = 5000L;
-
-    private MockIpSecTestUtils mMockIpSecTestUtils;
-    private Context mContext;
-    private IpSecManager mIpSecManager;
-    private UdpEncapsulationSocket mUdpEncapSocket;
-
-    private IkeSocket mSpyIkeSocket;
-
-    private TestLooper mLooper;
-    private IkeSessionStateMachine mIkeSessionStateMachine;
-
-    private byte[] mPsk;
-
-    private ChildSessionOptions mChildSessionOptions;
-
-    private Executor mSpyUserCbExecutor;
-    private IkeSessionCallback mMockIkeSessionCallback;
-    private ChildSessionCallback mMockChildSessionCallback;
-
-    private EncryptionTransform mIkeEncryptionTransform;
-    private IntegrityTransform mIkeIntegrityTransform;
-    private PrfTransform mIkePrfTransform;
-    private DhGroupTransform mIkeDhGroupTransform;
-
-    private IIkeMessageHelper mMockIkeMessageHelper;
-    private ISaRecordHelper mMockSaRecordHelper;
-    private IBackoffTimeoutCalculator mMockBackoffTimeoutCalculator;
-
-    private ChildSessionStateMachine mMockChildSessionStateMachine;
-    private IChildSessionFactoryHelper mMockChildSessionFactoryHelper;
-    private IChildSessionSmCallback mDummyChildSmCallback;
-
-    private IkeSaRecord mSpyCurrentIkeSaRecord;
-    private IkeSaRecord mSpyLocalInitIkeSaRecord;
-    private IkeSaRecord mSpyRemoteInitIkeSaRecord;
-
-    private Log mSpyIkeLog;
-
-    private int mExpectedCurrentSaLocalReqMsgId;
-    private int mExpectedCurrentSaRemoteReqMsgId;
-
-    private EapSessionConfig mEapSessionConfig;
-    private IkeEapAuthenticatorFactory mMockEapAuthenticatorFactory;
-    private EapAuthenticator mMockEapAuthenticator;
-
-    private X509Certificate mRootCertificate;
-    private X509Certificate mServerEndCertificate;
-
-    private ArgumentCaptor<IkeMessage> mIkeMessageCaptor =
-            ArgumentCaptor.forClass(IkeMessage.class);
-    private ArgumentCaptor<IkeSaRecordConfig> mIkeSaRecordConfigCaptor =
-            ArgumentCaptor.forClass(IkeSaRecordConfig.class);
-    private ArgumentCaptor<IChildSessionSmCallback> mChildSessionSmCbCaptor =
-            ArgumentCaptor.forClass(IChildSessionSmCallback.class);
-    private ArgumentCaptor<List<IkePayload>> mPayloadListCaptor =
-            ArgumentCaptor.forClass(List.class);
-
-    private ReceivedIkePacket makeDummyReceivedIkeInitRespPacket(
-            long initiatorSpi,
-            long responderSpi,
-            @IkeHeader.ExchangeType int eType,
-            boolean isResp,
-            boolean fromIkeInit,
-            List<Integer> payloadTypeList,
-            List<String> payloadHexStringList)
-            throws Exception {
-
-        List<IkePayload> payloadList =
-                hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp);
-        // Build a remotely generated NAT_DETECTION_SOURCE_IP payload to mock a remote node's
-        // network that is not behind NAT.
-        IkePayload sourceNatPayload =
-                new IkeNotifyPayload(
-                        NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP,
-                        IkeNotifyPayload.generateNatDetectionData(
-                                initiatorSpi,
-                                responderSpi,
-                                REMOTE_ADDRESS,
-                                IkeSocket.IKE_SERVER_PORT));
-        payloadList.add(sourceNatPayload);
-        return makeDummyUnencryptedReceivedIkePacket(
-                initiatorSpi, responderSpi, eType, isResp, fromIkeInit, payloadList);
-    }
-
-    private ReceivedIkePacket makeDummyUnencryptedReceivedIkePacket(
-            long initiatorSpi,
-            long responderSpi,
-            @IkeHeader.ExchangeType int eType,
-            boolean isResp,
-            boolean fromIkeInit,
-            List<IkePayload> payloadList)
-            throws Exception {
-        IkeMessage dummyIkeMessage =
-                makeDummyIkeMessageForTest(
-                        initiatorSpi,
-                        responderSpi,
-                        eType,
-                        isResp,
-                        fromIkeInit,
-                        0,
-                        false /*isEncrypted*/,
-                        payloadList);
-
-        byte[] dummyIkePacketBytes = new byte[0];
-        when(mMockIkeMessageHelper.decode(0, dummyIkeMessage.ikeHeader, dummyIkePacketBytes))
-                .thenReturn(new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes));
-
-        return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes);
-    }
-
-    private ReceivedIkePacket makeDummyEncryptedReceivedIkePacket(
-            IkeSaRecord ikeSaRecord,
-            @IkeHeader.ExchangeType int eType,
-            boolean isResp,
-            List<Integer> payloadTypeList,
-            List<String> payloadHexStringList)
-            throws Exception {
-        List<IkePayload> payloadList =
-                hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp);
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                ikeSaRecord, eType, isResp, payloadList);
-    }
-
-    private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList(
-            IkeSaRecord ikeSaRecord,
-            @IkeHeader.ExchangeType int eType,
-            boolean isResp,
-            List<IkePayload> payloadList)
-            throws Exception {
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                ikeSaRecord,
-                eType,
-                isResp,
-                isResp
-                        ? ikeSaRecord.getLocalRequestMessageId()
-                        : ikeSaRecord.getRemoteRequestMessageId(),
-                payloadList,
-                new byte[0] /*dummyIkePacketBytes*/);
-    }
-
-    private ReceivedIkePacket makeDummyEncryptedReceivedIkePacketWithPayloadList(
-            IkeSaRecord ikeSaRecord,
-            @IkeHeader.ExchangeType int eType,
-            boolean isResp,
-            int msgId,
-            List<IkePayload> payloadList,
-            byte[] dummyIkePacketBytes)
-            throws Exception {
-        boolean fromIkeInit = !ikeSaRecord.isLocalInit;
-        IkeMessage dummyIkeMessage =
-                makeDummyIkeMessageForTest(
-                        ikeSaRecord.getInitiatorSpi(),
-                        ikeSaRecord.getResponderSpi(),
-                        eType,
-                        isResp,
-                        fromIkeInit,
-                        msgId,
-                        true /*isEncyprted*/,
-                        payloadList);
-
-        setDecodeEncryptedPacketResult(
-                ikeSaRecord,
-                dummyIkeMessage.ikeHeader,
-                null /*collectedFrags*/,
-                new DecodeResultOk(dummyIkeMessage, dummyIkePacketBytes));
-
-        return new ReceivedIkePacket(dummyIkeMessage.ikeHeader, dummyIkePacketBytes);
-    }
-
-    private ReceivedIkePacket makeDummyReceivedIkePacketWithInvalidSyntax(
-            IkeSaRecord ikeSaRecord, boolean isResp, int eType) {
-        return makeDummyReceivedIkePacketWithDecodingError(
-                ikeSaRecord, isResp, eType, new InvalidSyntaxException("IkeStateMachineTest"));
-    }
-
-    private ReceivedIkePacket makeDummyReceivedIkePacketWithDecodingError(
-            IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeProtocolException exception) {
-        IkeHeader header =
-                makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK);
-        byte[] dummyPacket = new byte[0];
-        when(mMockIkeMessageHelper.decode(
-                        anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any()))
-                .thenReturn(new DecodeResultProtectedError(exception, dummyPacket));
-
-        return new ReceivedIkePacket(header, dummyPacket);
-    }
-
-    private ReceivedIkePacket makeDummyReceivedIkePacketWithUnprotectedError(
-            IkeSaRecord ikeSaRecord, boolean isResp, int eType, IkeException exception) {
-        IkeHeader header =
-                makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SK);
-        byte[] dummyPacket = new byte[0];
-        when(mMockIkeMessageHelper.decode(
-                        anyInt(), any(), any(), eq(ikeSaRecord), eq(header), any(), any()))
-                .thenReturn(new DecodeResultUnprotectedError(exception));
-
-        return new ReceivedIkePacket(header, dummyPacket);
-    }
-
-    private ReceivedIkePacket makeDummyReceivedIkeFragmentPacket(
-            IkeSaRecord ikeSaRecord,
-            boolean isResp,
-            int eType,
-            IkeSkfPayload skfPayload,
-            int nextPayloadType,
-            DecodeResultPartial collectedFrags) {
-        IkeHeader header =
-                makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF);
-
-        byte[] dummyPacket = new byte[0];
-        DecodeResultPartial resultFrags =
-                new DecodeResultPartial(
-                        header, dummyPacket, skfPayload, nextPayloadType, collectedFrags);
-        setDecodeEncryptedPacketResult(ikeSaRecord, header, collectedFrags, resultFrags);
-
-        return new ReceivedIkePacket(header, dummyPacket);
-    }
-
-    private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketOk(
-            IkeSaRecord ikeSaRecord,
-            boolean isResp,
-            int eType,
-            DecodeResultPartial collectedFrags,
-            List<IkePayload> payloadList,
-            byte[] firstFragBytes) {
-        IkeHeader header =
-                makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF);
-
-        IkeMessage completeMessage = new IkeMessage(header, payloadList);
-
-        setDecodeEncryptedPacketResult(
-                ikeSaRecord,
-                header,
-                collectedFrags,
-                new DecodeResultOk(completeMessage, firstFragBytes));
-
-        return new ReceivedIkePacket(header, new byte[0] /*dummyIkePacketBytes*/);
-    }
-
-    private ReceivedIkePacket makeDummyReceivedLastIkeFragmentPacketError(
-            IkeSaRecord ikeSaRecord,
-            boolean isResp,
-            int eType,
-            DecodeResultPartial collectedFrags,
-            IkeException exception) {
-        IkeHeader header =
-                makeDummyIkeHeader(ikeSaRecord, isResp, eType, IkePayload.PAYLOAD_TYPE_SKF);
-
-        byte[] dummyIkePacketBytes = new byte[0];
-        setDecodeEncryptedPacketResult(
-                ikeSaRecord,
-                header,
-                collectedFrags,
-                new DecodeResultProtectedError(exception, dummyIkePacketBytes));
-
-        return new ReceivedIkePacket(header, dummyIkePacketBytes);
-    }
-
-    private IkeHeader makeDummyIkeHeader(
-            IkeSaRecord ikeSaRecord, boolean isResp, int eType, int firstPayloadType) {
-        return new IkeHeader(
-                ikeSaRecord.getInitiatorSpi(),
-                ikeSaRecord.getResponderSpi(),
-                firstPayloadType,
-                eType,
-                isResp,
-                !ikeSaRecord.isLocalInit,
-                isResp
-                        ? ikeSaRecord.getLocalRequestMessageId()
-                        : ikeSaRecord.getRemoteRequestMessageId());
-    }
-
-    private void setDecodeEncryptedPacketResult(
-            IkeSaRecord ikeSaRecord,
-            IkeHeader header,
-            DecodeResultPartial collectedFrags,
-            DecodeResult result) {
-        when(mMockIkeMessageHelper.decode(
-                        anyInt(),
-                        any(),
-                        any(),
-                        eq(ikeSaRecord),
-                        eq(header),
-                        any(),
-                        eq(collectedFrags)))
-                .thenReturn(result);
-    }
-
-    private IkeMessage makeDummyIkeMessageForTest(
-            long initSpi,
-            long respSpi,
-            @IkeHeader.ExchangeType int eType,
-            boolean isResp,
-            boolean fromikeInit,
-            int messageId,
-            boolean isEncrypted,
-            List<IkePayload> payloadList)
-            throws Exception {
-        int firstPayloadType =
-                isEncrypted ? IkePayload.PAYLOAD_TYPE_SK : IkePayload.PAYLOAD_TYPE_NO_NEXT;
-
-        IkeHeader header =
-                new IkeHeader(
-                        initSpi, respSpi, firstPayloadType, eType, isResp, fromikeInit, messageId);
-
-        return new IkeMessage(header, payloadList);
-    }
-
-    private static List<IkePayload> hexStrListToIkePayloadList(
-            List<Integer> payloadTypeList, List<String> payloadHexStringList, boolean isResp)
-            throws Exception {
-        List<IkePayload> payloadList = new LinkedList<>();
-        for (int i = 0; i < payloadTypeList.size(); i++) {
-            payloadList.add(
-                    IkeTestUtils.hexStringToIkePayload(
-                            payloadTypeList.get(i), isResp, payloadHexStringList.get(i)));
-        }
-        return payloadList;
-    }
-
-    private void verifyDecodeEncryptedMessage(IkeSaRecord record, ReceivedIkePacket rcvPacket)
-            throws Exception {
-        verify(mMockIkeMessageHelper)
-                .decode(
-                        anyInt(),
-                        any(),
-                        any(),
-                        eq(record),
-                        eq(rcvPacket.ikeHeader),
-                        eq(rcvPacket.ikePacketBytes),
-                        eq(null));
-    }
-
-    private static IkeSaRecord makeDummyIkeSaRecord(long initSpi, long respSpi, boolean isLocalInit)
-            throws IOException {
-        Inet4Address initAddress = isLocalInit ? LOCAL_ADDRESS : REMOTE_ADDRESS;
-        Inet4Address respAddress = isLocalInit ? REMOTE_ADDRESS : LOCAL_ADDRESS;
-
-        return new IkeSaRecord(
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(initAddress, initSpi),
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(respAddress, respSpi),
-                isLocalInit,
-                TestUtils.hexStringToByteArray(NONCE_INIT_HEX_STRING),
-                TestUtils.hexStringToByteArray(NONCE_RESP_HEX_STRING),
-                new byte[KEY_LEN_IKE_SKD],
-                new byte[KEY_LEN_IKE_INTE],
-                new byte[KEY_LEN_IKE_INTE],
-                new byte[KEY_LEN_IKE_ENCR],
-                new byte[KEY_LEN_IKE_ENCR],
-                TestUtils.hexStringToByteArray(PRF_KEY_INIT_HEX_STRING),
-                TestUtils.hexStringToByteArray(PRF_KEY_RESP_HEX_STRING),
-                new LocalRequest(CMD_LOCAL_REQUEST_REKEY_IKE));
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mSpyIkeLog = TestUtils.makeSpyLogThrowExceptionForWtf(TAG);
-        IkeManager.setIkeLog(mSpyIkeLog);
-
-        mMockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec();
-        mIpSecManager = mMockIpSecTestUtils.getIpSecManager();
-        mContext = mMockIpSecTestUtils.getContext();
-        mUdpEncapSocket = mIpSecManager.openUdpEncapsulationSocket();
-        mEapSessionConfig =
-                new EapSessionConfig.Builder()
-                        .setEapSimConfig(EAP_SIM_SUB_ID, TelephonyManager.APPTYPE_USIM)
-                        .build();
-
-        mMockEapAuthenticatorFactory = mock(IkeEapAuthenticatorFactory.class);
-        mMockEapAuthenticator = mock(EapAuthenticator.class);
-        when(mMockEapAuthenticatorFactory.newEapAuthenticator(any(), any(), any(), any()))
-                .thenReturn(mMockEapAuthenticator);
-
-        mRootCertificate = CertUtils.createCertFromPemFile("self-signed-ca-a.pem");
-        mServerEndCertificate = CertUtils.createCertFromPemFile("end-cert-a.pem");
-
-        mPsk = TestUtils.hexStringToByteArray(PSK_HEX_STRING);
-
-        mChildSessionOptions = buildChildSessionOptions();
-
-        mIkeEncryptionTransform =
-                new EncryptionTransform(
-                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128);
-        mIkeIntegrityTransform =
-                new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96);
-        mIkePrfTransform = new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1);
-        mIkeDhGroupTransform = new DhGroupTransform(SaProposal.DH_GROUP_1024_BIT_MODP);
-
-        mSpyUserCbExecutor =
-                spy(
-                        (command) -> {
-                            command.run();
-                        });
-
-        mMockIkeSessionCallback = mock(IkeSessionCallback.class);
-        mMockChildSessionCallback = mock(ChildSessionCallback.class);
-
-        mLooper = new TestLooper();
-
-        mMockChildSessionStateMachine = mock(ChildSessionStateMachine.class);
-        mMockChildSessionFactoryHelper = mock(IChildSessionFactoryHelper.class);
-        ChildSessionStateMachineFactory.setChildSessionFactoryHelper(
-                mMockChildSessionFactoryHelper);
-        setupChildStateMachineFactory(mMockChildSessionStateMachine);
-
-        // Inject longer retransmission timeout
-        mMockBackoffTimeoutCalculator = mock(IBackoffTimeoutCalculator.class);
-        when(mMockBackoffTimeoutCalculator.getExponentialBackoffTimeout(anyInt()))
-                .thenReturn(RETRANSMIT_BACKOFF_TIMEOUT_MS);
-        Retransmitter.setBackoffTimeoutCalculator(mMockBackoffTimeoutCalculator);
-
-        // Setup state machine
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsPsk(mPsk));
-
-        mMockIkeMessageHelper = mock(IkeMessage.IIkeMessageHelper.class);
-        IkeMessage.setIkeMessageHelper(mMockIkeMessageHelper);
-        resetMockIkeMessageHelper();
-
-        mMockSaRecordHelper = mock(SaRecord.ISaRecordHelper.class);
-        SaRecord.setSaRecordHelper(mMockSaRecordHelper);
-
-        mSpyCurrentIkeSaRecord = spy(makeDummyIkeSaRecord(11, 12, true));
-        mSpyLocalInitIkeSaRecord = spy(makeDummyIkeSaRecord(21, 22, true));
-        mSpyRemoteInitIkeSaRecord = spy(makeDummyIkeSaRecord(31, 32, false));
-
-        mExpectedCurrentSaLocalReqMsgId = 0;
-        mExpectedCurrentSaRemoteReqMsgId = 0;
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mIkeSessionStateMachine.quit();
-        mIkeSessionStateMachine.setDbg(false);
-        mUdpEncapSocket.close();
-
-        mSpyCurrentIkeSaRecord.close();
-        mSpyLocalInitIkeSaRecord.close();
-        mSpyRemoteInitIkeSaRecord.close();
-
-        IkeManager.resetIkeLog();
-        Retransmitter.resetBackoffTimeoutCalculator();
-        IkeMessage.setIkeMessageHelper(new IkeMessageHelper());
-        SaRecord.setSaRecordHelper(new SaRecordHelper());
-        ChildSessionStateMachineFactory.setChildSessionFactoryHelper(
-                new ChildSessionFactoryHelper());
-    }
-
-    private IkeSessionStateMachine makeAndStartIkeSession(IkeSessionOptions ikeOptions)
-            throws Exception {
-        IkeSessionStateMachine ikeSession =
-                new IkeSessionStateMachine(
-                        mLooper.getLooper(),
-                        mContext,
-                        mIpSecManager,
-                        ikeOptions,
-                        mChildSessionOptions,
-                        mSpyUserCbExecutor,
-                        mMockIkeSessionCallback,
-                        mMockChildSessionCallback,
-                        mMockEapAuthenticatorFactory);
-        ikeSession.setDbg(true);
-
-        mLooper.dispatchAll();
-        ikeSession.mLocalAddress = LOCAL_ADDRESS;
-
-        mSpyIkeSocket = spy(IkeSocket.getIkeSocket(mUdpEncapSocket, ikeSession));
-        doNothing().when(mSpyIkeSocket).sendIkePacket(any(), any());
-        ikeSession.mIkeSocket = mSpyIkeSocket;
-
-        return ikeSession;
-    }
-
-    public static IkeSaProposal buildSaProposal() throws Exception {
-        return new IkeSaProposal.Builder()
-                .addEncryptionAlgorithm(
-                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
-                .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
-                .addPseudorandomFunction(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1)
-                .addDhGroup(SaProposal.DH_GROUP_1024_BIT_MODP)
-                .build();
-    }
-
-    private IkeSessionOptions.Builder buildIkeSessionOptionsCommon() throws Exception {
-        return new IkeSessionOptions.Builder()
-                .setServerAddress(REMOTE_ADDRESS)
-                .setUdpEncapsulationSocket(mUdpEncapSocket)
-                .addSaProposal(buildSaProposal())
-                .setLocalIdentification(new IkeIpv4AddrIdentification((Inet4Address) LOCAL_ADDRESS))
-                .setRemoteIdentification(
-                        new IkeIpv4AddrIdentification((Inet4Address) REMOTE_ADDRESS));
-    }
-
-    private IkeSessionOptions buildIkeSessionOptionsPsk(byte[] psk) throws Exception {
-        return buildIkeSessionOptionsCommon().setAuthPsk(psk).build();
-    }
-
-    private IkeSessionOptions buildIkeSessionOptionsEap() throws Exception {
-        return buildIkeSessionOptionsCommon()
-                .setAuthEap(mRootCertificate, mEapSessionConfig)
-                .build();
-    }
-
-    private ChildSessionOptions buildChildSessionOptions() throws Exception {
-        ChildSaProposal saProposal =
-                new ChildSaProposal.Builder()
-                        .addEncryptionAlgorithm(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC, SaProposal.KEY_LEN_AES_128)
-                        .addIntegrityAlgorithm(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96)
-                        .build();
-
-        return new TransportModeChildSessionOptions.Builder().addSaProposal(saProposal).build();
-    }
-
-    private ReceivedIkePacket makeIkeInitResponse() throws Exception {
-        // TODO: Build real IKE INIT response when IKE INIT response validation is implemented.
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NOTIFY);
-
-        payloadHexStringList.add(IKE_SA_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(KE_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(NAT_DETECTION_SOURCE_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(NAT_DETECTION_DESTINATION_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(FRAGMENTATION_SUPPORTED_PAYLOAD_HEX_STRING);
-
-        // In each test assign different IKE responder SPI in IKE INIT response to avoid remote SPI
-        // collision during response validation.
-        // STOPSHIP: b/131617794 allow #mockIkeSetup to be independent in each test after we can
-        // support IkeSession cleanup.
-        return makeDummyReceivedIkeInitRespPacket(
-                1L /*initiator SPI*/,
-                2L /*responder SPI*/,
-                IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT,
-                true /*isResp*/,
-                false /*fromIkeInit*/,
-                payloadTypeList,
-                payloadHexStringList);
-    }
-
-    private List<IkePayload> getIkeAuthPayloadListWithChildPayloads(
-            List<IkePayload> authRelatedPayloads) throws Exception {
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER);
-
-        payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING);
-
-        List<IkePayload> payloadList =
-                hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, true /*isResp*/);
-        payloadList.addAll(authRelatedPayloads);
-
-        return payloadList;
-    }
-
-    private ReceivedIkePacket makeIkeAuthRespWithChildPayloads(List<IkePayload> authRelatedPayloads)
-            throws Exception {
-        List<IkePayload> payloadList = getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads);
-
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                true /*isResp*/,
-                payloadList);
-    }
-
-    private ReceivedIkePacket makeIkeAuthRespWithoutChildPayloads(
-            List<IkePayload> authRelatedPayloads) throws Exception {
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                true /*isResp*/,
-                authRelatedPayloads);
-    }
-
-    private ReceivedIkePacket makeCreateChildCreateMessage(boolean isResp) throws Exception {
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                isResp,
-                makeCreateChildPayloadList(isResp));
-    }
-
-    private ReceivedIkePacket makeRekeyChildCreateMessage(boolean isResp, int spi)
-            throws Exception {
-        IkeNotifyPayload rekeyPayload =
-                new IkeNotifyPayload(
-                        IkePayload.PROTOCOL_ID_ESP,
-                        spi,
-                        IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA,
-                        new byte[0]);
-
-        List<IkePayload> payloadList = makeCreateChildPayloadList(isResp);
-        payloadList.add(rekeyPayload);
-
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                isResp,
-                payloadList);
-    }
-
-    private List<IkePayload> makeCreateChildPayloadList(boolean isResp) throws Exception {
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER);
-
-        payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING);
-
-        return hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, isResp);
-    }
-
-    private ReceivedIkePacket makeDeleteChildPacket(IkeDeletePayload[] payloads, boolean isResp)
-            throws Exception {
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_INFORMATIONAL,
-                isResp,
-                Arrays.asList(payloads));
-    }
-
-    private ReceivedIkePacket makeRekeyIkeResponse() throws Exception {
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE);
-
-        payloadHexStringList.add(IKE_REKEY_SA_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(KE_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(NONCE_RESP_PAYLOAD_HEX_STRING);
-
-        return makeDummyEncryptedReceivedIkePacket(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                true /*isResp*/,
-                payloadTypeList,
-                payloadHexStringList);
-    }
-
-    private ReceivedIkePacket makeDeleteIkeResponse(IkeSaRecord ikeSaRecord) throws Exception {
-        return makeDummyEncryptedReceivedIkePacket(
-                ikeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_INFORMATIONAL,
-                true /*isResp*/,
-                new LinkedList<>(),
-                new LinkedList<>());
-    }
-
-    private ReceivedIkePacket makeDpdIkeRequest(IkeSaRecord saRecord) throws Exception {
-        return makeDummyEncryptedReceivedIkePacket(
-                saRecord,
-                IkeHeader.EXCHANGE_TYPE_INFORMATIONAL,
-                false /*isResp*/,
-                new LinkedList<>(),
-                new LinkedList<>());
-    }
-
-    private ReceivedIkePacket makeDpdIkeRequest(int msgId, byte[] dummyIkePacketBytes)
-            throws Exception {
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                EXCHANGE_TYPE_INFORMATIONAL,
-                false /*isResp*/,
-                msgId,
-                new LinkedList<>(),
-                dummyIkePacketBytes);
-    }
-
-    private ReceivedIkePacket makeRekeyIkeRequest() throws Exception {
-        IkeSaPayload saPayload =
-                (IkeSaPayload)
-                        IkeTestUtils.hexStringToIkePayload(
-                                IkePayload.PAYLOAD_TYPE_SA,
-                                false /*isResp*/,
-                                IKE_REKEY_SA_PAYLOAD_HEX_STRING);
-        return makeRekeyIkeRequest(saPayload);
-    }
-
-    private ReceivedIkePacket makeRekeyIkeRequestWithUnacceptableProposal() throws Exception {
-        IkeSaPayload saPayload =
-                (IkeSaPayload)
-                        IkeTestUtils.hexStringToIkePayload(
-                                IkePayload.PAYLOAD_TYPE_SA,
-                                false /*isResp*/,
-                                IKE_REKEY_UNACCEPTABLE_SA_PAYLOAD_HEX_STRING);
-        return makeRekeyIkeRequest(saPayload);
-    }
-
-    private ReceivedIkePacket makeRekeyIkeRequest(IkeSaPayload saPayload) throws Exception {
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_KE);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_NONCE);
-
-        payloadHexStringList.add(KE_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(NONCE_INIT_PAYLOAD_HEX_STRING);
-
-        List<IkePayload> payloadList =
-                hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/);
-        payloadList.add(saPayload);
-
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord,
-                IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                false /*isResp*/,
-                payloadList);
-    }
-
-    private ReceivedIkePacket makeDeleteIkeRequest(IkeSaRecord saRecord) throws Exception {
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_DELETE);
-
-        payloadHexStringList.add(DELETE_IKE_PAYLOAD_HEX_STRING);
-
-        return makeDummyEncryptedReceivedIkePacket(
-                saRecord,
-                IkeHeader.EXCHANGE_TYPE_INFORMATIONAL,
-                false /*isResp*/,
-                payloadTypeList,
-                payloadHexStringList);
-    }
-
-    private ReceivedIkePacket makeResponseWithErrorNotify(IkeNotifyPayload notify)
-            throws Exception {
-        List<IkePayload> payloads = new LinkedList<>();
-        payloads.add(notify);
-        return makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                mSpyCurrentIkeSaRecord, EXCHANGE_TYPE_INFORMATIONAL, true /*isResp*/, payloads);
-    }
-
-    private static boolean isIkePayloadExist(
-            List<IkePayload> payloadList, @IkePayload.PayloadType int payloadType) {
-        for (IkePayload payload : payloadList) {
-            if (payload.payloadType == payloadType) return true;
-        }
-        return false;
-    }
-
-    private static boolean isNotifyExist(
-            List<IkePayload> payloadList, @IkeNotifyPayload.NotifyType int notifyType) {
-        for (IkeNotifyPayload notify :
-                IkePayload.getPayloadListForTypeInProvidedList(
-                        PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class, payloadList)) {
-            if (notify.notifyType == notifyType) return true;
-        }
-        return false;
-    }
-
-    private void verifyIncrementLocaReqMsgId() {
-        assertEquals(
-                ++mExpectedCurrentSaLocalReqMsgId,
-                mSpyCurrentIkeSaRecord.getLocalRequestMessageId());
-    }
-
-    private void verifyIncrementRemoteReqMsgId() {
-        assertEquals(
-                ++mExpectedCurrentSaRemoteReqMsgId,
-                mSpyCurrentIkeSaRecord.getRemoteRequestMessageId());
-    }
-
-    private void verifyRetransmissionStarted() {
-        assertTrue(
-                mIkeSessionStateMachine
-                        .getHandler()
-                        .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT));
-    }
-
-    private void verifyRetransmissionStopped() {
-        assertFalse(
-                mIkeSessionStateMachine
-                        .getHandler()
-                        .hasMessages(IkeSessionStateMachine.CMD_RETRANSMIT));
-    }
-
-    private IkeMessage verifyEncryptAndEncodeAndGetMessage(IkeSaRecord ikeSaRecord) {
-        verify(mMockIkeMessageHelper)
-                .encryptAndEncode(
-                        anyObject(),
-                        anyObject(),
-                        eq(ikeSaRecord),
-                        mIkeMessageCaptor.capture(),
-                        anyBoolean(),
-                        anyInt());
-        return mIkeMessageCaptor.getValue();
-    }
-
-    private void verifyEncryptAndEncodeNeverCalled(IkeSaRecord ikeSaRecord) {
-        verify(mMockIkeMessageHelper, never())
-                .encryptAndEncode(
-                        anyObject(),
-                        anyObject(),
-                        eq(ikeSaRecord),
-                        any(IkeMessage.class),
-                        anyBoolean(),
-                        anyInt());
-    }
-
-    private void verifyEncryptAndEncodeNeverCalled() {
-        verify(mMockIkeMessageHelper, never())
-                .encryptAndEncode(
-                        anyObject(),
-                        anyObject(),
-                        any(IkeSaRecord.class),
-                        any(IkeMessage.class),
-                        anyBoolean(),
-                        anyInt());
-    }
-
-    private void resetMockIkeMessageHelper() {
-        reset(mMockIkeMessageHelper);
-        when(mMockIkeMessageHelper.encode(any())).thenReturn(new byte[0]);
-        when(mMockIkeMessageHelper.encryptAndEncode(
-                        any(), any(), any(), any(), anyBoolean(), anyInt()))
-                .thenReturn(new byte[1][0]);
-    }
-
-    @Test
-    public void testQuit() {
-        mIkeSessionStateMachine.quit();
-        mLooper.dispatchAll();
-
-        verify(mSpyIkeSocket).releaseReference(eq(mIkeSessionStateMachine));
-        verify(mSpyIkeSocket).close();
-    }
-
-    @Test
-    public void testAllocateIkeSpi() throws Exception {
-        // Test randomness.
-        IkeSecurityParameterIndex ikeSpiOne =
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS);
-        IkeSecurityParameterIndex ikeSpiTwo =
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS);
-
-        assertNotEquals(ikeSpiOne.getSpi(), ikeSpiTwo.getSpi());
-        ikeSpiTwo.close();
-
-        // Test duplicate SPIs.
-        long spiValue = ikeSpiOne.getSpi();
-        try {
-            IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS, spiValue);
-            fail("Expected to fail because duplicate SPI was assigned to the same address.");
-        } catch (IOException expected) {
-
-        }
-
-        ikeSpiOne.close();
-        IkeSecurityParameterIndex ikeSpiThree =
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(LOCAL_ADDRESS, spiValue);
-        ikeSpiThree.close();
-    }
-
-    private void setupFirstIkeSa() throws Exception {
-        // Inject IkeSaRecord and release IKE SPI resource since we will lose their references
-        // later.
-        when(mMockSaRecordHelper.makeFirstIkeSaRecord(any(), any(), any()))
-                .thenAnswer(
-                        (invocation) -> {
-                            captureAndReleaseIkeSpiResource(invocation, 2);
-                            return mSpyCurrentIkeSaRecord;
-                        });
-    }
-
-    private void setupRekeyedIkeSa(IkeSaRecord rekeySaRecord) throws Exception {
-        // Inject IkeSaRecord and release IKE SPI resource since we will lose their references
-        // later.
-        when(mMockSaRecordHelper.makeRekeyedIkeSaRecord(
-                        eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any()))
-                .thenAnswer(
-                        (invocation) -> {
-                            captureAndReleaseIkeSpiResource(invocation, 4);
-                            return rekeySaRecord;
-                        });
-    }
-
-    private void throwExceptionWhenMakeRekeyIkeSa(Exception exception) throws Exception {
-        // Inject IkeSaRecord and release IKE SPI resource since we will lose their references
-        // later.
-        when(mMockSaRecordHelper.makeRekeyedIkeSaRecord(
-                        eq(mSpyCurrentIkeSaRecord), any(), any(), any(), any()))
-                .thenAnswer(
-                        (invocation) -> {
-                            captureAndReleaseIkeSpiResource(invocation, 4);
-                            throw exception;
-                        });
-    }
-
-    private void captureAndReleaseIkeSpiResource(InvocationOnMock invocation, int ikeConfigIndex) {
-        IkeSaRecordConfig config = (IkeSaRecordConfig) invocation.getArguments()[ikeConfigIndex];
-        config.initSpi.close();
-        config.respSpi.close();
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeInit() throws Exception {
-        setupFirstIkeSa();
-
-        // Send IKE INIT request
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Receive IKE INIT response
-        ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket);
-        mLooper.dispatchAll();
-        verifyIncrementLocaReqMsgId();
-
-        // Validate outbound IKE INIT request
-        verify(mMockIkeMessageHelper, times(2)).encode(mIkeMessageCaptor.capture());
-        IkeMessage ikeInitReqMessage = mIkeMessageCaptor.getValue();
-
-        IkeHeader ikeHeader = ikeInitReqMessage.ikeHeader;
-        assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT, ikeHeader.exchangeType);
-        assertFalse(ikeHeader.isResponseMsg);
-        assertTrue(ikeHeader.fromIkeInitiator);
-
-        List<IkePayload> payloadList = ikeInitReqMessage.ikePayloadList;
-        assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_SA));
-        assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_KE));
-        assertTrue(isIkePayloadExist(payloadList, IkePayload.PAYLOAD_TYPE_NONCE));
-        assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP));
-        assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_NAT_DETECTION_DESTINATION_IP));
-        assertTrue(isNotifyExist(payloadList, NOTIFY_TYPE_IKEV2_FRAGMENTATION_SUPPORTED));
-
-        verify(mSpyIkeSocket)
-                .registerIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine));
-
-        verify(mMockIkeMessageHelper)
-                .decode(0, dummyReceivedIkePacket.ikeHeader, dummyReceivedIkePacket.ikePacketBytes);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-
-        // Validate negotiated SA proposal.
-        IkeSaProposal negotiatedProposal = mIkeSessionStateMachine.mSaProposal;
-        assertNotNull(negotiatedProposal);
-
-        assertEquals(
-                new EncryptionTransform[] {mIkeEncryptionTransform},
-                negotiatedProposal.getEncryptionTransforms());
-        assertEquals(
-                new IntegrityTransform[] {mIkeIntegrityTransform},
-                negotiatedProposal.getIntegrityTransforms());
-        assertEquals(new PrfTransform[] {mIkePrfTransform}, negotiatedProposal.getPrfTransforms());
-
-        // Validate current IkeSaRecord.
-        verify(mMockSaRecordHelper)
-                .makeFirstIkeSaRecord(
-                        any(IkeMessage.class),
-                        any(IkeMessage.class),
-                        mIkeSaRecordConfigCaptor.capture());
-
-        IkeSaRecordConfig ikeSaRecordConfig = mIkeSaRecordConfigCaptor.getValue();
-        assertEquals(KEY_LEN_IKE_PRF, ikeSaRecordConfig.prf.getKeyLength());
-        assertEquals(KEY_LEN_IKE_INTE, ikeSaRecordConfig.integrityKeyLength);
-        assertEquals(KEY_LEN_IKE_ENCR, ikeSaRecordConfig.encryptionKeyLength);
-        assertEquals(CMD_LOCAL_REQUEST_REKEY_IKE, ikeSaRecordConfig.futureRekeyEvent.procedureType);
-
-        // Validate NAT detection
-        assertTrue(mIkeSessionStateMachine.mIsLocalBehindNat);
-        assertFalse(mIkeSessionStateMachine.mIsRemoteBehindNat);
-
-        // Validate fragmentation support negotiation
-        assertTrue(mIkeSessionStateMachine.mSupportFragment);
-    }
-
-    private void setIkeInitResults() throws Exception {
-        mIkeSessionStateMachine.mIkeCipher = mock(IkeCipher.class);
-        mIkeSessionStateMachine.mIkeIntegrity = mock(IkeMacIntegrity.class);
-        mIkeSessionStateMachine.mIkePrf = mock(IkeMacPrf.class);
-        mIkeSessionStateMachine.mSaProposal = buildSaProposal();
-        mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyCurrentIkeSaRecord;
-        mIkeSessionStateMachine.mLocalAddress = LOCAL_ADDRESS;
-        mIkeSessionStateMachine.mIsLocalBehindNat = true;
-        mIkeSessionStateMachine.mIsRemoteBehindNat = false;
-        mIkeSessionStateMachine.mSupportFragment = true;
-        mIkeSessionStateMachine.addIkeSaRecord(mSpyCurrentIkeSaRecord);
-    }
-
-    /** Initializes the mIkeSessionStateMachine in the IDLE state. */
-    private void setupIdleStateMachine() throws Exception {
-        setIkeInitResults();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-
-        mDummyChildSmCallback =
-                createChildAndGetChildSessionSmCallback(
-                        mMockChildSessionStateMachine, CHILD_SPI_REMOTE, mMockChildSessionCallback);
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    private void mockIkeInitAndTransitionToIkeAuth(State authState) throws Exception {
-        setIkeInitResults();
-
-        // Need to create a real IkeMacPrf instance for authentication because we cannot inject a
-        // method stub for IkeMacPrf#signBytes. IkeMacPrf#signBytes is inheritted from a package
-        // protected class IkePrf. We don't have the visibility to mock it.
-        mIkeSessionStateMachine.mIkePrf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-
-        mIkeSessionStateMachine.mIkeInitRequestBytes = new byte[0];
-        mIkeSessionStateMachine.mIkeInitResponseBytes = new byte[0];
-        mIkeSessionStateMachine.mIkeInitNoncePayload = new IkeNoncePayload();
-        mIkeSessionStateMachine.mIkeRespNoncePayload = new IkeNoncePayload();
-
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_FORCE_TRANSITION, authState);
-        mLooper.dispatchAll();
-    }
-
-    private void setupChildStateMachineFactory(ChildSessionStateMachine child) {
-        // After state machine start, add to the callback->statemachine map
-        when(mMockChildSessionFactoryHelper.makeChildSessionStateMachine(
-                        eq(mLooper.getLooper()),
-                        eq(mContext),
-                        eq(mChildSessionOptions),
-                        eq(mSpyUserCbExecutor),
-                        any(ChildSessionCallback.class),
-                        any(IChildSessionSmCallback.class)))
-                .thenReturn(child);
-    }
-
-    /**
-     * Utility to register a new callback -> state machine mapping.
-     *
-     * <p>Must be used if IkeSessionStateMachine.openChildSession() is not called, but commands
-     * injected instead.
-     *
-     * @param callback The callback to be used for the mapping
-     * @param sm The ChildSessionStateMachine instance to be used.
-     */
-    private void registerChildStateMachine(
-            ChildSessionCallback callback, ChildSessionStateMachine sm) {
-        setupChildStateMachineFactory(sm);
-        mIkeSessionStateMachine.registerChildSessionCallback(
-                mChildSessionOptions, callback, false /*isFirstChild*/);
-    }
-
-    @Test
-    public void testCreateAdditionalChild() throws Exception {
-        setupIdleStateMachine();
-
-        ChildSessionCallback childCallback = mock(ChildSessionCallback.class);
-        ChildSessionStateMachine childStateMachine = mock(ChildSessionStateMachine.class);
-        registerChildStateMachine(childCallback, childStateMachine);
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new ChildLocalRequest(
-                        IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_CHILD,
-                        childCallback,
-                        mChildSessionOptions));
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verify(childStateMachine)
-                .createChildSession(
-                        eq(LOCAL_ADDRESS),
-                        eq(REMOTE_ADDRESS),
-                        any(), // udpEncapSocket
-                        eq(mIkeSessionStateMachine.mIkePrf),
-                        any()); // sk_d
-
-        // Once for initial child, a second time for the additional child.
-        verify(mMockChildSessionFactoryHelper)
-                .makeChildSessionStateMachine(
-                        eq(mLooper.getLooper()),
-                        eq(mContext),
-                        eq(mChildSessionOptions),
-                        eq(mSpyUserCbExecutor),
-                        eq(childCallback),
-                        mChildSessionSmCbCaptor.capture());
-        IChildSessionSmCallback cb = mChildSessionSmCbCaptor.getValue();
-
-        // Mocking sending request
-        cb.onOutboundPayloadsReady(
-                IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                false /*isResp*/,
-                new LinkedList<>(),
-                childStateMachine);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        IkeMessage createChildRequest = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = createChildRequest.ikeHeader;
-        assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType);
-        assertFalse(ikeHeader.isResponseMsg);
-        assertTrue(ikeHeader.fromIkeInitiator);
-        assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId);
-        assertTrue(createChildRequest.ikePayloadList.isEmpty());
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-
-        // Mocking receiving response
-        ReceivedIkePacket dummyCreateChildResp = makeCreateChildCreateMessage(true /*isResp*/);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyCreateChildResp);
-        mLooper.dispatchAll();
-
-        verifyIncrementLocaReqMsgId();
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyCreateChildResp);
-
-        verify(childStateMachine)
-                .receiveResponse(
-                        eq(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA), mPayloadListCaptor.capture());
-
-        List<IkePayload> childRespList = mPayloadListCaptor.getValue();
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA));
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR));
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER));
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE));
-
-        // Mock finishing procedure
-        cb.onProcedureFinished(childStateMachine);
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-        verifyRetransmissionStopped();
-    }
-
-    @Test
-    public void testTriggerDeleteChildLocal() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new ChildLocalRequest(
-                        IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD,
-                        mMockChildSessionCallback,
-                        null /*childOptions*/));
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verify(mMockChildSessionStateMachine).deleteChildSession();
-    }
-
-    @Test
-    public void testHandleDeleteChildBeforeCreation() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new ChildLocalRequest(
-                        IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_CHILD,
-                        mock(ChildSessionCallback.class),
-                        null /*childOptions*/));
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testTriggerRekeyChildLocal() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new ChildLocalRequest(
-                        IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD,
-                        mMockChildSessionCallback,
-                        null /*childOptions*/));
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verify(mMockChildSessionStateMachine).rekeyChildSession();
-    }
-
-    @Test
-    public void testScheduleAndTriggerRekeyChildLocal() throws Exception {
-        setupIdleStateMachine();
-        long dummyRekeyTimeout = 10000L;
-
-        ChildLocalRequest rekeyRequest =
-                new ChildLocalRequest(
-                        IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD,
-                        mMockChildSessionCallback,
-                        null /*childOptions*/);
-        mDummyChildSmCallback.scheduleLocalRequest(rekeyRequest, dummyRekeyTimeout);
-
-        mLooper.moveTimeForward(dummyRekeyTimeout);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verify(mMockChildSessionStateMachine).rekeyChildSession();
-    }
-
-    private IChildSessionSmCallback createChildAndGetChildSessionSmCallback(
-            ChildSessionStateMachine child, int remoteSpi) throws Exception {
-        return createChildAndGetChildSessionSmCallback(
-                child, remoteSpi, mock(ChildSessionCallback.class));
-    }
-
-    private IChildSessionSmCallback createChildAndGetChildSessionSmCallback(
-            ChildSessionStateMachine child, int remoteSpi, ChildSessionCallback childCallback)
-            throws Exception {
-        registerChildStateMachine(childCallback, child);
-
-        IChildSessionSmCallback cb = mIkeSessionStateMachine.new ChildSessionSmCallback();
-        cb.onChildSaCreated(remoteSpi, child);
-        mLooper.dispatchAll();
-
-        return cb;
-    }
-
-    private void transitionToChildProcedureOngoing() {
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mChildProcedureOngoing);
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-    }
-
-    private void verifyChildReceiveDeleteRequest(
-            ChildSessionStateMachine child, IkeDeletePayload[] expectedDelPayloads) {
-        verify(child)
-                .receiveRequest(
-                        eq(IKE_EXCHANGE_SUBTYPE_DELETE_CHILD),
-                        eq(EXCHANGE_TYPE_INFORMATIONAL),
-                        mPayloadListCaptor.capture());
-        List<IkePayload> reqPayloads = mPayloadListCaptor.getValue();
-
-        int numExpectedDelPayloads = expectedDelPayloads.length;
-        assertEquals(numExpectedDelPayloads, reqPayloads.size());
-
-        for (int i = 0; i < numExpectedDelPayloads; i++) {
-            assertEquals(expectedDelPayloads[i], (IkeDeletePayload) reqPayloads.get(i));
-        }
-    }
-
-    private void outboundDeleteChildPayloadsReady(
-            IChildSessionSmCallback childSmCb,
-            IkeDeletePayload delPayload,
-            boolean isResp,
-            ChildSessionStateMachine child) {
-        List<IkePayload> outPayloadList = new LinkedList<>();
-        outPayloadList.add(delPayload);
-        childSmCb.onOutboundPayloadsReady(
-                IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, isResp, outPayloadList, child);
-        mLooper.dispatchAll();
-    }
-
-    private List<IkePayload> verifyOutInfoMsgHeaderAndGetPayloads(boolean isResp) {
-        IkeMessage deleteChildMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = deleteChildMessage.ikeHeader;
-        assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi);
-        assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi);
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-        assertEquals(isResp, ikeHeader.isResponseMsg);
-
-        return deleteChildMessage.ikePayloadList;
-    }
-
-    @Test
-    public void testDeferChildRequestToChildProcedureOngoing() throws Exception {
-        setupIdleStateMachine();
-
-        IkeDeletePayload[] inboundDelPayloads =
-                new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})};
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/));
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads);
-    }
-
-    @Test
-    public void testRemoteDeleteOneChild() throws Exception {
-        setupIdleStateMachine();
-        transitionToChildProcedureOngoing();
-
-        // Receive Delete Child Request
-        IkeDeletePayload[] inboundDelPayloads =
-                new IkeDeletePayload[] {new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE})};
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/));
-        mLooper.dispatchAll();
-
-        // Verify received payloads
-        verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads);
-
-        // Outbound payload list ready
-        IkeDeletePayload outDelPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL});
-        outboundDeleteChildPayloadsReady(
-                mDummyChildSmCallback,
-                outDelPayload,
-                true /*isResp*/,
-                mMockChildSessionStateMachine);
-
-        // Verify outbound response
-        List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, payloadList.size());
-        assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0)));
-    }
-
-    @Test
-    public void testRemoteDeleteMultipleChildSession() throws Exception {
-        ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class);
-        int childOneRemoteSpi = 11;
-        int childOneLocalSpi = 12;
-
-        ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class);
-        int childTwoRemoteSpi = 21;
-        int childTwoLocalSpi = 22;
-
-        setupIdleStateMachine();
-        IChildSessionSmCallback childSmCbOne =
-                createChildAndGetChildSessionSmCallback(childOne, childOneRemoteSpi);
-        IChildSessionSmCallback childSmCbTwo =
-                createChildAndGetChildSessionSmCallback(childTwo, childTwoRemoteSpi);
-
-        transitionToChildProcedureOngoing();
-
-        // Receive Delete Child Request
-        IkeDeletePayload[] inboundDelPayloads =
-                new IkeDeletePayload[] {
-                    new IkeDeletePayload(new int[] {childOneRemoteSpi, childTwoRemoteSpi})
-                };
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/));
-        mLooper.dispatchAll();
-
-        // Verify received payloads
-        verifyChildReceiveDeleteRequest(childOne, inboundDelPayloads);
-        verifyChildReceiveDeleteRequest(childTwo, inboundDelPayloads);
-
-        // childOne outbound payload list ready
-        IkeDeletePayload outDelPayloadOne = new IkeDeletePayload(new int[] {childOneLocalSpi});
-        outboundDeleteChildPayloadsReady(childSmCbOne, outDelPayloadOne, true /*isResp*/, childOne);
-        mLooper.dispatchAll();
-
-        // Verify that no response is sent
-        verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord);
-
-        // childTwo outbound payload list ready
-        IkeDeletePayload outDelPayloadTwo = new IkeDeletePayload(new int[] {childTwoLocalSpi});
-        outboundDeleteChildPayloadsReady(childSmCbTwo, outDelPayloadTwo, true /*isResp*/, childTwo);
-        mLooper.dispatchAll();
-
-        // Verify outbound response
-        List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(2, payloadList.size());
-        assertEquals(outDelPayloadOne, ((IkeDeletePayload) payloadList.get(0)));
-        assertEquals(outDelPayloadTwo, ((IkeDeletePayload) payloadList.get(1)));
-    }
-
-    @Test
-    public void testRemoteDeleteMultipleChildSaInSameSession() throws Exception {
-        int newChildRemoteSpi = 21;
-        int newChildLocalSpi = 22;
-
-        setupIdleStateMachine();
-        mDummyChildSmCallback.onChildSaCreated(newChildRemoteSpi, mMockChildSessionStateMachine);
-
-        transitionToChildProcedureOngoing();
-
-        // Receive Delete Child Request
-        IkeDeletePayload[] inboundDelPayloads =
-                new IkeDeletePayload[] {
-                    new IkeDeletePayload(new int[] {CHILD_SPI_REMOTE}),
-                    new IkeDeletePayload(new int[] {newChildRemoteSpi})
-                };
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/));
-        mLooper.dispatchAll();
-
-        // Verify received payloads
-        verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads);
-
-        // child outbound payload list ready
-        IkeDeletePayload outDelPayload =
-                new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL, newChildLocalSpi});
-        outboundDeleteChildPayloadsReady(
-                mDummyChildSmCallback,
-                outDelPayload,
-                true /*isResp*/,
-                mMockChildSessionStateMachine);
-        mLooper.dispatchAll();
-
-        // Verify outbound response
-        List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, payloadList.size());
-        assertEquals(outDelPayload, ((IkeDeletePayload) payloadList.get(0)));
-    }
-
-    @Test
-    public void testIgnoreUnrecognizedChildSpi() throws Exception {
-        int unrecognizedSpi = 2;
-
-        setupIdleStateMachine();
-        transitionToChildProcedureOngoing();
-
-        // Receive Delete Child Request
-        IkeDeletePayload[] inboundDelPayloads =
-                new IkeDeletePayload[] {
-                    new IkeDeletePayload(new int[] {unrecognizedSpi, CHILD_SPI_REMOTE})
-                };
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/));
-        mLooper.dispatchAll();
-
-        // Verify received payloads
-        verifyChildReceiveDeleteRequest(mMockChildSessionStateMachine, inboundDelPayloads);
-
-        // child outbound payload list ready
-        IkeDeletePayload outPayload = new IkeDeletePayload(new int[] {CHILD_SPI_LOCAL});
-        outboundDeleteChildPayloadsReady(
-                mDummyChildSmCallback, outPayload, true /*isResp*/, mMockChildSessionStateMachine);
-        mLooper.dispatchAll();
-
-        // Verify outbound response
-        List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, payloadList.size());
-        assertEquals(outPayload, ((IkeDeletePayload) payloadList.get(0)));
-    }
-
-    @Test
-    public void testRemoteDeleteChildHandlesReqWithNoRecognizedSpi() throws Exception {
-        int unrecognizedSpi = 2;
-
-        setupIdleStateMachine();
-
-        // Receive Delete Child Request without any recognized SPI
-        IkeDeletePayload[] inboundDelPayloads =
-                new IkeDeletePayload[] {new IkeDeletePayload(new int[] {unrecognizedSpi})};
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteChildPacket(inboundDelPayloads, false /*isResp*/));
-        mLooper.dispatchAll();
-
-        // Verify outbound empty response was sent
-        List<IkePayload> payloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertTrue(payloadList.isEmpty());
-
-        // Verify IKE Session was back to Idle
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testRemoteCreateChild() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                CMD_RECEIVE_IKE_PACKET, makeCreateChildCreateMessage(false /*isResp*/));
-
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, ikePayloadList.size());
-        assertEquals(
-                ERROR_TYPE_NO_ADDITIONAL_SAS,
-                ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType);
-    }
-
-    @Test
-    public void testTriggerRemoteRekeyChild() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                CMD_RECEIVE_IKE_PACKET,
-                makeRekeyChildCreateMessage(false /*isResp*/, CHILD_SPI_REMOTE));
-        mLooper.dispatchAll();
-
-        verify(mMockChildSessionStateMachine)
-                .receiveRequest(
-                        eq(IKE_EXCHANGE_SUBTYPE_REKEY_CHILD),
-                        eq(EXCHANGE_TYPE_CREATE_CHILD_SA),
-                        any(List.class));
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-    }
-
-    @Test
-    public void testHandleRekeyChildReqWithUnrecognizedSpi() throws Exception {
-        int unrecognizedSpi = 2;
-
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                CMD_RECEIVE_IKE_PACKET,
-                makeRekeyChildCreateMessage(false /*isResp*/, unrecognizedSpi));
-        mLooper.dispatchAll();
-
-        verify(mMockChildSessionStateMachine, never()).receiveRequest(anyInt(), anyInt(), any());
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, ikePayloadList.size());
-        IkeNotifyPayload notifyPayload = (IkeNotifyPayload) ikePayloadList.get(0);
-        assertEquals(ERROR_TYPE_CHILD_SA_NOT_FOUND, notifyPayload.notifyType);
-        assertEquals(unrecognizedSpi, notifyPayload.spi);
-    }
-
-    private void verifyNotifyUserCloseSession() {
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockIkeSessionCallback).onClosed();
-    }
-
-    @Test
-    public void testRcvRemoteDeleteIkeWhenChildProcedureOngoing() throws Exception {
-        setupIdleStateMachine();
-        transitionToChildProcedureOngoing();
-
-        mIkeSessionStateMachine.sendMessage(
-                CMD_RECEIVE_IKE_PACKET, makeDeleteIkeRequest(mSpyCurrentIkeSaRecord));
-
-        mLooper.dispatchAll();
-
-        verifyNotifyUserCloseSession();
-
-        // Verify state machine quit properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-
-        List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertTrue(ikePayloadList.isEmpty());
-    }
-
-    @Test
-    public void testRcvRemoteRekeyIkeWhenChildProcedureOngoing() throws Exception {
-        setupIdleStateMachine();
-        transitionToChildProcedureOngoing();
-
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, makeRekeyIkeRequest());
-
-        mLooper.dispatchAll();
-
-        // Since we have forced state machine to transition to ChildProcedureOngoing state without
-        // really starting any Child procedure, it should transition to Idle at this time.
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, ikePayloadList.size());
-        assertEquals(
-                ERROR_TYPE_TEMPORARY_FAILURE,
-                ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType);
-    }
-
-    @Test
-    public void testKillChildSessions() throws Exception {
-        setupIdleStateMachine();
-
-        ChildSessionStateMachine childOne = mock(ChildSessionStateMachine.class);
-        ChildSessionStateMachine childTwo = mock(ChildSessionStateMachine.class);
-        registerChildStateMachine(mock(ChildSessionCallback.class), childOne);
-        registerChildStateMachine(mock(ChildSessionCallback.class), childTwo);
-
-        mIkeSessionStateMachine.mCurrentIkeSaRecord = null;
-
-        mIkeSessionStateMachine.quitNow();
-
-        mLooper.dispatchAll();
-
-        verify(childOne).killSession();
-        verify(childTwo).killSession();
-    }
-
-    private IkeMessage verifyAuthReqAndGetMsg() {
-        IkeMessage ikeAuthReqMessage = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = ikeAuthReqMessage.ikeHeader;
-        assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType);
-        assertFalse(ikeHeader.isResponseMsg);
-        assertTrue(ikeHeader.fromIkeInitiator);
-
-        return ikeAuthReqMessage;
-    }
-
-    private IkeMessage verifyAuthReqWithChildPayloadsAndGetMsg() {
-        IkeMessage ikeAuthReqMessage = verifyAuthReqAndGetMsg();
-
-        assertNotNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_ID_INITIATOR, IkeIdPayload.class));
-        assertNotNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_ID_RESPONDER, IkeIdPayload.class));
-        assertNotNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class));
-        assertNotNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_TS_INITIATOR, IkeTsPayload.class));
-        assertNotNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_TS_RESPONDER, IkeTsPayload.class));
-
-        return ikeAuthReqMessage;
-    }
-
-    private void verifySharedKeyAuthentication(
-            IkeAuthPskPayload spyAuthPayload,
-            IkeIdPayload respIdPayload,
-            List<IkePayload> authRelatedPayloads,
-            boolean hasChildPayloads)
-            throws Exception {
-        // Send IKE AUTH response to IKE state machine
-        ReceivedIkePacket authResp = makeIkeAuthRespWithChildPayloads(authRelatedPayloads);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, authResp);
-        mLooper.dispatchAll();
-
-        // Validate outbound IKE AUTH request
-        IkeMessage ikeAuthReqMessage;
-        if (hasChildPayloads) {
-            ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg();
-        } else {
-            ikeAuthReqMessage = verifyAuthReqAndGetMsg();
-        }
-        assertNotNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPskPayload.class));
-
-        // Validate inbound IKE AUTH response
-        verifyIncrementLocaReqMsgId();
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, authResp);
-
-        // Validate authentication is done. Cannot use matchers because IkeAuthPskPayload is final.
-        verify(spyAuthPayload)
-                .verifyInboundSignature(
-                        mPsk,
-                        mIkeSessionStateMachine.mIkeInitRequestBytes,
-                        mSpyCurrentIkeSaRecord.nonceInitiator,
-                        respIdPayload.getEncodedPayloadBody(),
-                        mIkeSessionStateMachine.mIkePrf,
-                        mSpyCurrentIkeSaRecord.getSkPr());
-
-        // Validate that user has been notified
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockIkeSessionCallback).onOpened(any());
-        // TODO: Verify sessionConfiguration
-
-        // Verify payload list pair for first Child negotiation
-        ArgumentCaptor<List<IkePayload>> mReqPayloadListCaptor =
-                ArgumentCaptor.forClass(List.class);
-        ArgumentCaptor<List<IkePayload>> mRespPayloadListCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mMockChildSessionStateMachine)
-                .handleFirstChildExchange(
-                        mReqPayloadListCaptor.capture(),
-                        mRespPayloadListCaptor.capture(),
-                        eq(LOCAL_ADDRESS),
-                        eq(REMOTE_ADDRESS),
-                        any(), // udpEncapSocket
-                        eq(mIkeSessionStateMachine.mIkePrf),
-                        any()); // sk_d
-        List<IkePayload> childReqList = mReqPayloadListCaptor.getValue();
-        List<IkePayload> childRespList = mRespPayloadListCaptor.getValue();
-
-        assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_SA));
-        assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR));
-        assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER));
-        assertTrue(isIkePayloadExist(childReqList, IkePayload.PAYLOAD_TYPE_NONCE));
-        IkeSaPayload reqSaPayload =
-                IkePayload.getPayloadForTypeInProvidedList(
-                        IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childReqList);
-        assertFalse(reqSaPayload.isSaResponse);
-
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_SA));
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_INITIATOR));
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_TS_RESPONDER));
-        assertTrue(isIkePayloadExist(childRespList, IkePayload.PAYLOAD_TYPE_NONCE));
-        IkeSaPayload respSaPayload =
-                IkePayload.getPayloadForTypeInProvidedList(
-                        IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class, childRespList);
-        assertTrue(respSaPayload.isSaResponse);
-
-        // Mock finishing first Child SA negotiation.
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-
-        verify(mMockChildSessionFactoryHelper)
-                .makeChildSessionStateMachine(
-                        eq(mLooper.getLooper()),
-                        eq(mContext),
-                        eq(mChildSessionOptions),
-                        eq(mSpyUserCbExecutor),
-                        eq(mMockChildSessionCallback),
-                        mChildSessionSmCbCaptor.capture());
-        IChildSessionSmCallback cb = mChildSessionSmCbCaptor.getValue();
-
-        cb.onProcedureFinished(mMockChildSessionStateMachine);
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    private IkeAuthPskPayload makeSpyRespPskPayload() throws Exception {
-        IkeAuthPskPayload spyAuthPayload =
-                spy(
-                        (IkeAuthPskPayload)
-                                IkeTestUtils.hexStringToIkePayload(
-                                        IkePayload.PAYLOAD_TYPE_AUTH,
-                                        true /*isResp*/,
-                                        PSK_AUTH_RESP_PAYLOAD_HEX_STRING));
-
-        doNothing()
-                .when(spyAuthPayload)
-                .verifyInboundSignature(any(), any(), any(), any(), any(), any());
-        return spyAuthPayload;
-    }
-
-    private IkeAuthDigitalSignPayload makeSpyDigitalSignAuthPayload() throws Exception {
-        IkeAuthDigitalSignPayload spyAuthPayload =
-                spy(
-                        (IkeAuthDigitalSignPayload)
-                                IkeTestUtils.hexStringToIkePayload(
-                                        IkePayload.PAYLOAD_TYPE_AUTH,
-                                        true /*isResp*/,
-                                        GENERIC_DIGITAL_SIGN_AUTH_RESP_HEX_STRING));
-        doNothing()
-                .when(spyAuthPayload)
-                .verifyInboundSignature(any(), any(), any(), any(), any(), any());
-        return spyAuthPayload;
-    }
-
-    private IkeIdPayload makeRespIdPayload() throws Exception {
-        return (IkeIdPayload)
-                IkeTestUtils.hexStringToIkePayload(
-                        IkePayload.PAYLOAD_TYPE_ID_RESPONDER,
-                        true /*isResp*/,
-                        ID_PAYLOAD_RESPONDER_HEX_STRING);
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthPsk() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-
-        // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload.
-        List<IkePayload> authRelatedPayloads = new LinkedList<>();
-        IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload();
-        authRelatedPayloads.add(spyAuthPayload);
-
-        IkeIdPayload respIdPayload = makeRespIdPayload();
-        authRelatedPayloads.add(respIdPayload);
-
-        verifySharedKeyAuthentication(spyAuthPayload, respIdPayload, authRelatedPayloads, true);
-        verifyRetransmissionStopped();
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthPskVerifyFail() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-        resetMockIkeMessageHelper();
-
-        // Build IKE AUTH response with invalid Auth-PSK Payload and ID-Responder Payload.
-        List<IkePayload> authRelatedPayloads = new LinkedList<>();
-        IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload();
-        doThrow(new AuthenticationFailedException("DummyAuthFailException"))
-                .when(spyAuthPayload)
-                .verifyInboundSignature(any(), any(), any(), any(), any(), any());
-        authRelatedPayloads.add(spyAuthPayload);
-
-        IkeIdPayload respIdPayload = makeRespIdPayload();
-        authRelatedPayloads.add(respIdPayload);
-
-        // Send response to IKE state machine
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeIkeAuthRespWithChildPayloads(authRelatedPayloads));
-        mLooper.dispatchAll();
-
-        // Verify Delete request was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/);
-        assertEquals(1, payloads.size());
-        assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType);
-
-        // Verify IKE Session was closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback)
-                .onClosedExceptionally(any(AuthenticationFailedException.class));
-    }
-
-    @Test
-    public void testAuthPskHandleRespWithParsingError() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-        resetMockIkeMessageHelper();
-
-        // Mock receiving packet with syntax error
-        ReceivedIkePacket mockInvalidPacket =
-                makeDummyReceivedIkePacketWithInvalidSyntax(
-                        mSpyCurrentIkeSaRecord, true /*isResp*/, IkeHeader.EXCHANGE_TYPE_IKE_AUTH);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket);
-        mLooper.dispatchAll();
-
-        // Verify Delete request was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/);
-        assertEquals(1, payloads.size());
-        assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType);
-
-        // Verify IKE Session is closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthPreEap() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Mock IKE INIT
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-
-        // Build IKE AUTH response with EAP. Auth, ID-Resp and Cert payloads.
-        List<IkePayload> authRelatedPayloads = new LinkedList<>();
-
-        authRelatedPayloads.add(new IkeEapPayload(EAP_DUMMY_MSG));
-        authRelatedPayloads.add(makeSpyDigitalSignAuthPayload());
-        authRelatedPayloads.add(makeRespIdPayload());
-
-        IkeCertX509CertPayload certPayload = new IkeCertX509CertPayload(mServerEndCertificate);
-        authRelatedPayloads.add(certPayload);
-
-        // Send IKE AUTH response to IKE state machine
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeIkeAuthRespWithoutChildPayloads(authRelatedPayloads));
-        mLooper.dispatchAll();
-
-        // Validate outbound IKE AUTH request
-        IkeMessage ikeAuthReqMessage = verifyAuthReqWithChildPayloadsAndGetMsg();
-        assertNull(
-                ikeAuthReqMessage.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_AUTH, IkeAuthPayload.class));
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthInEap);
-        verifyRetransmissionStopped();
-        assertNotNull(mIkeSessionStateMachine.mInitIdPayload);
-        assertNotNull(mIkeSessionStateMachine.mRespIdPayload);
-    }
-
-    private IEapCallback verifyEapAuthenticatorCreatedAndGetCallback() {
-        ArgumentCaptor<IEapCallback> captor = ArgumentCaptor.forClass(IEapCallback.class);
-
-        verify(mMockEapAuthenticatorFactory)
-                .newEapAuthenticator(
-                        eq(mIkeSessionStateMachine.getHandler().getLooper()),
-                        captor.capture(),
-                        eq(mContext),
-                        eq(mEapSessionConfig));
-
-        return captor.getValue();
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthInEapStartsAuthenticatorAndProxiesMessage()
-            throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap);
-        mLooper.dispatchAll();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EAP_START_EAP_AUTH, new IkeEapPayload(EAP_DUMMY_MSG));
-        mLooper.dispatchAll();
-
-        verifyEapAuthenticatorCreatedAndGetCallback();
-
-        verify(mMockEapAuthenticator).processEapMessage(eq(EAP_DUMMY_MSG));
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthInEapHandlesOutboundResponse() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap);
-        mLooper.dispatchAll();
-
-        IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback();
-        callback.onResponse(EAP_DUMMY_MSG);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Verify EAP response
-        IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-        IkeHeader ikeHeader = resp.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_IKE_AUTH, ikeHeader.exchangeType);
-        assertFalse(ikeHeader.isResponseMsg);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-
-        assertEquals(1, resp.ikePayloadList.size());
-        assertArrayEquals(EAP_DUMMY_MSG, ((IkeEapPayload) resp.ikePayloadList.get(0)).eapMessage);
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthInEapHandlesMissingEapPacket() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap);
-        mLooper.dispatchAll();
-
-        // Mock sending IKE_AUTH{EAP} request
-        IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback();
-        callback.onResponse(EAP_DUMMY_MSG);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Send IKE AUTH response with no EAP Payload to IKE state machine
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeIkeAuthRespWithoutChildPayloads(new LinkedList<>()));
-        mLooper.dispatchAll();
-
-        // Verify state machine quit properly
-        verify(mMockIkeSessionCallback)
-                .onClosedExceptionally(any(AuthenticationFailedException.class));
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthInEapHandlesSuccess() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap);
-        mLooper.dispatchAll();
-
-        IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback();
-
-        // Setup dummy initIdPayload for next state.
-        mIkeSessionStateMachine.mInitIdPayload = mock(IkeIdPayload.class);
-        when(mIkeSessionStateMachine.mInitIdPayload.getEncodedPayloadBody())
-                .thenReturn(new byte[0]);
-
-        callback.onSuccess(mPsk, new byte[0]); // use mPsk as MSK, eMSK does not matter
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuthPostEap);
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthInEapHandlesError() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap);
-        mLooper.dispatchAll();
-
-        IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback();
-
-        Throwable error = new IllegalArgumentException();
-        callback.onError(error);
-        mLooper.dispatchAll();
-
-        // Fires user error callbacks
-        verify(mMockIkeSessionCallback)
-                .onClosedExceptionally(argThat(err -> err.getCause() == error));
-
-        // Verify state machine quit properly
-        verify(mSpyCurrentIkeSaRecord).close();
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthInEapHandlesFailure() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthInEap);
-        mLooper.dispatchAll();
-
-        IEapCallback callback = verifyEapAuthenticatorCreatedAndGetCallback();
-        callback.onFail();
-        mLooper.dispatchAll();
-
-        // Fires user error callbacks
-        verify(mMockIkeSessionCallback)
-                .onClosedExceptionally(any(AuthenticationFailedException.class));
-
-        // Verify state machine quit properly
-        verify(mSpyCurrentIkeSaRecord).close();
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthPostEap() throws Exception {
-        mIkeSessionStateMachine.quitNow();
-        reset(mMockChildSessionFactoryHelper);
-        setupChildStateMachineFactory(mMockChildSessionStateMachine);
-        mIkeSessionStateMachine = makeAndStartIkeSession(buildIkeSessionOptionsEap());
-
-        // Setup dummy state from IkeAuthPreEap for next state.
-        mIkeSessionStateMachine.mInitIdPayload = mock(IkeIdPayload.class);
-        when(mIkeSessionStateMachine.mInitIdPayload.getEncodedPayloadBody())
-                .thenReturn(new byte[0]);
-        mIkeSessionStateMachine.mRespIdPayload =
-                (IkeIdPayload)
-                        IkeTestUtils.hexStringToIkePayload(
-                                IkePayload.PAYLOAD_TYPE_ID_RESPONDER,
-                                true /*isResp*/,
-                                ID_PAYLOAD_RESPONDER_HEX_STRING);
-
-        List<Integer> payloadTypeList = new LinkedList<>();
-        List<String> payloadHexStringList = new LinkedList<>();
-
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_SA);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_INITIATOR);
-        payloadTypeList.add(IkePayload.PAYLOAD_TYPE_TS_RESPONDER);
-
-        payloadHexStringList.add(CHILD_SA_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(TS_INIT_PAYLOAD_HEX_STRING);
-        payloadHexStringList.add(TS_RESP_PAYLOAD_HEX_STRING);
-
-        mIkeSessionStateMachine.mFirstChildReqList =
-                hexStrListToIkePayloadList(payloadTypeList, payloadHexStringList, false /*isResp*/);
-
-        // Setup state and go to IN_EAP state
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuthPostEap);
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_EAP_FINISH_EAP_AUTH, mPsk);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Build IKE AUTH response with Auth-PSK Payload and ID-Responder Payload.
-        List<IkePayload> authRelatedPayloads = new LinkedList<>();
-        IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload();
-        authRelatedPayloads.add(spyAuthPayload);
-
-        IkeIdPayload respIdPayload = makeRespIdPayload();
-
-        verifySharedKeyAuthentication(spyAuthPayload, respIdPayload, authRelatedPayloads, false);
-        verifyRetransmissionStopped();
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthHandlesFirstFrag() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-
-        // Received IKE fragment
-        byte[] unencryptedData = "testCreateIkeLocalIkeAuthHandlesFrag".getBytes();
-        int fragNum = 1;
-        int totalFragments = 2;
-        IkeSkfPayload skfPayload =
-                IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments);
-
-        ReceivedIkePacket packet =
-                makeDummyReceivedIkeFragmentPacket(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                        skfPayload,
-                        PAYLOAD_TYPE_AUTH,
-                        null /* collectedFrags*/);
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet);
-        mLooper.dispatchAll();
-
-        // Verify state doesn't change
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth);
-
-        // Verify the IkeSaRecord has stored the fragment.
-        DecodeResultPartial resultPartial =
-                mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/);
-        assertEquals(PAYLOAD_TYPE_AUTH, resultPartial.firstPayloadType);
-        assertEquals(totalFragments, resultPartial.collectedFragsList.length);
-        assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]);
-        assertFalse(resultPartial.isAllFragmentsReceived());
-
-        assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(false /*isResp*/));
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthHandlesLastFragOk() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-
-        // Set previously collected IKE fragments
-        DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class);
-        mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/);
-
-        // Build reassembled IKE AUTH response with Auth-PSK Payload and ID-Responder Payload.
-        List<IkePayload> authRelatedPayloads = new LinkedList<>();
-        IkeAuthPskPayload spyAuthPayload = makeSpyRespPskPayload();
-        authRelatedPayloads.add(spyAuthPayload);
-
-        IkeIdPayload respIdPayload = makeRespIdPayload();
-        authRelatedPayloads.add(respIdPayload);
-
-        List<IkePayload> authPayloadList =
-                getIkeAuthPayloadListWithChildPayloads(authRelatedPayloads);
-
-        // Receive last auth response and do IKE_AUTH
-        ReceivedIkePacket packet =
-                makeDummyReceivedLastIkeFragmentPacketOk(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                        mockCollectedFrags,
-                        authPayloadList,
-                        "FirstFrag".getBytes());
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet);
-        mLooper.dispatchAll();
-
-        // Verify IKE AUTH is done
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-
-        // Verify collected response fragments are cleared.
-        assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/));
-        verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/);
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeAuthHandlesLastFragError() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-        resetMockIkeMessageHelper();
-
-        // Set previously collected IKE fragments
-        DecodeResultPartial mockCollectedFrags = mock(DecodeResultPartial.class);
-        mSpyCurrentIkeSaRecord.updateCollectedFragments(mockCollectedFrags, true /*isResp*/);
-
-        // Receive last auth response with syntax error
-        ReceivedIkePacket packet =
-                makeDummyReceivedLastIkeFragmentPacketError(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                        mockCollectedFrags,
-                        new InvalidSyntaxException("IkeStateMachineTest"));
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet);
-        mLooper.dispatchAll();
-
-        // Verify Delete request is sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/);
-        assertEquals(1, payloads.size());
-        assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType);
-
-        // Verify IKE Session is closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-
-        // Collected response fragments are cleared
-        assertNull(mSpyCurrentIkeSaRecord.getCollectedFragments(true /*isResp*/));
-        verify(mSpyCurrentIkeSaRecord).resetCollectedFragments(true /*isResp*/);
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateSendsRequest() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-        verifyRetransmissionStarted();
-
-        // Verify outbound message
-        IkeMessage rekeyMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = rekeyMsg.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, ikeHeader.exchangeType);
-        assertEquals(mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), ikeHeader.messageId);
-        assertFalse(ikeHeader.isResponseMsg);
-        assertTrue(ikeHeader.fromIkeInitiator);
-
-        // Verify SA payload & proposals
-        IkeSaPayload saPayload =
-                rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class);
-        assertFalse(saPayload.isSaResponse);
-        assertEquals(1, saPayload.proposalList.size());
-
-        IkeSaPayload.IkeProposal proposal =
-                (IkeSaPayload.IkeProposal) saPayload.proposalList.get(0);
-        assertEquals(1, proposal.number); // Must be 1-indexed
-        assertEquals(IkePayload.PROTOCOL_ID_IKE, proposal.protocolId);
-        assertEquals(IkePayload.SPI_LEN_IKE, proposal.spiSize);
-        assertEquals(mIkeSessionStateMachine.mSaProposal, proposal.saProposal);
-
-        // Verify Nonce and KE payloads exist.
-        assertNotNull(
-                rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class));
-
-        IkeKePayload kePayload =
-                rekeyMsg.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class);
-        assertNotNull(kePayload);
-        assertTrue(kePayload.isOutbound);
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateHandlesResponse() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Prepare "rekeyed" SA
-        setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord);
-
-        // Receive Rekey response
-        ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementLocaReqMsgId();
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket);
-
-        // Verify in delete state, and new SA record was saved:
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalDelete);
-        verifyRetransmissionStarted();
-        assertEquals(mSpyLocalInitIkeSaRecord, mIkeSessionStateMachine.mLocalInitNewIkeSaRecord);
-        verify(mSpyIkeSocket)
-                .registerIke(
-                        eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine));
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateHandleRespWithParsingError() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-        resetMockIkeMessageHelper();
-
-        // Mock receiving packet with syntax error
-        ReceivedIkePacket mockInvalidPacket =
-                makeDummyReceivedIkePacketWithInvalidSyntax(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket);
-        mLooper.dispatchAll();
-
-        // Verify Delete request was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/);
-        assertEquals(1, payloads.size());
-        assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType);
-
-        // Verify IKE Session is closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateHandleRespWithNonFatalErrorNotify() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-
-        // Mock receiving packet with NO_PROPOSAL_CHOSEN
-        ReceivedIkePacket resp =
-                makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_NO_PROPOSAL_CHOSEN));
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp);
-        mLooper.dispatchAll();
-
-        // Verify IKE Session goes back to Idle
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        // Move time forward to trigger retry
-        mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateHandleRespWithFatalErrorNotify() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-        resetMockIkeMessageHelper();
-
-        // Mock receiving packet with NO_PROPOSAL_CHOSEN
-        ReceivedIkePacket resp =
-                makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX));
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp);
-        mLooper.dispatchAll();
-
-        // Verify no message was sent because a fatal error notification was received
-        verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord);
-
-        // Verify IKE Session is closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateSaCreationFail() throws Exception {
-        // Throw error when building new IKE SA
-        throwExceptionWhenMakeRekeyIkeSa(
-                new GeneralSecurityException("testRekeyIkeLocalCreateSaCreationFail"));
-
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-        resetMockIkeMessageHelper();
-
-        // Receive Rekey response
-        ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket);
-        mLooper.dispatchAll();
-
-        // Verify Delete request was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(false /*isResp*/);
-        assertEquals(1, payloads.size());
-        assertEquals(IkePayload.PAYLOAD_TYPE_DELETE, payloads.get(0).payloadType);
-
-        // Verify IKE Session is closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class));
-    }
-
-    @Test
-    public void testRekeyIkeLocalCreateHandleReqWithNonFatalError() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-        resetMockIkeMessageHelper();
-
-        // Build protocol exception
-        List<Integer> unsupportedPayloads = new LinkedList<>();
-        unsupportedPayloads.add(PAYLOAD_TYPE_UNSUPPORTED);
-        UnsupportedCriticalPayloadException exception =
-                new UnsupportedCriticalPayloadException(unsupportedPayloads);
-
-        // Mock receiving packet with unsupported critical payload
-        ReceivedIkePacket mockInvalidPacket =
-                makeDummyReceivedIkePacketWithDecodingError(
-                        mSpyCurrentIkeSaRecord,
-                        false /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                        exception);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket);
-        mLooper.dispatchAll();
-
-        // Verify error notification was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, payloads.size());
-
-        IkePayload payload = payloads.get(0);
-        assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType);
-        assertEquals(
-                ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD, ((IkeNotifyPayload) payload).notifyType);
-
-        // Verify IKE Session stays in the same state
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-    }
-
-    private void mockCreateAndTransitionToRekeyDeleteLocal() {
-        // Seed fake rekey data and force transition to RekeyIkeLocalDelete
-        mIkeSessionStateMachine.mLocalInitNewIkeSaRecord = mSpyLocalInitIkeSaRecord;
-        mIkeSessionStateMachine.addIkeSaRecord(mSpyLocalInitIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeLocalDelete);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-    }
-
-    @Test
-    public void testRekeyIkeLocalDeleteSendsRequest() throws Exception {
-        setupIdleStateMachine();
-        mockCreateAndTransitionToRekeyDeleteLocal();
-
-        // Verify Rekey-Delete request
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalDelete);
-        verifyRetransmissionStarted();
-
-        // Verify outbound message
-        IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = delMsg.ikeHeader;
-        assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), ikeHeader.ikeInitiatorSpi);
-        assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), ikeHeader.ikeResponderSpi);
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-        assertFalse(ikeHeader.isResponseMsg);
-
-        List<IkeDeletePayload> deletePayloadList =
-                delMsg.getPayloadListForType(
-                        IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class);
-        assertEquals(1, deletePayloadList.size());
-
-        IkeDeletePayload deletePayload = deletePayloadList.get(0);
-        assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId);
-        assertEquals(0, deletePayload.numSpi);
-        assertEquals(0, deletePayload.spiSize);
-        assertArrayEquals(new int[0], deletePayload.spisToDelete);
-    }
-
-    private void verifyRekeyReplaceSa(IkeSaRecord newSaRecord) {
-        verify(mSpyCurrentIkeSaRecord).close();
-        verify(mSpyIkeSocket).unregisterIke(eq(mSpyCurrentIkeSaRecord.getLocalSpi()));
-        verify(mSpyIkeSocket, never()).unregisterIke(eq(newSaRecord.getLocalSpi()));
-
-        assertEquals(mIkeSessionStateMachine.mCurrentIkeSaRecord, newSaRecord);
-
-        verify(mMockChildSessionStateMachine).setSkD(newSaRecord.getSkD());
-    }
-
-    @Test
-    public void testRekeyIkeLocalDeleteHandlesResponse() throws Exception {
-        setupIdleStateMachine();
-        mockCreateAndTransitionToRekeyDeleteLocal();
-
-        // Receive Delete response
-        ReceivedIkePacket dummyDeleteIkeRespReceivedPacket =
-                makeDeleteIkeResponse(mSpyCurrentIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementLocaReqMsgId();
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket);
-
-        // Verify final state - Idle, with new SA, and old SA closed.
-        verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord);
-        verify(mMockIkeSessionCallback, never()).onClosed();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-        verifyRetransmissionStopped();
-    }
-
-    @Test
-    public void testRekeyIkeLocalDeleteHandlesRespWithParsingError() throws Exception {
-        setupIdleStateMachine();
-        mockCreateAndTransitionToRekeyDeleteLocal();
-        resetMockIkeMessageHelper();
-
-        // Mock receiving packet with syntax error
-        ReceivedIkePacket mockInvalidPacket =
-                makeDummyReceivedIkePacketWithInvalidSyntax(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_INFORMATIONAL);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket);
-        mLooper.dispatchAll();
-
-        // Verify no more request out
-        verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord);
-
-        // Verify final state - Idle, with new SA, and old SA closed.
-        verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-        verifyRetransmissionStopped();
-    }
-
-    @Test
-    public void testRekeyIkeLocalDeleteWithRequestOnNewSa() throws Exception {
-        setupIdleStateMachine();
-        mockCreateAndTransitionToRekeyDeleteLocal();
-
-        // Receive an empty (DPD) request on the new IKE SA
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDpdIkeRequest(mSpyLocalInitIkeSaRecord));
-        mLooper.dispatchAll();
-
-        // Verify final state - Idle, with new SA, and old SA closed.
-        verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-        verifyRetransmissionStopped();
-    }
-
-    @Test
-    public void testRekeyIkeLocalDeleteWithRequestFragOnNewSa() throws Exception {
-        setupIdleStateMachine();
-        mockCreateAndTransitionToRekeyDeleteLocal();
-
-        // Received IKE fragment
-        byte[] unencryptedData = "testRekeyIkeLocalDeleteWithRequestFragOnNewSa".getBytes();
-        int fragNum = 1;
-        int totalFragments = 2;
-        IkeSkfPayload skfPayload =
-                IkeTestUtils.makeDummySkfPayload(unencryptedData, fragNum, totalFragments);
-
-        ReceivedIkePacket packet =
-                makeDummyReceivedIkeFragmentPacket(
-                        mSpyLocalInitIkeSaRecord,
-                        false /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                        skfPayload,
-                        PAYLOAD_TYPE_SA,
-                        null /* collectedFrags*/);
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, packet);
-        mLooper.dispatchAll();
-
-        // Verify rekey is done.
-        verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord);
-        verifyRetransmissionStopped();
-
-        // Verify the IkeSaRecord has stored the new fragment.
-        DecodeResultPartial resultPartial =
-                mSpyLocalInitIkeSaRecord.getCollectedFragments(false /*isResp*/);
-        assertEquals(PAYLOAD_TYPE_SA, resultPartial.firstPayloadType);
-        assertEquals(totalFragments, resultPartial.collectedFragsList.length);
-        assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[fragNum - 1]);
-        assertFalse(resultPartial.isAllFragmentsReceived());
-    }
-
-    @Test
-    public void testRekeyIkeRemoteDeleteWithRequestOnNewSa() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyIkeRemoteDelete
-        mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord;
-        mIkeSessionStateMachine.addIkeSaRecord(mSpyRemoteInitIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Receive an empty (DPD) request on the new IKE SA
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDpdIkeRequest(mSpyRemoteInitIkeSaRecord));
-        mLooper.dispatchAll();
-
-        // Verify final state - Idle, with new SA, and old SA closed.
-        verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testRekeyIkeRemoteCreate() throws Exception {
-        setupIdleStateMachine();
-
-        setupRekeyedIkeSa(mSpyRemoteInitIkeSaRecord);
-
-        // Receive Rekey request
-        ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementRemoteReqMsgId();
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket);
-
-        // Verify SA created with correct parameters
-        ArgumentCaptor<SaRecord.IkeSaRecordConfig> recordConfigCaptor =
-                ArgumentCaptor.forClass(SaRecord.IkeSaRecordConfig.class);
-        verify(mMockSaRecordHelper)
-                .makeRekeyedIkeSaRecord(any(), any(), any(), any(), recordConfigCaptor.capture());
-        assertEquals(IKE_REKEY_SA_INITIATOR_SPI, recordConfigCaptor.getValue().initSpi.getSpi());
-
-        // Verify outbound CREATE_CHILD_SA message
-        IkeMessage rekeyCreateResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-        IkeHeader rekeyCreateRespHeader = rekeyCreateResp.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyCreateRespHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA, rekeyCreateRespHeader.exchangeType);
-        assertTrue(rekeyCreateRespHeader.isResponseMsg);
-        assertTrue(rekeyCreateRespHeader.fromIkeInitiator);
-        assertNotNull(
-                rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_SA, IkeSaPayload.class));
-        assertNotNull(
-                rekeyCreateResp.getPayloadForType(IkePayload.PAYLOAD_TYPE_KE, IkeKePayload.class));
-        assertNotNull(
-                rekeyCreateResp.getPayloadForType(
-                        IkePayload.PAYLOAD_TYPE_NONCE, IkeNoncePayload.class));
-
-        // Verify SA, StateMachine state
-        assertEquals(mSpyCurrentIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordAwaitingRemoteDel);
-        assertEquals(mSpyRemoteInitIkeSaRecord, mIkeSessionStateMachine.mIkeSaRecordSurviving);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete);
-        verify(mSpyIkeSocket)
-                .registerIke(
-                        eq(mSpyRemoteInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine));
-    }
-
-    @Test
-    public void testRekeyIkeRemoteCreateHandlesInvalidReq() throws Exception {
-        setupIdleStateMachine();
-
-        // Receive Rekey request
-        ReceivedIkePacket request = makeRekeyIkeRequestWithUnacceptableProposal();
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request);
-        mLooper.dispatchAll();
-
-        verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN);
-    }
-
-    @Test
-    public void testRekeyIkeRemoteCreateSaCreationFailure() throws Exception {
-        // Throw error when building new IKE SA
-        throwExceptionWhenMakeRekeyIkeSa(
-                new GeneralSecurityException("testRekeyIkeRemoteCreateSaCreationFailure"));
-        setupIdleStateMachine();
-
-        // Receive Rekey request
-        ReceivedIkePacket request = makeRekeyIkeRequest();
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request);
-        mLooper.dispatchAll();
-
-        verifyProcessRekeyReqFailure(ERROR_TYPE_NO_PROPOSAL_CHOSEN);
-    }
-
-    private void verifyProcessRekeyReqFailure(int expectedErrorCode) {
-        // Verify IKE Session is back to Idle
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        // Verify error notification was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, payloads.size());
-        IkeNotifyPayload notify = (IkeNotifyPayload) payloads.get(0);
-        assertEquals(expectedErrorCode, notify.notifyType);
-    }
-
-    @Test
-    public void testRekeyIkeRemoteDelete() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyIkeLocalDelete
-        mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord;
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Rekey Delete request
-        ReceivedIkePacket dummyDeleteIkeRequestReceivedPacket =
-                makeDeleteIkeRequest(mSpyCurrentIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRequestReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementRemoteReqMsgId();
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket);
-
-        // Verify outbound DELETE_IKE_SA message
-        IkeMessage rekeyDeleteResp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-        IkeHeader rekeyDeleteRespHeader = rekeyDeleteResp.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, rekeyDeleteRespHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, rekeyDeleteRespHeader.exchangeType);
-        assertTrue(rekeyDeleteRespHeader.isResponseMsg);
-        assertTrue(rekeyDeleteRespHeader.fromIkeInitiator);
-        assertTrue(rekeyDeleteResp.ikePayloadList.isEmpty());
-
-        // Verify final state - Idle, with new SA, and old SA closed.
-        verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord);
-
-        verify(mMockIkeSessionCallback, never()).onClosed();
-
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRequestReceivedPacket);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testRekeyIkeRemoteDeleteExitAndRenter() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyIkeLocalDelete
-        mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord;
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Trigger a timeout, and immediately re-enter remote-delete
-        mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1);
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.TIMEOUT_REKEY_REMOTE_DELETE);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeRemoteDelete);
-        mLooper.dispatchAll();
-
-        // Shift time forward, and assert the previous timeout was NOT fired.
-        mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS / 2 + 1);
-        mLooper.dispatchAll();
-
-        // Verify no request received, or response sent.
-        verify(mMockIkeMessageHelper, never()).decode(anyInt(), anyObject(), anyObject());
-        verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord);
-
-        // Verify final state has not changed - signal was not sent.
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete);
-    }
-
-    @Test
-    public void testRekeyIkeRemoteDeleteTimedOut() throws Exception {
-        setupIdleStateMachine();
-
-        // Seed fake rekey data and force transition to RekeyIkeLocalDelete
-        mIkeSessionStateMachine.mRemoteInitNewIkeSaRecord = mSpyRemoteInitIkeSaRecord;
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeRemoteDelete);
-        mLooper.dispatchAll();
-
-        mLooper.moveTimeForward(IkeSessionStateMachine.REKEY_DELETE_TIMEOUT_MS);
-        mLooper.dispatchAll();
-
-        // Verify no request received, or response sent.
-        verify(mMockIkeMessageHelper, never()).decode(anyInt(), anyObject(), anyObject());
-        verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord);
-
-        // Verify final state - Idle, with new SA, and old SA closed.
-        verifyRekeyReplaceSa(mSpyRemoteInitIkeSaRecord);
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testSimulRekey() throws Exception {
-        setupIdleStateMachine();
-
-        // Prepare "rekeyed" SA
-        setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord);
-        when(mSpyLocalInitIkeSaRecord.compareTo(mSpyRemoteInitIkeSaRecord)).thenReturn(1);
-
-        // Send Rekey request on mSpyCurrentIkeSaRecord
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-
-        // Receive Rekey request on mSpyCurrentIkeSaRecord
-        ReceivedIkePacket dummyRekeyIkeRequestReceivedPacket = makeRekeyIkeRequest();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRequestReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementRemoteReqMsgId();
-
-        // Receive Rekey response on mSpyCurrentIkeSaRecord
-        ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementLocaReqMsgId();
-        verify(mSpyIkeSocket)
-                .registerIke(
-                        eq(mSpyLocalInitIkeSaRecord.getLocalSpi()), eq(mIkeSessionStateMachine));
-
-        // Receive Delete response on mSpyCurrentIkeSaRecord
-        ReceivedIkePacket dummyDeleteIkeRespReceivedPacket =
-                makeDeleteIkeResponse(mSpyCurrentIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDeleteIkeRespReceivedPacket);
-        mLooper.dispatchAll();
-        verifyIncrementLocaReqMsgId();
-
-        // Verify
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRequestReceivedPacket);
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyRekeyIkeRespReceivedPacket);
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDeleteIkeRespReceivedPacket);
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        verifyRekeyReplaceSa(mSpyLocalInitIkeSaRecord);
-        verify(mMockIkeSessionCallback, never()).onClosed();
-    }
-
-    @Test
-    public void testOpenIkeSession() throws Exception {
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.Initial);
-
-        mIkeSessionStateMachine.openSession();
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeInit);
-    }
-
-    @Test
-    public void testIkeInitSchedulesRekey() throws Exception {
-        setupFirstIkeSa();
-
-        // Send IKE INIT request
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE);
-
-        // Receive IKE INIT response
-        ReceivedIkePacket dummyReceivedIkePacket = makeIkeInitResponse();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyReceivedIkePacket);
-
-        // Mock IKE AUTH and transition to Idle
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-        mIkeSessionStateMachine.mSaProposal = buildSaProposal();
-
-        // Move time forward to trigger rekey
-        mLooper.moveTimeForward(SA_SOFT_LIFETIME_MS);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-    }
-
-    @Test
-    public void testRekeyCreateIkeSchedulesRekey() throws Exception {
-        setupIdleStateMachine();
-
-        // Send Rekey-Create request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-
-        // Prepare "rekeyed" SA
-        setupRekeyedIkeSa(mSpyLocalInitIkeSaRecord);
-
-        // Receive Rekey response
-        ReceivedIkePacket dummyRekeyIkeRespReceivedPacket = makeRekeyIkeResponse();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyRekeyIkeRespReceivedPacket);
-        mLooper.dispatchAll();
-
-        // Mock rekey delete and transition to Idle
-        mIkeSessionStateMachine.mCurrentIkeSaRecord = mSpyLocalInitIkeSaRecord;
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-
-        // Move time forward to trigger rekey
-        mLooper.moveTimeForward(SA_SOFT_LIFETIME_MS);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-    }
-
-    @Test
-    public void testBuildEncryptedInformationalMessage() throws Exception {
-        IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_INVALID_SYNTAX, new byte[0]);
-
-        boolean isResp = false;
-        IkeMessage generated =
-                mIkeSessionStateMachine.buildEncryptedInformationalMessage(
-                        mSpyCurrentIkeSaRecord, new IkeInformationalPayload[] {payload}, isResp, 0);
-
-        assertEquals(mSpyCurrentIkeSaRecord.getInitiatorSpi(), generated.ikeHeader.ikeInitiatorSpi);
-        assertEquals(mSpyCurrentIkeSaRecord.getResponderSpi(), generated.ikeHeader.ikeResponderSpi);
-        assertEquals(
-                mSpyCurrentIkeSaRecord.getLocalRequestMessageId(), generated.ikeHeader.messageId);
-        assertEquals(isResp, generated.ikeHeader.isResponseMsg);
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, generated.ikeHeader.nextPayloadType);
-
-        List<IkeNotifyPayload> generatedPayloads =
-                generated.getPayloadListForType(
-                        IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-        assertEquals(1, generatedPayloads.size());
-
-        IkeNotifyPayload generatedPayload = generatedPayloads.get(0);
-        assertArrayEquals(new byte[0], generatedPayload.notifyData);
-        assertEquals(ERROR_TYPE_INVALID_SYNTAX, generatedPayload.notifyType);
-    }
-
-    private void verifyLastSentRespAllPackets(byte[][] expectedPackets, IkeSaRecord saRecord) {
-        if (expectedPackets == null) {
-            assertNull(saRecord.getLastSentRespAllPackets());
-            return;
-        }
-
-        assertEquals(expectedPackets.length, saRecord.getLastSentRespAllPackets().size());
-        for (int i = 0; i < expectedPackets.length; i++) {
-            assertArrayEquals(expectedPackets[i], saRecord.getLastSentRespAllPackets().get(i));
-        }
-    }
-
-    @Test
-    public void testEncryptedRetransmitterImmediatelySendsRequest() throws Exception {
-        setupIdleStateMachine();
-        byte[][] dummyLastRespBytes =
-                new byte[][] {"testRetransmitterSendsRequestLastResp".getBytes()};
-        mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyLastRespBytes));
-
-        IkeMessage spyIkeReqMessage =
-                spy(
-                        new IkeMessage(
-                                new IkeHeader(
-                                        mSpyCurrentIkeSaRecord.getInitiatorSpi(),
-                                        mSpyCurrentIkeSaRecord.getResponderSpi(),
-                                        IkePayload.PAYLOAD_TYPE_SK,
-                                        EXCHANGE_TYPE_INFORMATIONAL,
-                                        false /*isResp*/,
-                                        mSpyCurrentIkeSaRecord.isLocalInit,
-                                        mSpyCurrentIkeSaRecord.getLocalRequestMessageId()),
-                                new LinkedList<>()));
-
-        // Use something unique as a sentinel value
-        byte[][] dummyReqBytesList =
-                new byte[][] {
-                    "testRetransmitterSendsReqFrag1".getBytes(),
-                    "testRetransmitterSendsReqFrag2".getBytes()
-                };
-
-        doReturn(dummyReqBytesList)
-                .when(spyIkeReqMessage)
-                .encryptAndEncode(any(), any(), eq(mSpyCurrentIkeSaRecord), anyBoolean(), anyInt());
-
-        IkeSessionStateMachine.EncryptedRetransmitter retransmitter =
-                mIkeSessionStateMachine.new EncryptedRetransmitter(spyIkeReqMessage);
-
-        // Verify message is sent out, and that request does not change cached retransmit-response
-        // mLastSentIkeResp.
-        verify(mSpyIkeSocket).sendIkePacket(eq(dummyReqBytesList[0]), eq(REMOTE_ADDRESS));
-        verify(mSpyIkeSocket).sendIkePacket(eq(dummyReqBytesList[1]), eq(REMOTE_ADDRESS));
-        verifyLastSentRespAllPackets(dummyLastRespBytes, mSpyCurrentIkeSaRecord);
-    }
-
-    // TODO: b/141275871 Test retransmisstions are fired for correct times within certain time.
-
-    @Test
-    public void testCacheLastRequestAndResponse() throws Exception {
-        setupIdleStateMachine();
-        mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(null /*reqPacket*/);
-        mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(null /*respPacketList*/);
-
-        byte[] dummyIkeReqFirstPacket = "testLastSentRequest".getBytes();
-        byte[][] dummyIkeResp =
-                new byte[][] {
-                    "testLastSentRespFrag1".getBytes(), "testLastSentRespFrag2".getBytes()
-                };
-
-        when(mMockIkeMessageHelper.encryptAndEncode(
-                        any(),
-                        any(),
-                        eq(mSpyCurrentIkeSaRecord),
-                        any(IkeMessage.class),
-                        anyBoolean(),
-                        anyInt()))
-                .thenReturn(dummyIkeResp);
-
-        // Receive a DPD request, expect to send dummyIkeResp
-        ReceivedIkePacket dummyDpdRequest =
-                makeDpdIkeRequest(
-                        mSpyCurrentIkeSaRecord.getRemoteRequestMessageId(), dummyIkeReqFirstPacket);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest);
-        mLooper.dispatchAll();
-
-        verify(mSpyIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS));
-        verify(mSpyIkeSocket).sendIkePacket(eq(dummyIkeResp[1]), eq(REMOTE_ADDRESS));
-
-        verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord);
-        assertTrue(mSpyCurrentIkeSaRecord.isRetransmittedRequest(dummyIkeReqFirstPacket));
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testReplyRetransmittedRequest() throws Exception {
-        setupIdleStateMachine();
-
-        // Mock last sent request and response
-        byte[] dummyIkeReqFirstPacket = "testRcvRetransmittedRequestReq".getBytes();
-        byte[][] dummyIkeResp = new byte[][] {"testRcvRetransmittedRequestResp".getBytes()};
-
-        mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket);
-        mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyIkeResp));
-        mSpyCurrentIkeSaRecord.incrementRemoteRequestMessageId();
-
-        // Build request with last validated message ID
-        ReceivedIkePacket request =
-                makeDpdIkeRequest(
-                        mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1,
-                        dummyIkeReqFirstPacket);
-
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request);
-
-        mLooper.dispatchAll();
-
-        verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord);
-        verify(mSpyIkeSocket).sendIkePacket(eq(dummyIkeResp[0]), eq(REMOTE_ADDRESS));
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testDiscardFakeRetransmittedRequest() throws Exception {
-        setupIdleStateMachine();
-
-        // Mock last sent request and response
-        byte[] dummyIkeReqFirstPacket = "testDiscardFakeRetransmittedRequestReq".getBytes();
-        byte[][] dummyIkeResp = new byte[][] {"testDiscardFakeRetransmittedRequestResp".getBytes()};
-        mSpyCurrentIkeSaRecord.updateLastReceivedReqFirstPacket(dummyIkeReqFirstPacket);
-        mSpyCurrentIkeSaRecord.updateLastSentRespAllPackets(Arrays.asList(dummyIkeResp));
-        mSpyCurrentIkeSaRecord.incrementRemoteRequestMessageId();
-
-        // Build request with last validated message ID but different bytes
-        ReceivedIkePacket request =
-                makeDpdIkeRequest(
-                        mSpyCurrentIkeSaRecord.getRemoteRequestMessageId() - 1, new byte[0]);
-
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request);
-
-        mLooper.dispatchAll();
-
-        verifyLastSentRespAllPackets(dummyIkeResp, mSpyCurrentIkeSaRecord);
-        verify(mSpyIkeSocket, never()).sendIkePacket(any(), any());
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-
-    @Test
-    public void testDiscardRetransmittedResponse() throws Exception {
-        mockIkeInitAndTransitionToIkeAuth(mIkeSessionStateMachine.mCreateIkeLocalIkeAuth);
-        verifyRetransmissionStarted();
-
-        // Build and send fake response with last validated message ID to IKE state machine
-        ReceivedIkePacket resp =
-                makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                        mSpyCurrentIkeSaRecord,
-                        IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT,
-                        true /*isResp*/,
-                        mSpyCurrentIkeSaRecord.getLocalRequestMessageId() - 1,
-                        new LinkedList<>(),
-                        new byte[0]);
-
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp);
-        mLooper.dispatchAll();
-
-        // Verify current state does not change
-        verifyRetransmissionStarted();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.CreateIkeLocalIkeAuth);
-    }
-
-    @Test
-    public void testDeleteIkeLocalDeleteRequest() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Verify outbound message
-        IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = delMsg.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertFalse(ikeHeader.isResponseMsg);
-        assertTrue(ikeHeader.fromIkeInitiator);
-
-        List<IkeDeletePayload> deletePayloadList =
-                delMsg.getPayloadListForType(
-                        IkePayload.PAYLOAD_TYPE_DELETE, IkeDeletePayload.class);
-        assertEquals(1, deletePayloadList.size());
-
-        IkeDeletePayload deletePayload = deletePayloadList.get(0);
-        assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId);
-        assertEquals(0, deletePayload.numSpi);
-        assertEquals(0, deletePayload.spiSize);
-        assertArrayEquals(new int[0], deletePayload.spisToDelete);
-    }
-
-    @Test
-    public void testDeleteIkeLocalDeleteResponse() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        ReceivedIkePacket received = makeDeleteIkeResponse(mSpyCurrentIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received);
-        mLooper.dispatchAll();
-        verifyIncrementLocaReqMsgId();
-
-        verifyNotifyUserCloseSession();
-
-        // Verify state machine quit properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testDeleteIkeLocalDeleteResponseWithParsingError() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-        resetMockIkeMessageHelper();
-
-        // Mock receiving response with syntax error
-        ReceivedIkePacket mockInvalidPacket =
-                makeDummyReceivedIkePacketWithInvalidSyntax(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_INFORMATIONAL);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket);
-        mLooper.dispatchAll();
-
-        // Verify no more request out
-        verifyEncryptAndEncodeNeverCalled(mSpyCurrentIkeSaRecord);
-
-        // Verify state machine quit properly
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testDeleteIkeLocalDeleteHandlesInvalidResp() throws Exception {
-        setupIdleStateMachine();
-
-        // Send delete request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
-        mLooper.dispatchAll();
-
-        // Receive response with wrong exchange type
-        ReceivedIkePacket resp =
-                makeDummyReceivedIkePacketWithInvalidSyntax(
-                        mSpyCurrentIkeSaRecord,
-                        true /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, resp);
-        mLooper.dispatchAll();
-
-        // Verify state machine quit properly
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testDeleteIkeLocalDeleteReceivedNonDeleteRequest() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_DELETE_IKE));
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Verify delete sent out.
-        verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        resetMockIkeMessageHelper(); // Discard value.
-
-        ReceivedIkePacket received = makeRekeyIkeRequest();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, received);
-
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-        verifyIncrementRemoteReqMsgId();
-
-        // Verify outbound response
-        IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = resp.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertTrue(ikeHeader.isResponseMsg);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-
-        List<IkeNotifyPayload> notificationPayloadList =
-                resp.getPayloadListForType(IkePayload.PAYLOAD_TYPE_NOTIFY, IkeNotifyPayload.class);
-        assertEquals(1, notificationPayloadList.size());
-
-        IkeNotifyPayload notifyPayload = notificationPayloadList.get(0);
-        assertEquals(IkeProtocolException.ERROR_TYPE_TEMPORARY_FAILURE, notifyPayload.notifyType);
-    }
-
-    @Test
-    public void testDeleteIkeRemoteDelete() throws Exception {
-        setupIdleStateMachine();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET,
-                makeDeleteIkeRequest(mSpyCurrentIkeSaRecord));
-
-        mLooper.dispatchAll();
-        verifyIncrementRemoteReqMsgId();
-
-        // Verify outbound message
-        IkeMessage delMsg = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-
-        IkeHeader ikeHeader = delMsg.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertTrue(ikeHeader.isResponseMsg);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-
-        assertTrue(delMsg.ikePayloadList.isEmpty());
-
-        verifyNotifyUserCloseSession();
-
-        // Verify state machine quit properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    @Test
-    public void testReceiveDpd() throws Exception {
-        setupIdleStateMachine();
-
-        // Receive a DPD request, expect to stay in IDLE state
-        ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest);
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest);
-
-        // Verify outbound response
-        IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-        IkeHeader ikeHeader = resp.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertTrue(ikeHeader.isResponseMsg);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-        assertTrue(resp.ikePayloadList.isEmpty());
-    }
-
-    @Test
-    public void testReceiveDpdNonIdle() throws Exception {
-        setupIdleStateMachine();
-
-        // Move to a non-idle state. Use RekeyIkeRemoteDelete, as it doesn't send out any requests.
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mRekeyIkeRemoteDelete);
-        mLooper.dispatchAll();
-
-        // In a rekey state, receiving (and handling) a DPD should not result in a change of states
-        ReceivedIkePacket dummyDpdRequest = makeDpdIkeRequest(mSpyCurrentIkeSaRecord);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, dummyDpdRequest);
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeRemoteDelete);
-
-        verifyDecodeEncryptedMessage(mSpyCurrentIkeSaRecord, dummyDpdRequest);
-
-        // Verify outbound response
-        IkeMessage resp = verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-        IkeHeader ikeHeader = resp.ikeHeader;
-        assertEquals(IkePayload.PAYLOAD_TYPE_SK, ikeHeader.nextPayloadType);
-        assertEquals(IkeHeader.EXCHANGE_TYPE_INFORMATIONAL, ikeHeader.exchangeType);
-        assertTrue(ikeHeader.isResponseMsg);
-        assertEquals(mSpyCurrentIkeSaRecord.isLocalInit, ikeHeader.fromIkeInitiator);
-        assertTrue(resp.ikePayloadList.isEmpty());
-    }
-
-    @Test
-    public void testIdleTriggersNewRequests() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-
-        // Verify that the command is executed, and the state machine transitions to the right state
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-        verifyRetransmissionStarted();
-    }
-
-    @Test
-    public void testNonIdleStateDoesNotTriggerNewRequests() throws Exception {
-        setupIdleStateMachine();
-
-        // Force ourselves into a non-idle state
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mReceiving);
-        mLooper.dispatchAll();
-        verifyEncryptAndEncodeNeverCalled();
-
-        // Queue a local request, and expect that it is not run (yet)
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE,
-                new LocalRequest(IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_IKE));
-        mLooper.dispatchAll();
-
-        // Verify that the state machine is still in the Receiving state
-        verifyEncryptAndEncodeNeverCalled();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.Receiving);
-
-        // Go back to Idle, and expect to immediately transition to RekeyIkeLocalCreate from the
-        // queued request
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.RekeyIkeLocalCreate);
-        verifyEncryptAndEncodeAndGetMessage(mSpyCurrentIkeSaRecord);
-    }
-
-    @Test
-    public void testOpenChildSessionValidatesArgs() throws Exception {
-        setupIdleStateMachine();
-
-        // Expect failure - no callbacks provided
-        try {
-            mIkeSessionStateMachine.openChildSession(mChildSessionOptions, null);
-        } catch (IllegalArgumentException expected) {
-        }
-
-        // Expect failure - callbacks already registered
-        try {
-            mIkeSessionStateMachine.openChildSession(
-                    mChildSessionOptions, mMockChildSessionCallback);
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testOpenChildSession() throws Exception {
-        setupIdleStateMachine();
-
-        ChildSessionCallback cb = mock(ChildSessionCallback.class);
-        mIkeSessionStateMachine.openChildSession(mChildSessionOptions, cb);
-
-        // Test that inserting the same cb returns an error, even before the state
-        // machine has a chance to process it.
-        try {
-            mIkeSessionStateMachine.openChildSession(mChildSessionOptions, cb);
-        } catch (IllegalArgumentException expected) {
-        }
-
-        verify(mMockChildSessionFactoryHelper)
-                .makeChildSessionStateMachine(
-                        eq(mLooper.getLooper()),
-                        eq(mContext),
-                        eq(mChildSessionOptions),
-                        eq(mSpyUserCbExecutor),
-                        eq(cb),
-                        any());
-
-        // Verify state in IkeSessionStateMachine
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-
-        synchronized (mIkeSessionStateMachine.mChildCbToSessions) {
-            assertTrue(mIkeSessionStateMachine.mChildCbToSessions.containsKey(cb));
-        }
-    }
-
-    @Test
-    public void testCloseChildSessionValidatesArgs() throws Exception {
-        setupIdleStateMachine();
-
-        // Expect failure - callbacks not registered
-        try {
-            mIkeSessionStateMachine.closeChildSession(mock(ChildSessionCallback.class));
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testCloseChildSession() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-    }
-
-    @Test
-    public void testCloseImmediatelyAfterOpenChildSession() throws Exception {
-        setupIdleStateMachine();
-
-        ChildSessionCallback cb = mock(ChildSessionCallback.class);
-        mIkeSessionStateMachine.openChildSession(mChildSessionOptions, cb);
-
-        // Verify that closing the session immediately still picks up the child callback
-        // even before the looper has a chance to run.
-        mIkeSessionStateMachine.closeChildSession(mMockChildSessionCallback);
-    }
-
-    @Test
-    public void testOnChildSessionClosed() throws Exception {
-        setupIdleStateMachine();
-
-        mDummyChildSmCallback.onChildSessionClosed(mMockChildSessionCallback);
-
-        synchronized (mIkeSessionStateMachine.mChildCbToSessions) {
-            assertFalse(
-                    mIkeSessionStateMachine.mChildCbToSessions.containsKey(
-                            mMockChildSessionCallback));
-        }
-    }
-
-    @Test
-    public void testHandleUnexpectedExceptionInEnterState() throws Exception {
-        Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG);
-        IkeManager.setIkeLog(spyIkeLog);
-
-        IkeSessionOptions mockSessionOptions = mock(IkeSessionOptions.class);
-        when(mockSessionOptions.getSaProposals()).thenThrow(mock(RuntimeException.class));
-
-        IkeSessionStateMachine ikeSession =
-                new IkeSessionStateMachine(
-                        mLooper.getLooper(),
-                        mContext,
-                        mIpSecManager,
-                        mockSessionOptions,
-                        mChildSessionOptions,
-                        mSpyUserCbExecutor,
-                        mMockIkeSessionCallback,
-                        mMockChildSessionCallback,
-                        mMockEapAuthenticatorFactory);
-        // Send IKE INIT request
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE);
-        mLooper.dispatchAll();
-
-        assertNull(ikeSession.getCurrentState());
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class));
-        verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class));
-    }
-
-    @Test
-    public void testHandleUnexpectedExceptionInProcessStateMsg() throws Exception {
-        Log spyIkeLog = TestUtils.makeSpyLogDoLogErrorForWtf(TAG);
-        IkeManager.setIkeLog(spyIkeLog);
-
-        setupIdleStateMachine();
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, null /*receivedIkePacket*/);
-        mLooper.dispatchAll();
-
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mSpyUserCbExecutor).execute(any(Runnable.class));
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class));
-        verify(spyIkeLog).wtf(anyString(), anyString(), any(RuntimeException.class));
-    }
-
-    @Test
-    public void testCreateIkeLocalIkeInitRcvErrorNotify() throws Exception {
-        // Send IKE INIT request
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_LOCAL_REQUEST_CREATE_IKE);
-        mLooper.dispatchAll();
-        verifyRetransmissionStarted();
-
-        // Receive IKE INIT response with erro notification.
-        List<IkePayload> payloads = new LinkedList<>();
-        payloads.add(new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_NO_PROPOSAL_CHOSEN));
-        ReceivedIkePacket resp =
-                makeDummyUnencryptedReceivedIkePacket(
-                        1L /*initiator SPI*/,
-                        2L /*respodner SPI*/,
-                        IkeHeader.EXCHANGE_TYPE_IKE_SA_INIT,
-                        true /*isResp*/,
-                        false /*fromIkeInit*/,
-                        payloads);
-
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp);
-        mLooper.dispatchAll();
-
-        // Fires user error callbacks
-        verify(mMockIkeSessionCallback)
-                .onClosedExceptionally(
-                        argThat(err -> err instanceof NoValidProposalChosenException));
-        // Verify state machine quit properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-    }
-
-    private void mockSendRekeyChildReq() throws Exception {
-        setupIdleStateMachine();
-
-        ChildLocalRequest childLocalRequest =
-                new ChildLocalRequest(
-                        IkeSessionStateMachine.CMD_LOCAL_REQUEST_REKEY_CHILD,
-                        mMockChildSessionCallback,
-                        null /*childOptions*/);
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_EXECUTE_LOCAL_REQ, childLocalRequest);
-        mLooper.dispatchAll();
-
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verify(mMockChildSessionStateMachine).rekeyChildSession();
-
-        // Mocking sending request
-        mDummyChildSmCallback.onOutboundPayloadsReady(
-                IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA,
-                false /*isResp*/,
-                new LinkedList<>(),
-                mMockChildSessionStateMachine);
-        mLooper.dispatchAll();
-    }
-
-    private void mockRcvTempFail() throws Exception {
-        ReceivedIkePacket resp =
-                makeResponseWithErrorNotify(new IkeNotifyPayload(ERROR_TYPE_TEMPORARY_FAILURE));
-
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-    }
-
-    @Test
-    public void testTempFailureHandlerScheduleRetry() throws Exception {
-        mockSendRekeyChildReq();
-
-        // Mock sending TEMPORARY_FAILURE response
-        mockRcvTempFail();
-
-        // Move time forward to trigger retry
-        mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS);
-        mLooper.dispatchAll();
-
-        // Verify that rekey is triggered again
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState()
-                        instanceof IkeSessionStateMachine.ChildProcedureOngoing);
-        verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession();
-    }
-
-    @Test
-    public void testTempFailureHandlerTimeout() throws Exception {
-        long currentTime = 0;
-        int retryCnt = 0;
-
-        mockSendRekeyChildReq();
-
-        while (currentTime + RETRY_INTERVAL_MS < TEMP_FAILURE_RETRY_TIMEOUT_MS) {
-            mockRcvTempFail();
-
-            mLooper.moveTimeForward(RETRY_INTERVAL_MS);
-            currentTime += RETRY_INTERVAL_MS;
-            mLooper.dispatchAll();
-
-            retryCnt++;
-            verify(mMockChildSessionStateMachine, times(1 + retryCnt)).rekeyChildSession();
-        }
-
-        mLooper.moveTimeForward(RETRY_INTERVAL_MS);
-        mLooper.dispatchAll();
-
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(IkeInternalException.class));
-    }
-
-    @Test
-    public void testTempFailureHandlerCancelTimer() throws Exception {
-        mockSendRekeyChildReq();
-
-        // Mock sending TEMPORARY_FAILURE response
-        mockRcvTempFail();
-
-        // Move time forward to trigger retry
-        mLooper.moveTimeForward(IkeSessionStateMachine.RETRY_INTERVAL_MS);
-        mLooper.dispatchAll();
-        verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession();
-
-        // Mock sending a valid response
-        ReceivedIkePacket resp =
-                makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                        mSpyCurrentIkeSaRecord,
-                        EXCHANGE_TYPE_CREATE_CHILD_SA,
-                        true /*isResp*/,
-                        new LinkedList<>());
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, resp);
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION, mIkeSessionStateMachine.mIdle);
-        mLooper.dispatchAll();
-
-        // Move time forward
-        mLooper.moveTimeForward(IkeSessionStateMachine.TEMP_FAILURE_RETRY_TIMEOUT_MS);
-        mLooper.dispatchAll();
-
-        // Validate IKE Session is not closed
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-        // Validate no more retry
-        verify(mMockChildSessionStateMachine, times(2)).rekeyChildSession();
-    }
-
-    @Test
-    public void testIdleReceiveRequestWithFatalError() throws Exception {
-        setupIdleStateMachine();
-
-        // Mock receiving packet with syntax error
-        ReceivedIkePacket mockInvalidPacket =
-                makeDummyReceivedIkePacketWithInvalidSyntax(
-                        mSpyCurrentIkeSaRecord,
-                        false /*isResp*/,
-                        IkeHeader.EXCHANGE_TYPE_CREATE_CHILD_SA);
-        mIkeSessionStateMachine.sendMessage(CMD_RECEIVE_IKE_PACKET, mockInvalidPacket);
-        mLooper.dispatchAll();
-
-        // Verify Delete request was sent
-        List<IkePayload> payloads = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, payloads.size());
-
-        IkePayload payload = payloads.get(0);
-        assertEquals(IkePayload.PAYLOAD_TYPE_NOTIFY, payload.payloadType);
-        assertEquals(ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) payload).notifyType);
-
-        // Verify IKE Session is closed properly
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-    }
-
-    @Test
-    public void testHandlesInvalidRequest() throws Exception {
-        setupIdleStateMachine();
-
-        mIkeSessionStateMachine.sendMessage(
-                IkeSessionStateMachine.CMD_FORCE_TRANSITION,
-                mIkeSessionStateMachine.mChildProcedureOngoing);
-
-        // Receive an IKE AUTH request
-        ReceivedIkePacket request =
-                makeDummyEncryptedReceivedIkePacketWithPayloadList(
-                        mSpyCurrentIkeSaRecord,
-                        IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                        false /*isResp*/,
-                        new LinkedList<IkePayload>());
-        mIkeSessionStateMachine.sendMessage(IkeSessionStateMachine.CMD_RECEIVE_IKE_PACKET, request);
-        mLooper.dispatchAll();
-
-        // Verify error notification was sent
-        List<IkePayload> ikePayloadList = verifyOutInfoMsgHeaderAndGetPayloads(true /*isResp*/);
-        assertEquals(1, ikePayloadList.size());
-        assertEquals(
-                ERROR_TYPE_INVALID_SYNTAX, ((IkeNotifyPayload) ikePayloadList.get(0)).notifyType);
-
-        // Verify IKE Session has quit
-        assertNull(mIkeSessionStateMachine.getCurrentState());
-        verify(mMockIkeSessionCallback).onClosedExceptionally(any(InvalidSyntaxException.class));
-    }
-
-    @Test
-    public void testIdleHandlesUnprotectedPacket() throws Exception {
-        setupIdleStateMachine();
-
-        ReceivedIkePacket req =
-                makeDummyReceivedIkePacketWithUnprotectedError(
-                        mSpyCurrentIkeSaRecord,
-                        false /*isResp*/,
-                        EXCHANGE_TYPE_INFORMATIONAL,
-                        mock(IkeException.class));
-
-        mLooper.dispatchAll();
-        assertTrue(
-                mIkeSessionStateMachine.getCurrentState() instanceof IkeSessionStateMachine.Idle);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/SaRecordTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/SaRecordTest.java
deleted file mode 100644
index 646b9d9..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/SaRecordTest.java
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.AdditionalMatchers.aryEq;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecManager.SecurityParameterIndex;
-import android.net.IpSecManager.UdpEncapsulationSocket;
-import android.net.IpSecTransform;
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.ChildLocalRequest;
-import com.android.internal.net.ipsec.ike.IkeLocalRequestScheduler.LocalRequest;
-import com.android.internal.net.ipsec.ike.IkeSessionStateMachine.IkeSecurityParameterIndex;
-import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecord;
-import com.android.internal.net.ipsec.ike.SaRecord.ChildSaRecordConfig;
-import com.android.internal.net.ipsec.ike.SaRecord.IIpSecTransformHelper;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecordConfig;
-import com.android.internal.net.ipsec.ike.SaRecord.IpSecTransformHelper;
-import com.android.internal.net.ipsec.ike.SaRecord.SaRecordHelper;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.testutils.MockIpSecTestUtils;
-import com.android.server.IpSecService;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.net.Inet4Address;
-
-@RunWith(JUnit4.class)
-public final class SaRecordTest {
-    private static final Inet4Address LOCAL_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private static final Inet4Address REMOTE_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-
-    private static final String PRF_KEY_HEX_STRING = "094787780EE466E2CB049FA327B43908BC57E485";
-    private static final String DATA_TO_SIGN_HEX_STRING = "010000000a50500d";
-    private static final String CALCULATED_MAC_HEX_STRING =
-            "D83B20CC6A0932B2A7CEF26E4020ABAAB64F0C6A";
-
-    private static final long IKE_INIT_SPI = 0x5F54BF6D8B48E6E1L;
-    private static final long IKE_RESP_SPI = 0x909232B3D1EDCB5CL;
-
-    private static final String IKE_NONCE_INIT_HEX_STRING =
-            "C39B7F368F4681B89FA9B7BE6465ABD7C5F68B6ED5D3B4C72CB4240EB5C46412";
-    private static final String IKE_NONCE_RESP_HEX_STRING =
-            "9756112CA539F5C25ABACC7EE92B73091942A9C06950F98848F1AF1694C4DDFF";
-
-    private static final String IKE_SHARED_DH_KEY_HEX_STRING =
-            "C14155DEA40056BD9C76FB4819687B7A397582F4CD5AFF4B"
-                    + "8F441C56E0C08C84234147A0BA249A555835A048E3CA2980"
-                    + "7D057A61DD26EEFAD9AF9C01497005E52858E29FB42EB849"
-                    + "6731DF96A11CCE1F51137A9A1B900FA81AEE7898E373D4E4"
-                    + "8B899BBECA091314ECD4B6E412EF4B0FEF798F54735F3180"
-                    + "7424A318287F20E8";
-
-    private static final String IKE_SKEYSEED_HEX_STRING =
-            "8C42F3B1F5F81C7BAAC5F33E9A4F01987B2F9657";
-    private static final String IKE_SK_D_HEX_STRING = "C86B56EFCF684DCC2877578AEF3137167FE0EBF6";
-    private static final String IKE_SK_AUTH_INIT_HEX_STRING =
-            "554FBF5A05B7F511E05A30CE23D874DB9EF55E51";
-    private static final String IKE_SK_AUTH_RESP_HEX_STRING =
-            "36D83420788337CA32ECAA46892C48808DCD58B1";
-    private static final String IKE_SK_ENCR_INIT_HEX_STRING = "5CBFD33F75796C0188C4A3A546AEC4A1";
-    private static final String IKE_SK_ENCR_RESP_HEX_STRING = "C33B35FCF29514CD9D8B4A695E1A816E";
-    private static final String IKE_SK_PRF_INIT_HEX_STRING =
-            "094787780EE466E2CB049FA327B43908BC57E485";
-    private static final String IKE_SK_PRF_RESP_HEX_STRING =
-            "A30E6B08BE56C0E6BFF4744143C75219299E1BEB";
-    private static final String IKE_KEY_MAT =
-            IKE_SK_D_HEX_STRING
-                    + IKE_SK_AUTH_INIT_HEX_STRING
-                    + IKE_SK_AUTH_RESP_HEX_STRING
-                    + IKE_SK_ENCR_INIT_HEX_STRING
-                    + IKE_SK_ENCR_RESP_HEX_STRING
-                    + IKE_SK_PRF_INIT_HEX_STRING
-                    + IKE_SK_PRF_RESP_HEX_STRING;
-
-    private static final int IKE_AUTH_ALGO_KEY_LEN = 20;
-    private static final int IKE_ENCR_ALGO_KEY_LEN = 16;
-    private static final int IKE_PRF_KEY_LEN = 20;
-    private static final int IKE_SK_D_KEY_LEN = IKE_PRF_KEY_LEN;
-
-    private static final int FIRST_CHILD_INIT_SPI = 0x2ad4c0a2;
-    private static final int FIRST_CHILD_RESP_SPI = 0xcae7019f;
-
-    private static final String FIRST_CHILD_ENCR_INIT_HEX_STRING =
-            "1B865CEA6E2C23973E8C5452ADC5CD7D";
-    private static final String FIRST_CHILD_ENCR_RESP_HEX_STRING =
-            "5E82FEDACC6DCB0756DDD7553907EBD1";
-    private static final String FIRST_CHILD_AUTH_INIT_HEX_STRING =
-            "A7A5A44F7EF4409657206C7DC52B7E692593B51E";
-    private static final String FIRST_CHILD_AUTH_RESP_HEX_STRING =
-            "CDE612189FD46DE870FAEC04F92B40B0BFDBD9E1";
-    private static final String FIRST_CHILD_KEY_MAT =
-            FIRST_CHILD_ENCR_INIT_HEX_STRING
-                    + FIRST_CHILD_AUTH_INIT_HEX_STRING
-                    + FIRST_CHILD_ENCR_RESP_HEX_STRING
-                    + FIRST_CHILD_AUTH_RESP_HEX_STRING;
-
-    private static final int FIRST_CHILD_AUTH_ALGO_KEY_LEN = 20;
-    private static final int FIRST_CHILD_ENCR_ALGO_KEY_LEN = 16;
-
-    private IkeMacPrf mIkeHmacSha1Prf;
-    private IkeMacIntegrity mHmacSha1IntegrityMac;
-    private IkeCipher mAesCbcCipher;
-
-    private LocalRequest mMockFutureRekeyIkeEvent;
-    private ChildLocalRequest mMockFutureRekeyChildEvent;
-
-    private SaRecordHelper mSaRecordHelper = new SaRecordHelper();
-
-    @Before
-    public void setUp() throws Exception {
-        mIkeHmacSha1Prf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-        mHmacSha1IntegrityMac =
-                IkeMacIntegrity.create(
-                        new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96),
-                        IkeMessage.getSecurityProvider());
-        mAesCbcCipher =
-                IkeCipher.create(
-                        new EncryptionTransform(
-                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
-                                SaProposal.KEY_LEN_AES_128),
-                        IkeMessage.getSecurityProvider());
-
-        mMockFutureRekeyIkeEvent = mock(LocalRequest.class);
-        mMockFutureRekeyChildEvent = mock(ChildLocalRequest.class);
-    }
-
-    // Test generating keying material for making IKE SA.
-    @Test
-    public void testMakeIkeSaRecord() throws Exception {
-        byte[] sKeySeed = TestUtils.hexStringToByteArray(IKE_SKEYSEED_HEX_STRING);
-        byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING);
-        byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING);
-
-        IkeSecurityParameterIndex ikeInitSpi =
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(
-                        LOCAL_ADDRESS, IKE_INIT_SPI);
-        IkeSecurityParameterIndex ikeRespSpi =
-                IkeSecurityParameterIndex.allocateSecurityParameterIndex(
-                        REMOTE_ADDRESS, IKE_RESP_SPI);
-        IkeSaRecordConfig ikeSaRecordConfig =
-                new IkeSaRecordConfig(
-                        ikeInitSpi,
-                        ikeRespSpi,
-                        mIkeHmacSha1Prf,
-                        IKE_AUTH_ALGO_KEY_LEN,
-                        IKE_ENCR_ALGO_KEY_LEN,
-                        true /*isLocalInit*/,
-                        mMockFutureRekeyIkeEvent);
-
-        int keyMaterialLen =
-                IKE_SK_D_KEY_LEN
-                        + IKE_AUTH_ALGO_KEY_LEN * 2
-                        + IKE_ENCR_ALGO_KEY_LEN * 2
-                        + IKE_PRF_KEY_LEN * 2;
-
-        IkeSaRecord ikeSaRecord =
-                mSaRecordHelper.makeIkeSaRecord(sKeySeed, nonceInit, nonceResp, ikeSaRecordConfig);
-
-        assertTrue(ikeSaRecord.isLocalInit);
-        assertEquals(IKE_INIT_SPI, ikeSaRecord.getInitiatorSpi());
-        assertEquals(IKE_RESP_SPI, ikeSaRecord.getResponderSpi());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING), ikeSaRecord.getSkD());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_AUTH_INIT_HEX_STRING),
-                ikeSaRecord.getOutboundIntegrityKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_AUTH_RESP_HEX_STRING),
-                ikeSaRecord.getInboundIntegrityKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_ENCR_INIT_HEX_STRING),
-                ikeSaRecord.getOutboundEncryptionKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_ENCR_RESP_HEX_STRING),
-                ikeSaRecord.getInboundDecryptionKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_PRF_INIT_HEX_STRING), ikeSaRecord.getSkPi());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(IKE_SK_PRF_RESP_HEX_STRING), ikeSaRecord.getSkPr());
-
-        ikeSaRecord.close();
-
-        verify(mMockFutureRekeyIkeEvent).cancel();
-    }
-
-    // Test generating keying material and building IpSecTransform for making Child SA.
-    @Test
-    public void testMakeChildSaRecord() throws Exception {
-        byte[] sharedKey = new byte[0];
-        byte[] nonceInit = TestUtils.hexStringToByteArray(IKE_NONCE_INIT_HEX_STRING);
-        byte[] nonceResp = TestUtils.hexStringToByteArray(IKE_NONCE_RESP_HEX_STRING);
-
-        MockIpSecTestUtils mockIpSecTestUtils = MockIpSecTestUtils.setUpMockIpSec();
-        IpSecManager ipSecManager = mockIpSecTestUtils.getIpSecManager();
-        IpSecService mockIpSecService = mockIpSecTestUtils.getIpSecService();
-        Context context = mockIpSecTestUtils.getContext();
-
-        when(mockIpSecService.allocateSecurityParameterIndex(
-                        eq(LOCAL_ADDRESS.getHostAddress()), anyInt(), anyObject()))
-                .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(FIRST_CHILD_INIT_SPI));
-        when(mockIpSecService.allocateSecurityParameterIndex(
-                        eq(REMOTE_ADDRESS.getHostAddress()), anyInt(), anyObject()))
-                .thenReturn(MockIpSecTestUtils.buildDummyIpSecSpiResponse(FIRST_CHILD_RESP_SPI));
-
-        SecurityParameterIndex childInitSpi =
-                ipSecManager.allocateSecurityParameterIndex(LOCAL_ADDRESS);
-        SecurityParameterIndex childRespSpi =
-                ipSecManager.allocateSecurityParameterIndex(REMOTE_ADDRESS);
-
-        byte[] initAuthKey = TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_INIT_HEX_STRING);
-        byte[] respAuthKey = TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_RESP_HEX_STRING);
-        byte[] initEncryptionKey = TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_INIT_HEX_STRING);
-        byte[] respEncryptionKey = TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_RESP_HEX_STRING);
-
-        IIpSecTransformHelper mockIpSecHelper;
-        mockIpSecHelper = mock(IIpSecTransformHelper.class);
-        SaRecord.setIpSecTransformHelper(mockIpSecHelper);
-
-        IpSecTransform mockInTransform = mock(IpSecTransform.class);
-        IpSecTransform mockOutTransform = mock(IpSecTransform.class);
-        UdpEncapsulationSocket mockUdpEncapSocket = mock(UdpEncapsulationSocket.class);
-
-        when(mockIpSecHelper.makeIpSecTransform(
-                        eq(context),
-                        eq(LOCAL_ADDRESS),
-                        eq(mockUdpEncapSocket),
-                        eq(childRespSpi),
-                        eq(mHmacSha1IntegrityMac),
-                        eq(mAesCbcCipher),
-                        aryEq(initAuthKey),
-                        aryEq(initEncryptionKey),
-                        eq(false)))
-                .thenReturn(mockOutTransform);
-
-        when(mockIpSecHelper.makeIpSecTransform(
-                        eq(context),
-                        eq(REMOTE_ADDRESS),
-                        eq(mockUdpEncapSocket),
-                        eq(childInitSpi),
-                        eq(mHmacSha1IntegrityMac),
-                        eq(mAesCbcCipher),
-                        aryEq(respAuthKey),
-                        aryEq(respEncryptionKey),
-                        eq(false)))
-                .thenReturn(mockInTransform);
-
-        ChildSaRecordConfig childSaRecordConfig =
-                new ChildSaRecordConfig(
-                        mockIpSecTestUtils.getContext(),
-                        childInitSpi,
-                        childRespSpi,
-                        LOCAL_ADDRESS,
-                        REMOTE_ADDRESS,
-                        mockUdpEncapSocket,
-                        mIkeHmacSha1Prf,
-                        mHmacSha1IntegrityMac,
-                        mAesCbcCipher,
-                        TestUtils.hexStringToByteArray(IKE_SK_D_HEX_STRING),
-                        false /*isTransport*/,
-                        true /*isLocalInit*/,
-                        mMockFutureRekeyChildEvent);
-
-        ChildSaRecord childSaRecord =
-                mSaRecordHelper.makeChildSaRecord(
-                        sharedKey, nonceInit, nonceResp, childSaRecordConfig);
-
-        assertTrue(childSaRecord.isLocalInit);
-        assertEquals(FIRST_CHILD_INIT_SPI, childSaRecord.getLocalSpi());
-        assertEquals(FIRST_CHILD_RESP_SPI, childSaRecord.getRemoteSpi());
-        assertEquals(mockInTransform, childSaRecord.getInboundIpSecTransform());
-        assertEquals(mockOutTransform, childSaRecord.getOutboundIpSecTransform());
-
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_INIT_HEX_STRING),
-                childSaRecord.getOutboundIntegrityKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(FIRST_CHILD_AUTH_RESP_HEX_STRING),
-                childSaRecord.getInboundIntegrityKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_INIT_HEX_STRING),
-                childSaRecord.getOutboundEncryptionKey());
-        assertArrayEquals(
-                TestUtils.hexStringToByteArray(FIRST_CHILD_ENCR_RESP_HEX_STRING),
-                childSaRecord.getInboundDecryptionKey());
-
-        childSaRecord.close();
-        verify(mMockFutureRekeyChildEvent).cancel();
-
-        SaRecord.setIpSecTransformHelper(new IpSecTransformHelper());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipherTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipherTest.java
deleted file mode 100644
index a3b2253..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeCombinedModeCipherTest.java
+++ /dev/null
@@ -1,160 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.Arrays;
-import java.util.Random;
-
-import javax.crypto.AEADBadTagException;
-
-@RunWith(JUnit4.class)
-public final class IkeCombinedModeCipherTest {
-    private static final String IV = "fbd69d9de2dafc5e";
-    private static final String ENCRYPTED_PADDED_DATA_WITH_CHECKSUM =
-            "f4109834e9f3559758c05edf119917521b885f67f0d14ced43";
-    private static final String UNENCRYPTED_PADDED_DATA = "000000080000400f00";
-    private static final String ADDITIONAL_AUTH_DATA =
-            "77c708b4523e39a471dc683c1d4f21362e202508000000060000004129000025";
-    private static final String KEY =
-            "7C04513660DEC572D896105254EF92608054F8E6EE19E79CE52AB8697B2B5F2C2AA90C29";
-
-    private static final int AES_GCM_IV_LEN = 8;
-    private static final int AES_GCM_16_CHECKSUM_LEN = 128;
-
-    private IkeCombinedModeCipher mAesGcm16Cipher;
-
-    private byte[] mAesGcmKey;
-    private byte[] mIv;
-    private byte[] mEncryptedPaddedDataWithChecksum;
-    private byte[] mUnencryptedPaddedData;
-    private byte[] mAdditionalAuthData;
-
-    @Before
-    public void setUp() {
-        mAesGcm16Cipher =
-                (IkeCombinedModeCipher)
-                        IkeCipher.create(
-                                new EncryptionTransform(
-                                        SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
-                                        SaProposal.KEY_LEN_AES_256),
-                                IkeMessage.getSecurityProvider());
-
-        mAesGcmKey = TestUtils.hexStringToByteArray(KEY);
-        mIv = TestUtils.hexStringToByteArray(IV);
-        mEncryptedPaddedDataWithChecksum =
-                TestUtils.hexStringToByteArray(ENCRYPTED_PADDED_DATA_WITH_CHECKSUM);
-        mUnencryptedPaddedData = TestUtils.hexStringToByteArray(UNENCRYPTED_PADDED_DATA);
-        mAdditionalAuthData = TestUtils.hexStringToByteArray(ADDITIONAL_AUTH_DATA);
-    }
-
-    @Test
-    public void testBuild() throws Exception {
-        assertTrue(mAesGcm16Cipher.isAead());
-        assertEquals(AES_GCM_IV_LEN, mAesGcm16Cipher.generateIv().length);
-    }
-
-    @Test
-    public void testGenerateRandomIv() throws Exception {
-        assertFalse(Arrays.equals(mAesGcm16Cipher.generateIv(), mAesGcm16Cipher.generateIv()));
-    }
-
-    @Test
-    public void testEncrypt() throws Exception {
-        byte[] calculatedData =
-                mAesGcm16Cipher.encrypt(
-                        mUnencryptedPaddedData, mAdditionalAuthData, mAesGcmKey, mIv);
-
-        assertArrayEquals(mEncryptedPaddedDataWithChecksum, calculatedData);
-    }
-
-    @Test
-    public void testDecrypt() throws Exception {
-        byte[] calculatedData =
-                mAesGcm16Cipher.decrypt(
-                        mEncryptedPaddedDataWithChecksum, mAdditionalAuthData, mAesGcmKey, mIv);
-
-        assertArrayEquals(mUnencryptedPaddedData, calculatedData);
-    }
-
-    @Test
-    public void testEncryptWithWrongKeyLen() throws Exception {
-        byte[] encryptionKey = TestUtils.hexStringToByteArray(KEY + "00");
-
-        try {
-            mAesGcm16Cipher.encrypt(
-                    mUnencryptedPaddedData, mAdditionalAuthData, encryptionKey, mIv);
-            fail("Expected to fail because encryption key has wrong length.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecrypWithWrongKey() throws Exception {
-        byte[] encryptionKey = new byte[mAesGcmKey.length];
-        new Random().nextBytes(encryptionKey);
-
-        try {
-            mAesGcm16Cipher.decrypt(
-                    mEncryptedPaddedDataWithChecksum, mAdditionalAuthData, encryptionKey, mIv);
-            fail("Expected to fail because decryption key is wrong");
-        } catch (AEADBadTagException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIpSecAlgorithm() throws Exception {
-        IpSecAlgorithm ipsecAlgorithm = mAesGcm16Cipher.buildIpSecAlgorithmWithKey(mAesGcmKey);
-
-        IpSecAlgorithm expectedIpSecAlgorithm =
-                new IpSecAlgorithm(
-                        IpSecAlgorithm.AUTH_CRYPT_AES_GCM, mAesGcmKey, AES_GCM_16_CHECKSUM_LEN);
-
-        assertTrue(IpSecAlgorithm.equals(expectedIpSecAlgorithm, ipsecAlgorithm));
-    }
-
-    @Test
-    public void buildIpSecAlgorithmWithInvalidKey() throws Exception {
-        byte[] encryptionKey = TestUtils.hexStringToByteArray(KEY + "00");
-
-        try {
-            mAesGcm16Cipher.buildIpSecAlgorithmWithKey(encryptionKey);
-            fail("Expected to fail because encryption key has wrong length.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrityTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrityTest.java
deleted file mode 100644
index ed62566..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeMacIntegrityTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.Arrays;
-
-@RunWith(JUnit4.class)
-public final class IkeMacIntegrityTest {
-    private static final String DATA_TO_AUTH_HEX_STRING =
-            "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec"
-                    + "230000d0b9132b7bb9f658dfdc648e5017a6322a030c316c"
-                    + "e55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58"
-                    + "46de333ecd3ea2b705d18293b130395300ba92a351041345"
-                    + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f"
-                    + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60"
-                    + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b"
-                    + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423"
-                    + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3"
-                    + "59eb4e81";
-    private static final String INTEGRITY_KEY_HEX_STRING =
-            "554fbf5a05b7f511e05a30ce23d874db9ef55e51";
-    private static final String CHECKSUM_HEX_STRING = "ae6e0f22abdad69ba8007d50";
-
-    private IkeMacIntegrity mHmacSha1IntegrityMac;
-    private byte[] mHmacSha1IntegrityKey;
-
-    private byte[] mDataToAuthenticate;
-
-    @Before
-    public void setUp() throws Exception {
-        mHmacSha1IntegrityMac =
-                IkeMacIntegrity.create(
-                        new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96),
-                        IkeMessage.getSecurityProvider());
-        mHmacSha1IntegrityKey = TestUtils.hexStringToByteArray(INTEGRITY_KEY_HEX_STRING);
-
-        mDataToAuthenticate = TestUtils.hexStringToByteArray(DATA_TO_AUTH_HEX_STRING);
-    }
-
-    @Test
-    public void testGenerateChecksum() throws Exception {
-        byte[] calculatedChecksum =
-                mHmacSha1IntegrityMac.generateChecksum(mHmacSha1IntegrityKey, mDataToAuthenticate);
-
-        byte[] expectedChecksum = TestUtils.hexStringToByteArray(CHECKSUM_HEX_STRING);
-        assertArrayEquals(expectedChecksum, calculatedChecksum);
-    }
-
-    @Test
-    public void testGenerateChecksumWithDifferentKey() throws Exception {
-        byte[] integrityKey = mHmacSha1IntegrityKey.clone();
-        integrityKey[0]++;
-
-        byte[] calculatedChecksum =
-                mHmacSha1IntegrityMac.generateChecksum(integrityKey, mDataToAuthenticate);
-
-        byte[] expectedChecksum = TestUtils.hexStringToByteArray(CHECKSUM_HEX_STRING);
-        assertFalse(Arrays.equals(expectedChecksum, calculatedChecksum));
-    }
-
-    @Test
-    public void testGenerateChecksumWithInvalidKey() throws Exception {
-        byte[] integrityKey = TestUtils.hexStringToByteArray(INTEGRITY_KEY_HEX_STRING + "0000");
-
-        try {
-            byte[] calculatedChecksum =
-                    mHmacSha1IntegrityMac.generateChecksum(integrityKey, mDataToAuthenticate);
-            fail("Expected to fail due to invalid authentication key.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIpSecAlgorithm() throws Exception {
-        IpSecAlgorithm ipsecAlgorithm =
-                mHmacSha1IntegrityMac.buildIpSecAlgorithmWithKey(mHmacSha1IntegrityKey);
-
-        IpSecAlgorithm expectedIpSecAlgorithm =
-                new IpSecAlgorithm(IpSecAlgorithm.AUTH_HMAC_SHA1, mHmacSha1IntegrityKey, 96);
-
-        assertTrue(IpSecAlgorithm.equals(expectedIpSecAlgorithm, ipsecAlgorithm));
-    }
-
-    @Test
-    public void buildIpSecAlgorithmWithInvalidKey() throws Exception {
-        byte[] encryptionKey = TestUtils.hexStringToByteArray(INTEGRITY_KEY_HEX_STRING + "00");
-
-        try {
-            mHmacSha1IntegrityMac.buildIpSecAlgorithmWithKey(encryptionKey);
-
-            fail("Expected to fail due to integrity key with wrong length.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipherTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipherTest.java
deleted file mode 100644
index 3f3a0e1..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/crypto/IkeNormalModeCipherTest.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.crypto;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.IpSecAlgorithm;
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.Arrays;
-
-import javax.crypto.IllegalBlockSizeException;
-
-@RunWith(JUnit4.class)
-public final class IkeNormalModeCipherTest {
-    private static final String IKE_AUTH_INIT_REQUEST_IV = "b9132b7bb9f658dfdc648e5017a6322a";
-    private static final String IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA =
-            "030c316ce55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58"
-                    + "46de333ecd3ea2b705d18293b130395300ba92a351041345"
-                    + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f"
-                    + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60"
-                    + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b"
-                    + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423"
-                    + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3"
-                    + "59eb4e81";
-    private static final String IKE_AUTH_INIT_REQUEST_UNENCRYPTED_PADDED_DATA =
-            "2400000c010000000a50500d2700000c010000000a505050"
-                    + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327"
-                    + "44dfb2c12c00002c00000028010304032ad4c0a20300000c"
-                    + "0100000c800e008003000008030000020000000805000000"
-                    + "2d00001801000000070000100000ffff00000000ffffffff"
-                    + "2900001801000000070000100000ffff00000000ffffffff"
-                    + "29000008000040000000000c000040010000000100000000"
-                    + "000000000000000b";
-
-    private static final String ENCR_KEY_FROM_INIT_TO_RESP = "5cbfd33f75796c0188c4a3a546aec4a1";
-
-    private static final int AES_BLOCK_SIZE = 16;
-
-    private IkeNormalModeCipher mAesCbcCipher;
-    private byte[] mAesCbcKey;
-
-    private byte[] mIv;
-    private byte[] mEncryptedPaddedData;
-    private byte[] mUnencryptedPaddedData;
-
-    @Before
-    public void setUp() throws Exception {
-        mAesCbcCipher =
-                (IkeNormalModeCipher)
-                        IkeCipher.create(
-                                new EncryptionTransform(
-                                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
-                                        SaProposal.KEY_LEN_AES_128),
-                                IkeMessage.getSecurityProvider());
-        mAesCbcKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP);
-
-        mIv = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_IV);
-        mEncryptedPaddedData =
-                TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA);
-        mUnencryptedPaddedData =
-                TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_UNENCRYPTED_PADDED_DATA);
-    }
-
-    @Test
-    public void testBuild() throws Exception {
-        assertFalse(mAesCbcCipher.isAead());
-        assertEquals(AES_BLOCK_SIZE, mAesCbcCipher.getBlockSize());
-        assertEquals(AES_BLOCK_SIZE, mAesCbcCipher.generateIv().length);
-    }
-
-    @Test
-    public void testGenerateRandomIv() throws Exception {
-        assertFalse(Arrays.equals(mAesCbcCipher.generateIv(), mAesCbcCipher.generateIv()));
-    }
-
-    @Test
-    public void testEncryptWithNormalCipher() throws Exception {
-        byte[] calculatedData = mAesCbcCipher.encrypt(mUnencryptedPaddedData, mAesCbcKey, mIv);
-
-        assertArrayEquals(mEncryptedPaddedData, calculatedData);
-    }
-
-    @Test
-    public void testDecryptWithNormalCipher() throws Exception {
-        byte[] calculatedData = mAesCbcCipher.decrypt(mEncryptedPaddedData, mAesCbcKey, mIv);
-        assertArrayEquals(mUnencryptedPaddedData, calculatedData);
-    }
-
-    @Test
-    public void testEncryptWithWrongKey() throws Exception {
-        byte[] encryptionKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP + "00");
-
-        try {
-            mAesCbcCipher.encrypt(mEncryptedPaddedData, encryptionKey, mIv);
-            fail("Expected to fail due to encryption key with wrong length.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecryptWithNormalCipherWithBadPad() throws Exception {
-        byte[] dataToDecrypt =
-                TestUtils.hexStringToByteArray(
-                        IKE_AUTH_INIT_REQUEST_UNENCRYPTED_PADDED_DATA + "00");
-        try {
-            mAesCbcCipher.decrypt(dataToDecrypt, mAesCbcKey, mIv);
-            fail("Expected to fail when try to decrypt data with bad padding");
-        } catch (IllegalBlockSizeException expected) {
-
-        }
-    }
-
-    @Test
-    public void testBuildIpSecAlgorithm() throws Exception {
-        IpSecAlgorithm ipsecAlgorithm = mAesCbcCipher.buildIpSecAlgorithmWithKey(mAesCbcKey);
-
-        IpSecAlgorithm expectedIpSecAlgorithm =
-                new IpSecAlgorithm(IpSecAlgorithm.CRYPT_AES_CBC, mAesCbcKey);
-
-        assertTrue(IpSecAlgorithm.equals(expectedIpSecAlgorithm, ipsecAlgorithm));
-    }
-
-    @Test
-    public void buildIpSecAlgorithmWithInvalidKey() throws Exception {
-        byte[] encryptionKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP + "00");
-
-        try {
-            mAesCbcCipher.buildIpSecAlgorithmWithKey(encryptionKey);
-
-            fail("Expected to fail due to encryption key with wrong length.");
-        } catch (IllegalArgumentException expected) {
-
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayloadTest.java
deleted file mode 100644
index 96921c3..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeAuthDigitalSignPayloadTest.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static com.android.internal.net.ipsec.ike.message.IkeAuthDigitalSignPayload.SIGNATURE_ALGO_RSA_SHA2_256;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacPrf;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.PrfTransform;
-import com.android.internal.net.ipsec.ike.testutils.CertUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.PrivateKey;
-import java.security.cert.X509Certificate;
-
-public final class IkeAuthDigitalSignPayloadTest {
-    // TODO: Build a RSA_SHA1 signature and add tests for it.
-
-    // RSA_SHA2_256
-    private static final String AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING =
-            "0e0000000f300d06092a864886f70d01010b05006f76af4150d653c5d4136b9f"
-                    + "69d905849bf075c563e6d14ccda42361ec3e7d12c72e2dece5711ea1d952f7b8"
-                    + "e12c5d982aa4efdaeac36a02b222aa96242cc424";
-    private static final String SIGNATURE =
-            "6f76af4150d653c5d4136b9f69d905849bf075c563e6d14ccda42361ec3e7d12"
-                    + "c72e2dece5711ea1d952f7b8e12c5d982aa4efdaeac36a02b222aa96242cc424";
-
-    private static final String IKE_INIT_RESP_HEX_STRING =
-            "02458497587b09d488d5b76480bce53d2120222000000000000001cc2200002c"
-                    + "00000028010100040300000801000003030000080300000203000008020000020"
-                    + "00000080400000e28000108000e000013d60e51c40922cb121e395bacbd627cdd"
-                    + "d3240baa4fcefd29f65f8dd37329d68d4fb4854f8b8f07cfb60900e276d99a396"
-                    + "1112ee866b5456cf588dc1092fd3bc19668fb8fa42872f51c0ee748bdb665dcbe"
-                    + "15ac454f6ed966149954dac5187638d1ab61869d97a4873c4733c48cbe3acc8a6"
-                    + "5cfea3ce83fd09fba174bf0ec56d73a0585859399e61c2c38e695841f8df8a511"
-                    + "aadd438f56634165ad9b88e858c1585f1bee646943b8a96f5397721079a127b87"
-                    + "fd286e8f869ae021ce82adf91fa360217ac32268b39b698bf06a4e89b8d0267af"
-                    + "1c5b979b6493adb10a0e14aa707309e914b8d377903e75cb13cffbfde9c26842f"
-                    + "b49a07a4497c9907d39515b290000244b8aed6297c09a5a0dda06c873f5573b34"
-                    + "886dd779e90c19beca3fc54ab3cae02900001c00004004d8e7cb9d1e689ae8c84"
-                    + "c5078355436f3347376ff2900001c0000400545bc3f2113770de91c769094f1bd"
-                    + "614534e765ea290000080000402e290000100000402f000100020003000400000"
-                    + "00800004014";
-    private static final String NONCE_INIT_HEX_STRING =
-            "a5dded450b5ffd2670f37954367fce28279a085c830a03358b10b0872c0578f9";
-    private static final String ID_RESP_PAYLOAD_BODY_HEX_STRING = "01000000c0a82b8a";
-    private static final String SKP_RESP_HEX_STRING = "8FE8EC3153EDE924C23D6630D3C992A494E2F256";
-
-    private static final byte[] IKE_INIT_RESP_REQUEST =
-            TestUtils.hexStringToByteArray(IKE_INIT_RESP_HEX_STRING);
-    private static final byte[] NONCE_INIT_RESP =
-            TestUtils.hexStringToByteArray(NONCE_INIT_HEX_STRING);
-    private static final byte[] ID_RESP_PAYLOAD_BODY =
-            TestUtils.hexStringToByteArray(ID_RESP_PAYLOAD_BODY_HEX_STRING);
-    private static final byte[] PRF_RESP_KEY = TestUtils.hexStringToByteArray(SKP_RESP_HEX_STRING);
-
-    private IkeMacPrf mIkeHmacSha1Prf;
-
-    @Before
-    public void setUp() throws Exception {
-        mIkeHmacSha1Prf =
-                IkeMacPrf.create(
-                        new PrfTransform(SaProposal.PSEUDORANDOM_FUNCTION_HMAC_SHA1),
-                        IkeMessage.getSecurityProvider());
-    }
-
-    @Test
-    public void testDecodeGenericDigitalSignPayload() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING);
-        IkeAuthPayload payload = IkeAuthPayload.getIkeAuthPayload(false, inputPacket);
-
-        assertTrue(payload instanceof IkeAuthDigitalSignPayload);
-        IkeAuthDigitalSignPayload dsPayload = (IkeAuthDigitalSignPayload) payload;
-        assertEquals(SIGNATURE_ALGO_RSA_SHA2_256, dsPayload.signatureAlgoAndHash);
-        assertArrayEquals(dsPayload.signature, TestUtils.hexStringToByteArray(SIGNATURE));
-    }
-
-    @Test
-    public void testVerifyInboundSignature() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING);
-        IkeAuthDigitalSignPayload payload =
-                (IkeAuthDigitalSignPayload) IkeAuthPayload.getIkeAuthPayload(false, inputPacket);
-
-        X509Certificate cert = CertUtils.createCertFromPemFile("end-cert-small.pem");
-
-        payload.verifyInboundSignature(
-                cert,
-                IKE_INIT_RESP_REQUEST,
-                NONCE_INIT_RESP,
-                ID_RESP_PAYLOAD_BODY,
-                mIkeHmacSha1Prf,
-                PRF_RESP_KEY);
-    }
-
-    @Test
-    public void testVerifyInboundSignatureFail() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(AUTH_PAYLOAD_BODY_GENERIC_DIGITAL_SIGN_HEX_STRING);
-        IkeAuthDigitalSignPayload payload =
-                (IkeAuthDigitalSignPayload) IkeAuthPayload.getIkeAuthPayload(false, inputPacket);
-
-        assertArrayEquals(payload.signature, TestUtils.hexStringToByteArray(SIGNATURE));
-        X509Certificate cert = CertUtils.createCertFromPemFile("end-cert-a.pem");
-
-        try {
-            payload.verifyInboundSignature(
-                    cert,
-                    IKE_INIT_RESP_REQUEST,
-                    NONCE_INIT_RESP,
-                    ID_RESP_PAYLOAD_BODY,
-                    mIkeHmacSha1Prf,
-                    PRF_RESP_KEY);
-            fail("Expected to fail due to wrong certificate.");
-        } catch (AuthenticationFailedException expected) {
-        }
-    }
-
-    @Test
-    public void testGenerateSignature() throws Exception {
-        PrivateKey key = CertUtils.createRsaPrivateKeyFromKeyFile("end-cert-key-a.key");
-
-        IkeAuthDigitalSignPayload authPayload =
-                new IkeAuthDigitalSignPayload(
-                        SIGNATURE_ALGO_RSA_SHA2_256,
-                        key,
-                        IKE_INIT_RESP_REQUEST,
-                        NONCE_INIT_RESP,
-                        ID_RESP_PAYLOAD_BODY,
-                        mIkeHmacSha1Prf,
-                        PRF_RESP_KEY);
-
-        assertEquals(SIGNATURE_ALGO_RSA_SHA2_256, authPayload.signatureAlgoAndHash);
-        assertArrayEquals(authPayload.signature, TestUtils.hexStringToByteArray(SIGNATURE));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayloadTest.java
deleted file mode 100644
index 2bb72e3..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeCertPayloadTest.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.testutils.CertUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.cert.TrustAnchor;
-import java.security.cert.X509Certificate;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-
-public final class IkeCertPayloadTest {
-    private X509Certificate mEndCertA;
-    private X509Certificate mEndCertB;
-    private X509Certificate mEndCertSmall;
-
-    private X509Certificate mIntermediateCertBOne;
-    private X509Certificate mIntermediateCertBTwo;
-
-    private TrustAnchor mTrustAnchorA;
-    private TrustAnchor mTrustAnchorB;
-    private TrustAnchor mTrustAnchorSmall;
-
-    @Before
-    public void setUp() throws Exception {
-        mEndCertA = CertUtils.createCertFromPemFile("end-cert-a.pem");
-        mTrustAnchorA =
-                new TrustAnchor(
-                        CertUtils.createCertFromPemFile("self-signed-ca-a.pem"),
-                        null /*nameConstraints*/);
-
-        mEndCertB = CertUtils.createCertFromPemFile("end-cert-b.pem");
-        mIntermediateCertBOne = CertUtils.createCertFromPemFile("intermediate-ca-b-one.pem");
-        mIntermediateCertBTwo = CertUtils.createCertFromPemFile("intermediate-ca-b-two.pem");
-        mTrustAnchorB =
-                new TrustAnchor(
-                        CertUtils.createCertFromPemFile("self-signed-ca-b.pem"),
-                        null /*nameConstraints*/);
-
-        mEndCertSmall = CertUtils.createCertFromPemFile("end-cert-small.pem");
-        mTrustAnchorSmall =
-                new TrustAnchor(
-                        CertUtils.createCertFromPemFile("self-signed-ca-small.pem"),
-                        null /*nameConstraints*/);
-    }
-
-    @Test
-    public void testValidateCertsNoIntermediateCerts() throws Exception {
-        List<X509Certificate> certList = new LinkedList<>();
-        certList.add(mEndCertA);
-
-        Set<TrustAnchor> trustAnchors = new HashSet<>();
-        trustAnchors.add(mTrustAnchorA);
-
-        IkeCertPayload.validateCertificates(mEndCertA, certList, null /*crlList*/, trustAnchors);
-    }
-
-    @Test
-    public void testValidateCertsWithIntermediateCerts() throws Exception {
-        List<X509Certificate> certList = new LinkedList<>();
-
-        certList.add(mEndCertB);
-        certList.add(mIntermediateCertBTwo);
-        certList.add(mIntermediateCertBOne);
-
-        Set<TrustAnchor> trustAnchors = new HashSet<>();
-        trustAnchors.add(mTrustAnchorB);
-
-        IkeCertPayload.validateCertificates(mEndCertB, certList, null /*crlList*/, trustAnchors);
-    }
-
-    @Test
-    public void testValidateCertsWithMultiTrustAnchors() throws Exception {
-        List<X509Certificate> certList = new LinkedList<>();
-        certList.add(mEndCertA);
-
-        Set<TrustAnchor> trustAnchors = new HashSet<>();
-        trustAnchors.add(mTrustAnchorA);
-        trustAnchors.add(mTrustAnchorB);
-
-        IkeCertPayload.validateCertificates(mEndCertA, certList, null /*crlList*/, trustAnchors);
-    }
-
-    @Test
-    public void testValidateCertsWithWrongTrustAnchor() throws Exception {
-        List<X509Certificate> certList = new LinkedList<>();
-        certList.add(mEndCertA);
-
-        Set<TrustAnchor> trustAnchors = new HashSet<>();
-        trustAnchors.add(mTrustAnchorB);
-
-        try {
-            IkeCertPayload.validateCertificates(
-                    mEndCertA, certList, null /*crlList*/, trustAnchors);
-            fail("Expected to fail due to absence of valid trust anchor.");
-        } catch (AuthenticationFailedException expected) {
-        }
-    }
-
-    @Test
-    public void testValidateCertsWithMissingIntermediateCerts() throws Exception {
-        List<X509Certificate> certList = new LinkedList<>();
-        certList.add(mEndCertB);
-        certList.add(mIntermediateCertBOne);
-
-        Set<TrustAnchor> trustAnchors = new HashSet<>();
-        trustAnchors.add(mTrustAnchorB);
-
-        try {
-            IkeCertPayload.validateCertificates(
-                    mEndCertA, certList, null /*crlList*/, trustAnchors);
-            fail("Expected to fail due to absence of intermediate certificate.");
-        } catch (AuthenticationFailedException expected) {
-        }
-    }
-
-    @Test
-    public void testValidateCertsWithSmallSizeKey() throws Exception {
-        List<X509Certificate> certList = new LinkedList<>();
-        certList.add(mEndCertSmall);
-
-        Set<TrustAnchor> trustAnchors = new HashSet<>();
-        trustAnchors.add(mTrustAnchorSmall);
-
-        try {
-            IkeCertPayload.validateCertificates(
-                    mEndCertSmall, certList, null /*crlList*/, trustAnchors);
-            fail("Expected to fail because certificates use small size key");
-        } catch (AuthenticationFailedException expected) {
-        }
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayloadTest.java
deleted file mode 100644
index 9fc3222..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeConfigPayloadTest.java
+++ /dev/null
@@ -1,631 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_ADDRESS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DHCP;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_DNS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_NETMASK;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP4_SUBNET;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_ADDRESS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_DNS;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_ATTR_INTERNAL_IP6_SUBNET;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_TYPE_REPLY;
-import static com.android.internal.net.ipsec.ike.message.IkeConfigPayload.CONFIG_TYPE_REQUEST;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_CP;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NOTIFY;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.net.LinkAddress;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttrIpv4AddressBase;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttrIpv6AddrRangeBase;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttribute;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dhcp;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Dns;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Netmask;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv4Subnet;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Address;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Dns;
-import com.android.internal.net.ipsec.ike.message.IkeConfigPayload.ConfigAttributeIpv6Subnet;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-import java.util.LinkedList;
-import java.util.List;
-
-public final class IkeConfigPayloadTest {
-    private static final String CONFIG_REQ_PAYLOAD_HEX =
-            "2900001801000000000100000008000000030000000a0000";
-    private static final String CONFIG_RESP_PAYLOAD_HEX =
-            "210000200200000000010004c000026400030004080808080003000408080404";
-    private static final String CONFIG_RESP_PAYLOAD_INVALID_ONE_HEX =
-            "210000200200000000010004c000026400020004fffffffe00020004fffffffe";
-    private static final String CONFIG_RESP_PAYLOAD_INVALID_TWO_HEX =
-            "210000100200000000020004fffffffe";
-
-    private static final byte[] CONFIG_REQ_PAYLOAD =
-            TestUtils.hexStringToByteArray(CONFIG_REQ_PAYLOAD_HEX);
-    private static final byte[] CONFIG_RESP_PAYLOAD =
-            TestUtils.hexStringToByteArray(CONFIG_RESP_PAYLOAD_HEX);
-
-    private static final Inet4Address IPV4_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-    private static final Inet4Address IPV4_NETMASK =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.240"));
-    private static final int IP4_PREFIX_LEN = 28;
-    private static final LinkAddress IPV4_LINK_ADDRESS =
-            new LinkAddress(IPV4_ADDRESS, IP4_PREFIX_LEN);
-
-    private static final byte[] IPV4_ADDRESS_ATTRIBUTE_WITH_VALUE =
-            TestUtils.hexStringToByteArray("00010004c0000264");
-    private static final byte[] IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("00010000");
-
-    private static final byte[] IPV4_NETMASK_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("00020000");
-
-    private static final Inet4Address IPV4_DNS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("8.8.8.8"));
-    private static final byte[] IPV4_DNS_ATTRIBUTE_VALUE =
-            TestUtils.hexStringToByteArray("08080808");
-    private static final byte[] IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("00030000");
-
-    private static final Inet4Address IPV4_DHCP =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200"));
-    private static final byte[] IPV4_DHCP_ATTRIBUTE_WITH_VALUE =
-            TestUtils.hexStringToByteArray("00060004c00002c8");
-    private static final byte[] IPV4_DHCP_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("00060000");
-
-    private static final byte[] IPV4_SUBNET_ATTRIBUTE_VALUE =
-            TestUtils.hexStringToByteArray("c0000264fffffff0");
-    private static final byte[] IPV4_SUBNET_ATTRIBUTE_WITH_VALUE =
-            TestUtils.hexStringToByteArray("000d0008c0000264fffffff0");
-    private static final byte[] IPV4_SUBNET_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("000d0000");
-
-    private static final Inet6Address IPV6_ADDRESS =
-            (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8::1"));
-    private static final int IP6_PREFIX_LEN = 64;
-    private static final LinkAddress IPV6_LINK_ADDRESS =
-            new LinkAddress(IPV6_ADDRESS, IP6_PREFIX_LEN);
-
-    private static final byte[] IPV6_ADDRESS_ATTRIBUTE_VALUE =
-            TestUtils.hexStringToByteArray("20010db800000000000000000000000140");
-    private static final byte[] IPV6_ADDRESS_ATTRIBUTE_WITH_VALUE =
-            TestUtils.hexStringToByteArray("0008001120010db800000000000000000000000140");
-    private static final byte[] IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("00080000");
-
-    private static final byte[] IPV6_SUBNET_ATTRIBUTE_VALUE = IPV6_ADDRESS_ATTRIBUTE_VALUE;
-    private static final byte[] IPV6_SUBNET_ATTRIBUTE_WITH_VALUE =
-            TestUtils.hexStringToByteArray("000f001120010db800000000000000000000000140");
-    private static final byte[] IPV6_SUBNET_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("000f0000");
-
-    private static final Inet6Address IPV6_DNS =
-            (Inet6Address) (InetAddressUtils.parseNumericAddress("2001:db8:100::1"));
-    private static final byte[] IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE =
-            TestUtils.hexStringToByteArray("000a0000");
-
-    private Inet4Address[] mNetMasks;
-    private int[] mIpv4PrefixLens;
-
-    @Before
-    public void setUp() throws Exception {
-        mNetMasks =
-                new Inet4Address[] {
-                    (Inet4Address) (InetAddressUtils.parseNumericAddress("0.0.0.0")),
-                    (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.255")),
-                    (Inet4Address) (InetAddressUtils.parseNumericAddress("255.255.255.240"))
-                };
-        mIpv4PrefixLens = new int[] {0, 32, 28};
-    }
-
-    private IkeConfigPayload verifyDecodeHeaderAndGetPayload(
-            IkePayload payload, int expectedConfigType) {
-        assertEquals(PAYLOAD_TYPE_CP, payload.payloadType);
-        assertFalse(payload.isCritical);
-        assertTrue(payload instanceof IkeConfigPayload);
-
-        IkeConfigPayload configPayload = (IkeConfigPayload) payload;
-        assertEquals(expectedConfigType, configPayload.configType);
-
-        return configPayload;
-    }
-
-    @Test
-    public void testDecodeConfigRequest() throws Exception {
-        IkePayload payload =
-                IkePayloadFactory.getIkePayload(
-                                PAYLOAD_TYPE_CP,
-                                false /*isResp*/,
-                                ByteBuffer.wrap(CONFIG_REQ_PAYLOAD))
-                        .first;
-
-        IkeConfigPayload configPayload =
-                verifyDecodeHeaderAndGetPayload(payload, CONFIG_TYPE_REQUEST);
-
-        List<ConfigAttribute> recognizedAttributeList = configPayload.recognizedAttributeList;
-        assertEquals(4, recognizedAttributeList.size());
-
-        ConfigAttribute att = recognizedAttributeList.get(0);
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, att.attributeType);
-        assertNull(((ConfigAttributeIpv4Address) att).address);
-
-        att = recognizedAttributeList.get(1);
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, att.attributeType);
-        assertNull(((ConfigAttributeIpv6Address) att).linkAddress);
-
-        att = recognizedAttributeList.get(2);
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, att.attributeType);
-        assertNull(((ConfigAttributeIpv4Dns) att).address);
-
-        att = recognizedAttributeList.get(3);
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_DNS, att.attributeType);
-        assertNull(((ConfigAttributeIpv6Dns) att).address);
-    }
-
-    @Test
-    public void testDecodeConfigResponse() throws Exception {
-        IkePayload payload =
-                IkePayloadFactory.getIkePayload(
-                                PAYLOAD_TYPE_CP,
-                                true /*isResp*/,
-                                ByteBuffer.wrap(CONFIG_RESP_PAYLOAD))
-                        .first;
-
-        IkeConfigPayload configPayload =
-                verifyDecodeHeaderAndGetPayload(payload, CONFIG_TYPE_REPLY);
-
-        List<ConfigAttribute> recognizedAttributeList = configPayload.recognizedAttributeList;
-        assertEquals(3, recognizedAttributeList.size());
-
-        ConfigAttribute att = recognizedAttributeList.get(0);
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, att.attributeType);
-        assertEquals(IPV4_ADDRESS, ((ConfigAttributeIpv4Address) att).address);
-
-        att = recognizedAttributeList.get(1);
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, att.attributeType);
-        assertEquals(IPV4_DNS, ((ConfigAttributeIpv4Dns) att).address);
-
-        att = recognizedAttributeList.get(2);
-        InetAddress expectedDns = InetAddress.getByName("8.8.4.4");
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, att.attributeType);
-        assertEquals(expectedDns, ((ConfigAttributeIpv4Dns) att).address);
-    }
-
-    @Test
-    public void testDecodeConfigRespWithTwoNetmask() throws Exception {
-        byte[] configPayloadBytes =
-                TestUtils.hexStringToByteArray(CONFIG_RESP_PAYLOAD_INVALID_ONE_HEX);
-        try {
-            IkePayloadFactory.getIkePayload(
-                    PAYLOAD_TYPE_CP, true /*isResp*/, ByteBuffer.wrap(configPayloadBytes));
-            fail("Expected to fail because more than on netmask found");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeConfigRespNetmaskFoundWithoutIpv4Addr() throws Exception {
-        byte[] configPayloadBytes =
-                TestUtils.hexStringToByteArray(CONFIG_RESP_PAYLOAD_INVALID_TWO_HEX);
-        try {
-            IkePayloadFactory.getIkePayload(
-                    PAYLOAD_TYPE_CP, true /*isResp*/, ByteBuffer.wrap(configPayloadBytes));
-            fail("Expected to fail because netmask is found without a IPv4 address");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    private ConfigAttribute makeMockAttribute(byte[] encodedAttribute) {
-        ConfigAttribute mockAttribute = mock(ConfigAttribute.class);
-
-        when(mockAttribute.getAttributeLen()).thenReturn(encodedAttribute.length);
-
-        doAnswer(
-                (invocation) -> {
-                    ByteBuffer buffer = (ByteBuffer) invocation.getArguments()[0];
-                    buffer.put(encodedAttribute);
-                    return null;
-                })
-                .when(mockAttribute)
-                .encodeAttributeToByteBuffer(any(ByteBuffer.class));
-
-        return mockAttribute;
-    }
-
-    @Test
-    public void testBuildAndEncodeOutboundConfig() throws Exception {
-        List<ConfigAttribute> mockAttributeList = new LinkedList<>();
-        mockAttributeList.add(makeMockAttribute(IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE));
-        mockAttributeList.add(makeMockAttribute(IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE));
-        mockAttributeList.add(makeMockAttribute(IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE));
-        mockAttributeList.add(makeMockAttribute(IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE));
-        IkeConfigPayload configPayload = new IkeConfigPayload(false /*isReply*/, mockAttributeList);
-
-        assertEquals(PAYLOAD_TYPE_CP, configPayload.payloadType);
-        assertFalse(configPayload.isCritical);
-        assertEquals(CONFIG_TYPE_REQUEST, configPayload.configType);
-        assertEquals(mockAttributeList, configPayload.recognizedAttributeList);
-
-        ByteBuffer buffer = ByteBuffer.allocate(configPayload.getPayloadLength());
-        configPayload.encodeToByteBuffer(PAYLOAD_TYPE_NOTIFY, buffer);
-        assertArrayEquals(CONFIG_REQ_PAYLOAD, buffer.array());
-    }
-
-    private void verifyBuildAndEncodeAttributeCommon(
-            ConfigAttribute attribute, int expectedAttributeType, byte[] expectedEncodedAttribute) {
-        assertEquals(expectedAttributeType, attribute.attributeType);
-
-        ByteBuffer buffer = ByteBuffer.allocate(attribute.getAttributeLen());
-        attribute.encodeAttributeToByteBuffer(buffer);
-        assertArrayEquals(expectedEncodedAttribute, buffer.array());
-    }
-
-    private void verifyEncodeIpv4AddresBaseAttribute(
-            ConfigAttrIpv4AddressBase attribute,
-            int expectedAttributeType,
-            byte[] expectedEncodedAttribute,
-            Inet4Address expectedAddress) {
-        verifyBuildAndEncodeAttributeCommon(
-                attribute, expectedAttributeType, expectedEncodedAttribute);
-        assertEquals(expectedAddress, attribute.address);
-    }
-
-    private void verifyEncodeIpv6RangeBaseAttribute(
-            ConfigAttrIpv6AddrRangeBase attribute,
-            int expectedAttributeType,
-            byte[] expectedEncodedAttribute,
-            LinkAddress expectedLinkAddress) {
-        verifyBuildAndEncodeAttributeCommon(
-                attribute, expectedAttributeType, expectedEncodedAttribute);
-        assertEquals(expectedLinkAddress, attribute.linkAddress);
-    }
-
-    @Test
-    public void testDecodeIpv4AddressWithValue() throws Exception {
-        ConfigAttributeIpv4Address attributeIp4Address =
-                new ConfigAttributeIpv4Address(IPV4_ADDRESS.getAddress());
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType);
-        assertEquals(IPV4_ADDRESS, attributeIp4Address.address);
-    }
-
-    @Test
-    public void testDecodeIpv4AddressWithoutValue() throws Exception {
-        ConfigAttributeIpv4Address attributeIp4Address =
-                new ConfigAttributeIpv4Address(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_ADDRESS, attributeIp4Address.attributeType);
-        assertNull(attributeIp4Address.address);
-    }
-
-    @Test
-    public void testDecodeIpv4AddressWithInvalidValue() throws Exception {
-        byte[] invalidValue = new byte[] {1};
-
-        try {
-            ConfigAttributeIpv4Address attributeIp4Address =
-                    new ConfigAttributeIpv4Address(invalidValue);
-            fail("Expected to fail due to invalid attribute value");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeIpv4AddressWithValue() throws Exception {
-        ConfigAttributeIpv4Address attributeIp4Address =
-                new ConfigAttributeIpv4Address(IPV4_ADDRESS);
-
-        verifyEncodeIpv4AddresBaseAttribute(
-                attributeIp4Address,
-                CONFIG_ATTR_INTERNAL_IP4_ADDRESS,
-                IPV4_ADDRESS_ATTRIBUTE_WITH_VALUE,
-                IPV4_ADDRESS);
-    }
-
-    @Test
-    public void testEncodeIpv4AddressWithoutValue() throws Exception {
-        ConfigAttributeIpv4Address attributeIp4Address = new ConfigAttributeIpv4Address();
-
-        verifyEncodeIpv4AddresBaseAttribute(
-                attributeIp4Address,
-                CONFIG_ATTR_INTERNAL_IP4_ADDRESS,
-                IPV4_ADDRESS_ATTRIBUTE_WITHOUT_VALUE,
-                null /*expectedAddress*/);
-    }
-
-    @Test
-    public void testDecodeIpv4NetmaskWithValue() throws Exception {
-        ConfigAttributeIpv4Netmask attribute =
-                new ConfigAttributeIpv4Netmask(IPV4_NETMASK.getAddress());
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_NETMASK, attribute.attributeType);
-        assertEquals(IPV4_NETMASK, attribute.address);
-    }
-
-    @Test
-    public void testDecodeIpv4NetmaskWithoutValue() throws Exception {
-        ConfigAttributeIpv4Netmask attribute = new ConfigAttributeIpv4Netmask(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_NETMASK, attribute.attributeType);
-        assertNull(attribute.address);
-    }
-
-    @Test
-    public void testEncodeIpv4Netmask() throws Exception {
-        ConfigAttributeIpv4Netmask attribute = new ConfigAttributeIpv4Netmask();
-
-        verifyEncodeIpv4AddresBaseAttribute(
-                attribute,
-                CONFIG_ATTR_INTERNAL_IP4_NETMASK,
-                IPV4_NETMASK_ATTRIBUTE_WITHOUT_VALUE,
-                null /*expectedAddress*/);
-    }
-
-    @Test
-    public void testDecodeIpv4DnsWithValue() throws Exception {
-        ConfigAttributeIpv4Dns attribute = new ConfigAttributeIpv4Dns(IPV4_DNS.getAddress());
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, attribute.attributeType);
-        assertEquals(IPV4_DNS, attribute.address);
-    }
-
-    @Test
-    public void testDecodeIpv4DnsWithoutValue() throws Exception {
-        ConfigAttributeIpv4Dns attribute = new ConfigAttributeIpv4Dns(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DNS, attribute.attributeType);
-        assertNull(attribute.address);
-    }
-
-    @Test
-    public void testEncodeIpv4Dns() throws Exception {
-        ConfigAttributeIpv4Dns attribute = new ConfigAttributeIpv4Dns();
-
-        verifyEncodeIpv4AddresBaseAttribute(
-                attribute,
-                CONFIG_ATTR_INTERNAL_IP4_DNS,
-                IPV4_DNS_ATTRIBUTE_WITHOUT_VALUE,
-                null /*expectedAddress*/);
-    }
-
-    @Test
-    public void testDecodeIpv4DhcpWithValue() throws Exception {
-        ConfigAttributeIpv4Dhcp attribute = new ConfigAttributeIpv4Dhcp(IPV4_DHCP.getAddress());
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DHCP, attribute.attributeType);
-        assertEquals(IPV4_DHCP, attribute.address);
-    }
-
-    @Test
-    public void testDecodeIpv4DhcpWithoutValue() throws Exception {
-        ConfigAttributeIpv4Dhcp attribute = new ConfigAttributeIpv4Dhcp(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_DHCP, attribute.attributeType);
-        assertNull(attribute.address);
-    }
-
-    @Test
-    public void testEncodeIpv4DhcpWithValue() throws Exception {
-        ConfigAttributeIpv4Dhcp attributeIp4Dhcp = new ConfigAttributeIpv4Dhcp(IPV4_DHCP);
-
-        verifyEncodeIpv4AddresBaseAttribute(
-                attributeIp4Dhcp,
-                CONFIG_ATTR_INTERNAL_IP4_DHCP,
-                IPV4_DHCP_ATTRIBUTE_WITH_VALUE,
-                IPV4_DHCP);
-    }
-
-    @Test
-    public void testEncodeIpv4DhcpWithoutValue() throws Exception {
-        ConfigAttributeIpv4Dhcp attribute = new ConfigAttributeIpv4Dhcp();
-
-        verifyEncodeIpv4AddresBaseAttribute(
-                attribute,
-                CONFIG_ATTR_INTERNAL_IP4_DHCP,
-                IPV4_DHCP_ATTRIBUTE_WITHOUT_VALUE,
-                null /*expectedAddress*/);
-    }
-
-    @Test
-    public void testDecodeIpv4SubnetWithValue() throws Exception {
-        ConfigAttributeIpv4Subnet attributeIp4Subnet =
-                new ConfigAttributeIpv4Subnet(IPV4_SUBNET_ATTRIBUTE_VALUE);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_SUBNET, attributeIp4Subnet.attributeType);
-        assertEquals(IPV4_LINK_ADDRESS, attributeIp4Subnet.linkAddress);
-    }
-
-    @Test
-    public void testDecodeIpv4SubnetWithoutValue() throws Exception {
-        ConfigAttributeIpv4Subnet attributeIp4Subnet = new ConfigAttributeIpv4Subnet(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP4_SUBNET, attributeIp4Subnet.attributeType);
-        assertNull(attributeIp4Subnet.linkAddress);
-    }
-
-    @Test
-    public void testDecodeIpv4SubnetWithInvalidValue() throws Exception {
-        byte[] ipAddress = IPV4_ADDRESS.getAddress();
-        ByteBuffer buffer = ByteBuffer.allocate(ipAddress.length * 2);
-        buffer.put(ipAddress).put(ipAddress);
-
-        try {
-            new ConfigAttributeIpv4Subnet(buffer.array());
-            fail("Expected to fail due to invalid netmask.");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeIpv4SubnetWithoutValue() throws Exception {
-        ConfigAttributeIpv4Subnet attributeIp4Subnet = new ConfigAttributeIpv4Subnet();
-
-        verifyBuildAndEncodeAttributeCommon(
-                attributeIp4Subnet,
-                CONFIG_ATTR_INTERNAL_IP4_SUBNET,
-                IPV4_SUBNET_ATTRIBUTE_WITHOUT_VALUE);
-        assertNull(attributeIp4Subnet.linkAddress);
-    }
-
-    @Test
-    public void testNetmaskToPrefixLen() throws Exception {
-        for (int i = 0; i < mNetMasks.length; i++) {
-            assertEquals(mIpv4PrefixLens[i], ConfigAttribute.netmaskToPrefixLen(mNetMasks[i]));
-        }
-    }
-
-    @Test
-    public void testPrefixToNetmaskBytes() throws Exception {
-        for (int i = 0; i < mIpv4PrefixLens.length; i++) {
-            assertArrayEquals(
-                    mNetMasks[i].getAddress(),
-                    ConfigAttribute.prefixToNetmaskBytes(mIpv4PrefixLens[i]));
-        }
-    }
-
-    @Test
-    public void testDecodeIpv6AddressWithValue() throws Exception {
-        ConfigAttributeIpv6Address attributeIp6Address =
-                new ConfigAttributeIpv6Address(IPV6_ADDRESS_ATTRIBUTE_VALUE);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, attributeIp6Address.attributeType);
-        assertEquals(IPV6_LINK_ADDRESS, attributeIp6Address.linkAddress);
-    }
-
-    @Test
-    public void testDecodeIpv6AddressWithoutValue() throws Exception {
-        ConfigAttributeIpv6Address attributeIp6Address =
-                new ConfigAttributeIpv6Address(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_ADDRESS, attributeIp6Address.attributeType);
-        assertNull(attributeIp6Address.linkAddress);
-    }
-
-    @Test
-    public void testDecodeIpv6AddressWithInvalidValue() throws Exception {
-        byte[] invalidValue = new byte[] {1};
-
-        try {
-            ConfigAttributeIpv6Address attributeIp6Address =
-                    new ConfigAttributeIpv6Address(invalidValue);
-            fail("Expected to fail due to invalid attribute value");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeIpv6AddressWithValue() throws Exception {
-        ConfigAttributeIpv6Address attributeIp6Address =
-                new ConfigAttributeIpv6Address(IPV6_LINK_ADDRESS);
-
-        verifyEncodeIpv6RangeBaseAttribute(
-                attributeIp6Address,
-                CONFIG_ATTR_INTERNAL_IP6_ADDRESS,
-                IPV6_ADDRESS_ATTRIBUTE_WITH_VALUE,
-                IPV6_LINK_ADDRESS);
-    }
-
-    @Test
-    public void testEncodeIpv6AddressWithoutValue() throws Exception {
-        ConfigAttributeIpv6Address attributeIp6Address = new ConfigAttributeIpv6Address();
-
-        verifyEncodeIpv6RangeBaseAttribute(
-                attributeIp6Address,
-                CONFIG_ATTR_INTERNAL_IP6_ADDRESS,
-                IPV6_ADDRESS_ATTRIBUTE_WITHOUT_VALUE,
-                null /*expectedLinkAddress*/);
-    }
-
-    @Test
-    public void testDecodeIpv6SubnetWithValue() throws Exception {
-        ConfigAttributeIpv6Subnet attributeIp6Subnet =
-                new ConfigAttributeIpv6Subnet(IPV6_SUBNET_ATTRIBUTE_VALUE);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_SUBNET, attributeIp6Subnet.attributeType);
-        assertEquals(IPV6_LINK_ADDRESS, attributeIp6Subnet.linkAddress);
-    }
-
-    @Test
-    public void testDecodeIpv6SubnetWithoutValue() throws Exception {
-        ConfigAttributeIpv6Subnet attributeIp6Subnet = new ConfigAttributeIpv6Subnet(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_SUBNET, attributeIp6Subnet.attributeType);
-        assertNull(attributeIp6Subnet.linkAddress);
-    }
-
-    @Test
-    public void testEncodeIpv6SubnetWithoutValue() throws Exception {
-        ConfigAttributeIpv6Subnet attributeIp6Subnet = new ConfigAttributeIpv6Subnet();
-
-        verifyEncodeIpv6RangeBaseAttribute(
-                attributeIp6Subnet,
-                CONFIG_ATTR_INTERNAL_IP6_SUBNET,
-                IPV6_SUBNET_ATTRIBUTE_WITHOUT_VALUE,
-                null /*expectedLinkAddress*/);
-    }
-
-    @Test
-    public void testDecodeIpv6DnsWithValue() throws Exception {
-        ConfigAttributeIpv6Dns attribute = new ConfigAttributeIpv6Dns(IPV6_DNS.getAddress());
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_DNS, attribute.attributeType);
-        assertEquals(IPV6_DNS, attribute.address);
-    }
-
-    @Test
-    public void testDecodeIpv6DnsWithoutValue() throws Exception {
-        ConfigAttributeIpv6Dns attribute = new ConfigAttributeIpv6Dns(new byte[0]);
-
-        assertEquals(CONFIG_ATTR_INTERNAL_IP6_DNS, attribute.attributeType);
-        assertNull(attribute.address);
-    }
-
-    @Test
-    public void testEncodeIpv6Dns() throws Exception {
-        ConfigAttributeIpv6Dns attribute = new ConfigAttributeIpv6Dns();
-
-        verifyBuildAndEncodeAttributeCommon(
-                attribute, CONFIG_ATTR_INTERNAL_IP6_DNS, IPV6_DNS_ATTRIBUTE_WITHOUT_VALUE);
-        assertNull(attribute.address);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayloadTest.java
deleted file mode 100644
index 6be5336..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeDeletePayloadTest.java
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_ESP;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PROTOCOL_ID_IKE;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.SPI_LEN_IPSEC;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.SPI_LEN_NOT_INCLUDED;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-public final class IkeDeletePayloadTest {
-    private static final String DELETE_IKE_PAYLOAD_HEX_STRING = "0000000801000000";
-    private static final String DELETE_CHILD_PAYLOAD_HEX_STRING = "0000000c030400012ad4c0a2";
-    private static final String CHILD_SPI = "2ad4c0a2";
-
-    private static final String DELETE_MULTIPLE_CHILD_PAYLOAD_HEX_STRING =
-            "0000001003040002abcdef0120fedcba";
-    private static final String[] MULTIPLE_CHILD_SPIS = new String[] {"abcdef01", "20fedcba"};
-
-    private static final int NUM_CHILD_SPI = 1;
-
-    private static final int PROTOCOL_ID_OFFSET = 4;
-    private static final int SPI_SIZE_OFFSET = 5;
-    private static final int NUM_OF_SPI_OFFSET = 6;
-
-    @Test
-    public void testDecodeDeleteIkePayload() throws Exception {
-        ByteBuffer inputBuffer =
-                ByteBuffer.wrap(TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING));
-
-        IkePayload payload =
-                IkePayloadFactory.getIkePayload(
-                                IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer)
-                        .first;
-
-        assertTrue(payload instanceof IkeDeletePayload);
-
-        IkeDeletePayload deletePayload = (IkeDeletePayload) payload;
-        assertEquals(IkePayload.PROTOCOL_ID_IKE, deletePayload.protocolId);
-        assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, deletePayload.spiSize);
-        assertEquals(0, deletePayload.numSpi);
-        assertArrayEquals(new int[0], deletePayload.spisToDelete);
-    }
-
-    @Test
-    public void testDecodeDeleteChildPayload() throws Exception {
-        ByteBuffer inputBuffer =
-                ByteBuffer.wrap(TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING));
-
-        IkePayload payload =
-                IkePayloadFactory.getIkePayload(
-                                IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer)
-                        .first;
-
-        assertTrue(payload instanceof IkeDeletePayload);
-
-        IkeDeletePayload deletePayload = (IkeDeletePayload) payload;
-        assertEquals(IkePayload.PROTOCOL_ID_ESP, deletePayload.protocolId);
-        assertEquals(IkePayload.SPI_LEN_IPSEC, deletePayload.spiSize);
-        assertEquals(NUM_CHILD_SPI, deletePayload.numSpi);
-
-        int expectedChildSpi = TestUtils.hexStringToInt(CHILD_SPI);
-        assertArrayEquals(new int[] {expectedChildSpi}, deletePayload.spisToDelete);
-    }
-
-    @Test
-    public void testDecodeWithInvalidProtocol() throws Exception {
-        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
-        deletePayloadBytes[PROTOCOL_ID_OFFSET] = -1;
-        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
-
-        try {
-            IkePayloadFactory.getIkePayload(
-                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
-            fail("Expected to fail due to unrecognized protocol ID.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeWithInvalidSpiSize() throws Exception {
-        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
-        deletePayloadBytes[SPI_SIZE_OFFSET] = IkePayload.SPI_LEN_IPSEC;
-        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
-
-        try {
-            IkePayloadFactory.getIkePayload(
-                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
-            fail("Expected to fail due to invalid SPI size in Delete IKE Payload.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeWithInvalidNumSpi() throws Exception {
-        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
-        deletePayloadBytes[NUM_OF_SPI_OFFSET] = 1;
-        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
-
-        try {
-            IkePayloadFactory.getIkePayload(
-                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
-            fail("Expected to fail because number of SPI is not zero in Delete IKE Payload.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testDecodeWithInvalidNumSpiAndSpiSize() throws Exception {
-        byte[] deletePayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
-        deletePayloadBytes[SPI_SIZE_OFFSET] = 1;
-        deletePayloadBytes[NUM_CHILD_SPI] = 4;
-        ByteBuffer inputBuffer = ByteBuffer.wrap(deletePayloadBytes);
-
-        try {
-            IkePayloadFactory.getIkePayload(
-                    IkePayload.PAYLOAD_TYPE_DELETE, false /*is request*/, inputBuffer);
-            fail("Expected to fail due to invalid SPI size in Delete IKE Payload.");
-        } catch (InvalidSyntaxException expected) {
-
-        }
-    }
-
-    @Test
-    public void testOutboundConstructorForIke() throws Exception {
-        IkeDeletePayload deletePayload = new IkeDeletePayload();
-
-        assertEquals(PROTOCOL_ID_IKE, deletePayload.protocolId);
-        assertEquals(SPI_LEN_NOT_INCLUDED, deletePayload.spiSize);
-        assertEquals(0, deletePayload.numSpi);
-        assertEquals(0, deletePayload.spisToDelete.length);
-    }
-
-    @Test
-    public void testOutboundConstructorWithSingleChildSa() throws Exception {
-        int[] childSpis = new int[] {TestUtils.hexStringToInt(CHILD_SPI)};
-        IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis);
-
-        assertEquals(PROTOCOL_ID_ESP, deletePayload.protocolId);
-        assertEquals(SPI_LEN_IPSEC, deletePayload.spiSize);
-        assertEquals(NUM_CHILD_SPI, deletePayload.numSpi);
-        assertArrayEquals(childSpis, deletePayload.spisToDelete);
-    }
-
-    @Test
-    public void testOutboundConstructorWithMultipleChildSas() throws Exception {
-        int[] childSpis = new int[] {0x1, 0x2, 0xfffffffd, 0xffffffff};
-        IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis);
-
-        assertEquals(PROTOCOL_ID_ESP, deletePayload.protocolId);
-        assertEquals(SPI_LEN_IPSEC, deletePayload.spiSize);
-        assertEquals(childSpis.length, deletePayload.numSpi);
-        assertArrayEquals(childSpis, deletePayload.spisToDelete);
-    }
-
-    @Test
-    public void testOutboundConstructorWithNoChildSas() throws Exception {
-        try {
-            IkeDeletePayload deletePayload = new IkeDeletePayload(new int[] {});
-            fail("Expected exception for invalid SPI list");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testEncodeForIke() throws Exception {
-        IkeDeletePayload deletePayload = new IkeDeletePayload();
-        ByteBuffer bb = ByteBuffer.allocate(deletePayload.getPayloadLength());
-
-        deletePayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, bb);
-
-        byte[] expectedPayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedPayloadBytes, bb.array());
-    }
-
-    @Test
-    public void testEncodeWithSingleChildSa() throws Exception {
-        int[] childSpis = new int[] {TestUtils.hexStringToInt(CHILD_SPI)};
-        IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis);
-        ByteBuffer bb = ByteBuffer.allocate(deletePayload.getPayloadLength());
-
-        deletePayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, bb);
-
-        byte[] expectedPayloadBytes =
-                TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedPayloadBytes, bb.array());
-    }
-
-    @Test
-    public void testEncodeWithMultipleChildSas() throws Exception {
-        int[] childSpis =
-                Arrays.stream(MULTIPLE_CHILD_SPIS)
-                        .mapToInt(val -> TestUtils.hexStringToInt(val))
-                        .toArray();
-        IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis);
-        ByteBuffer bb = ByteBuffer.allocate(deletePayload.getPayloadLength());
-
-        deletePayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, bb);
-
-        byte[] expectedPayloadBytes =
-                TestUtils.hexStringToByteArray(DELETE_MULTIPLE_CHILD_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedPayloadBytes, bb.array());
-    }
-
-    @Test
-    public void testPayloadLengthForIke() throws Exception {
-        IkeDeletePayload deletePayload = new IkeDeletePayload();
-
-        byte[] expectedPayloadBytes = TestUtils.hexStringToByteArray(DELETE_IKE_PAYLOAD_HEX_STRING);
-        assertEquals(expectedPayloadBytes.length, deletePayload.getPayloadLength());
-    }
-
-    @Test
-    public void testPayloadLengthWithSingleChildSa() throws Exception {
-        int[] childSpis = new int[] {TestUtils.hexStringToInt(CHILD_SPI)};
-        IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis);
-
-        byte[] expectedPayloadBytes =
-                TestUtils.hexStringToByteArray(DELETE_CHILD_PAYLOAD_HEX_STRING);
-        assertEquals(expectedPayloadBytes.length, deletePayload.getPayloadLength());
-    }
-
-    @Test
-    public void testPayloadLengthWithMultipleChildSas() throws Exception {
-        int[] childSpis =
-                Arrays.stream(MULTIPLE_CHILD_SPIS)
-                        .mapToInt(val -> TestUtils.hexStringToInt(val))
-                        .toArray();
-        IkeDeletePayload deletePayload = new IkeDeletePayload(childSpis);
-
-        byte[] expectedPayloadBytes =
-                TestUtils.hexStringToByteArray(DELETE_MULTIPLE_CHILD_PAYLOAD_HEX_STRING);
-        assertEquals(expectedPayloadBytes.length, deletePayload.getPayloadLength());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayloadTest.java
deleted file mode 100644
index fff82b6..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEapPayloadTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static com.android.internal.net.TestUtils.hexStringToByteArray;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-
-public class IkeEapPayloadTest {
-    private static final String EAP_SUCCESS_STRING = "03010004";
-    private static final byte[] EAP_SUCCESS_PACKET = hexStringToByteArray(EAP_SUCCESS_STRING);
-
-    private static final byte[] IKE_EAP_PAYLOAD =
-            hexStringToByteArray(
-                    "00000008" + EAP_SUCCESS_STRING);
-
-    @Test
-    public void testDecodeIkeEapPayload() throws Exception {
-        ByteBuffer input = ByteBuffer.wrap(IKE_EAP_PAYLOAD);
-        IkePayload result = IkePayloadFactory
-                .getIkePayload(IkePayload.PAYLOAD_TYPE_EAP, true, input).first;
-
-        assertTrue(result instanceof IkeEapPayload);
-        IkeEapPayload ikeEapPayload = (IkeEapPayload) result;
-        assertArrayEquals(EAP_SUCCESS_PACKET, ikeEapPayload.eapMessage);
-    }
-
-    @Test
-    public void testEncodeToByteBuffer() {
-        IkeEapPayload ikeEapPayload = new IkeEapPayload(EAP_SUCCESS_PACKET);
-        ByteBuffer result = ByteBuffer.allocate(IKE_EAP_PAYLOAD.length);
-
-        ikeEapPayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, result);
-        assertArrayEquals(IKE_EAP_PAYLOAD, result.array());
-    }
-
-    @Test
-    public void testOutboundConstructorForIke() {
-        IkeEapPayload ikeEapPayload = new IkeEapPayload(EAP_SUCCESS_PACKET);
-        assertArrayEquals(EAP_SUCCESS_PACKET, ikeEapPayload.eapMessage);
-    }
-
-    @Test
-    public void testGetPayloadLength() {
-        IkeEapPayload ikeEapPayload = new IkeEapPayload(EAP_SUCCESS_PACKET);
-        assertEquals(IKE_EAP_PAYLOAD.length, ikeEapPayload.getPayloadLength());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBodyTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBodyTest.java
deleted file mode 100644
index 36c7648..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeEncryptedPayloadBodyTest.java
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.net.ipsec.ike.message;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeCombinedModeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-
-public final class IkeEncryptedPayloadBodyTest {
-    private static final String IKE_AUTH_INIT_REQUEST_HEADER =
-            "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec";
-    private static final String IKE_AUTH_INIT_REQUEST_SK_HEADER = "230000d0";
-    private static final String IKE_AUTH_INIT_REQUEST_IV = "b9132b7bb9f658dfdc648e5017a6322a";
-    private static final String IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA =
-            "030c316ce55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58"
-                    + "46de333ecd3ea2b705d18293b130395300ba92a351041345"
-                    + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f"
-                    + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60"
-                    + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b"
-                    + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423"
-                    + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3"
-                    + "59eb4e81";
-    private static final String IKE_AUTH_INIT_REQUEST_CHECKSUM = "ae6e0f22abdad69ba8007d50";
-
-    private static final String IKE_AUTH_INIT_REQUEST_UNENCRYPTED_DATA =
-            "2400000c010000000a50500d2700000c010000000a505050"
-                    + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327"
-                    + "44dfb2c12c00002c00000028010304032ad4c0a20300000c"
-                    + "0100000c800e008003000008030000020000000805000000"
-                    + "2d00001801000000070000100000ffff00000000ffffffff"
-                    + "2900001801000000070000100000ffff00000000ffffffff"
-                    + "29000008000040000000000c0000400100000001";
-    private static final String IKE_AUTH_INIT_REQUEST_PADDING = "0000000000000000000000";
-    private static final int HMAC_SHA1_CHECKSUM_LEN = 12;
-
-    private static final String ENCR_KEY_FROM_INIT_TO_RESP = "5cbfd33f75796c0188c4a3a546aec4a1";
-    private static final String INTE_KEY_FROM_INIT_TO_RESP =
-            "554fbf5a05b7f511e05a30ce23d874db9ef55e51";
-
-    private static final String ENCR_ALGO_AES_CBC = "AES/CBC/NoPadding";
-
-    // Test vectors for IKE message protected by HmacSha1 and 3DES
-    private static final String HMAC_SHA1_3DES_MSG_HEX_STRING =
-            "5837b1bd28ec424f85ddd0c609c8dbfe2e20232000000002"
-                    + "00000064300000488beaf41d88544baabd95eac60269f19a"
-                    + "5986295fe318ce02f65368cd957985f36b183794c4c78d35"
-                    + "437762297a131a773d7f7806aaa0c590f48b9d71001f4d65"
-                    + "70a44533";
-
-    private static final String HMAC_SHA1_3DES_DECRYPTED_BODY_HEX_STRING =
-            "00000028013c00241a013c001f10dac4f8b759138776091dd0f00033c5b07374726f6e675377616e";
-
-    private static final String HMAC_SHA1_3DES_MSG_ENCR_KEY =
-            "ee0fdd6d35bbdbe9eeef2f24495b6632e5047bdd8e413c87";
-    private static final String HMAC_SHA1_3DES_MSG_INTE_KEY =
-            "867a0bd019108db856cf6984fc9fb62d70c0de74";
-
-    // TODO: b/142753861 Test IKE fragment protected by AES_CBC instead of 3DES
-
-    // Test vectors for IKE fragment protected by HmacSha1 and 3DES
-    private static final String HMAC_SHA1_3DES_FRAG_HEX_STRING =
-            "939ae1251d18eb9077a99551b15c6e933520232000000001"
-                    + "000000c0000000a400050005fd7c7931705af184b7be76bb"
-                    + "d45a8ecbb3ffd58b9438b93f67e9fe86b06229f80e9b52d2"
-                    + "ff6afde3f2c13ae93ce55a801f62e1a818c9003880a36bbe"
-                    + "986fe6979ba233b9f4f0ddc992d06dbad5a2b998be18fae9"
-                    + "47e5ccfb37775d069344e711fbf499bb289cf4cca245bd45"
-                    + "0ad89d18689207759507ba18d47247e920b9e000a25a7596"
-                    + "e4130929e5cdc37d5c1b0d90bbaae946c260f4d3cf815f6d";
-    private static final String HMAC_SHA1_3DES_FRAG_DECRYPTED_BODY_HEX_STRING =
-            "54ebd95c572100002002000000000100040a0a0a01000300"
-                    + "040808080800030004080804042c00002c00000028020304"
-                    + "03cc86090a0300000c0100000c800e010003000008030000"
-                    + "0200000008050000002d00001801000000070000100000ff"
-                    + "ff0a0a0a010a0a0a010000001801000000070000100000ff"
-                    + "ff00000000ffffffff";
-    private static final String HMAC_SHA1_3DES_FRAG_IV = "fd7c7931705af184";
-    private static final String HMAC_SHA1_3DES_FRAG_PADDING = "dcf0fa5e2b64";
-
-    private static final int HMAC_SHA1_3DES_FRAGMENT_NUM = 5;
-    private static final int HMAC_SHA1_3DES_TOTAL_FRAGMENTS = 5;
-
-    private static final String HMAC_SHA1_3DES_FRAG_ENCR_KEY =
-            "6BBF6CB3526D6492F4DA0AF45E9B9FD3E1FF534280352073";
-    private static final String HMAC_SHA1_3DES_FRAG_INTE_KEY =
-            "293449E8E518060780B9C06F15838A06EEF57814";
-
-    // Test vectors for IKE message protected by AES_GCM_16
-    private static final String AES_GCM_MSG_HEX_STRING =
-            "77c708b4523e39a471dc683c1d4f21362e20230800000005"
-                    + "0000006127000045fbd69d9ee2dafc5e7c03a0106761065b2"
-                    + "8fa8d11aed6046f7f8af117e44da7635be6e0dfafcb0a387c"
-                    + "53fb46ba5d6fa9509161915929de97b7fbe23dc65723b0fe";
-    private static final String AES_GCM_MSG_DECRYPTED_BODY_HEX_STRING =
-            "000000280200000033233837e909ec805d56151bef5b1fa9b8e25b32419c9b3fc96ee699ec29d501";
-    private static final String AES_GCM_MSG_IV = "fbd69d9ee2dafc5e";
-    private static final String AES_GCM_MSG_ENCR_KEY =
-            "7C04513660DEC572D896105254EF92608054F8E6EE19E79CE52AB8697B2B5F2C2AA90C29";
-
-    // Test vectors for IKE fragment protected by AES_GCM_16
-    private static final String AES_GCM_FRAG_HEX_STRING =
-            "77c708b4523e39a471dc683c1d4f213635202320000000010"
-                    + "0000113000000f7000200026faf9e5c04c67571871681d443"
-                    + "01489f99fd78d318b0517a5a99bf6a3e1770f43d7d997c9e0"
-                    + "d186038d16df3fd525eda821f80b3a40fc6bce397ac67539e"
-                    + "40042919a5e9af38c70881d092a8571f0e131f594c0e8d6b8"
-                    + "4ea116f0c95619439b0a267b35bc47dac72bbfb3d3776feb3"
-                    + "86d7d4f819b0248f52f60bf4371ab6384e37819a9685c27d8"
-                    + "e41abe30cd6f60905dd5c05c351ec0a1fcf9b99360161d2f3"
-                    + "4dcf6401829df9392121d88e2201d279200e25d750678af6a"
-                    + "7f4892a5c8d4a7358ec50cdf12cfa7652488f756ba6d07441"
-                    + "e9a27aad3976ac8a705ff796857cb2df9ce360c3992e0285b"
-                    + "34834255b06";
-    private static final String AES_GCM_FRAG_DECRYPTED_BODY_HEX_STRING =
-            "0fce6e996f4936ec8db8097339c371c686be75f4bed3f259c"
-                    + "14d39c3ad90cb864085c6375f75b724d9f9daa8e7b22a106a"
-                    + "488bc48c081997b7416fd33b146882e51ff6a640edf760212"
-                    + "7f2454d502e92262ba3dd07cff52ee1bb1ea85f582db41a68"
-                    + "aaf6dace362e5d8b10cfeb65eebc7572690e2c415a11cae57"
-                    + "020810cf7aa56d9f2d5c2be3a633f8e4c6af5483a2b1f05bd"
-                    + "4340ab551ddf7f51def57eaf5a37793ff6aa1e1ec288a2adf"
-                    + "a647c369f15efa61a619966a320f24e1765c0e00c5ed394aa"
-                    + "ef14512032b005827c000000090100000501";
-    private static final String AES_GCM_FRAG_IV = "6faf9e5c04c67571";
-
-    private static final int AES_GCM_FRAGMENT_NUM = 2;
-    private static final int AES_GCM_TOTAL_FRAGMENTS = 2;
-
-    private static final String AES_GCM_FRAG_ENCR_KEY =
-            "955ED949D6F18857220E97B17D9285C830A39F8D4DC46AB43943668093C62A3D66664F8C";
-
-    private static final int ENCRYPTED_BODY_SK_OFFSET =
-            IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH;
-    private static final int ENCRYPTED_BODY_SKF_OFFSET =
-            ENCRYPTED_BODY_SK_OFFSET + IkeSkfPayload.SKF_HEADER_LEN;
-
-    private IkeNormalModeCipher mAesCbcCipher;
-    private byte[] mAesCbcKey;
-
-    private IkeMacIntegrity mHmacSha1IntegrityMac;
-    private byte[] mHmacSha1IntegrityKey;
-
-    private byte[] mDataToPadAndEncrypt;
-    private byte[] mDataToAuthenticate;
-    private byte[] mEncryptedPaddedData;
-    private byte[] mIkeMessage;
-
-    private byte[] mChecksum;
-    private byte[] mIv;
-    private byte[] mPadding;
-
-    private IkeNormalModeCipher m3DesCipher;
-
-    private IkeCombinedModeCipher mAesGcm16Cipher;
-
-    private byte[] mAesGcmMsgKey;
-    private byte[] mAesGcmMsg;
-    private byte[] mAesGcmUnencryptedData;
-
-    private byte[] mAesGcmFragKey;
-    private byte[] mAesGcmFragMsg;
-    private byte[] mAesGcmFragUnencryptedData;
-
-    @Before
-    public void setUp() throws Exception {
-        mDataToPadAndEncrypt =
-                TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_UNENCRYPTED_DATA);
-        String hexStringToAuthenticate =
-                IKE_AUTH_INIT_REQUEST_HEADER
-                        + IKE_AUTH_INIT_REQUEST_SK_HEADER
-                        + IKE_AUTH_INIT_REQUEST_IV
-                        + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA;
-        mDataToAuthenticate = TestUtils.hexStringToByteArray(hexStringToAuthenticate);
-        mEncryptedPaddedData =
-                TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA);
-        mIkeMessage =
-                TestUtils.hexStringToByteArray(
-                        IKE_AUTH_INIT_REQUEST_HEADER
-                                + IKE_AUTH_INIT_REQUEST_SK_HEADER
-                                + IKE_AUTH_INIT_REQUEST_IV
-                                + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA
-                                + IKE_AUTH_INIT_REQUEST_CHECKSUM);
-
-        mChecksum = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_CHECKSUM);
-        mIv = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_IV);
-        mPadding = TestUtils.hexStringToByteArray(IKE_AUTH_INIT_REQUEST_PADDING);
-
-        m3DesCipher =
-                (IkeNormalModeCipher)
-                        IkeCipher.create(
-                                new EncryptionTransform(SaProposal.ENCRYPTION_ALGORITHM_3DES),
-                                IkeMessage.getSecurityProvider());
-
-        mAesCbcCipher =
-                (IkeNormalModeCipher)
-                        IkeCipher.create(
-                                new EncryptionTransform(
-                                        SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
-                                        SaProposal.KEY_LEN_AES_128),
-                                IkeMessage.getSecurityProvider());
-        mAesCbcKey = TestUtils.hexStringToByteArray(ENCR_KEY_FROM_INIT_TO_RESP);
-
-        mHmacSha1IntegrityMac =
-                IkeMacIntegrity.create(
-                        new IntegrityTransform(SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96),
-                        IkeMessage.getSecurityProvider());
-        mHmacSha1IntegrityKey = TestUtils.hexStringToByteArray(INTE_KEY_FROM_INIT_TO_RESP);
-
-        mAesGcm16Cipher =
-                (IkeCombinedModeCipher)
-                        IkeCipher.create(
-                                new EncryptionTransform(
-                                        SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16,
-                                        SaProposal.KEY_LEN_AES_256),
-                                IkeMessage.getSecurityProvider());
-
-        mAesGcmMsgKey = TestUtils.hexStringToByteArray(AES_GCM_MSG_ENCR_KEY);
-        mAesGcmMsg = TestUtils.hexStringToByteArray(AES_GCM_MSG_HEX_STRING);
-        mAesGcmUnencryptedData =
-                TestUtils.hexStringToByteArray(AES_GCM_MSG_DECRYPTED_BODY_HEX_STRING);
-
-        mAesGcmFragKey = TestUtils.hexStringToByteArray(AES_GCM_FRAG_ENCR_KEY);
-        mAesGcmFragMsg = TestUtils.hexStringToByteArray(AES_GCM_FRAG_HEX_STRING);
-        mAesGcmFragUnencryptedData =
-                TestUtils.hexStringToByteArray(AES_GCM_FRAG_DECRYPTED_BODY_HEX_STRING);
-    }
-
-    @Test
-    public void testValidateChecksum() throws Exception {
-        IkeEncryptedPayloadBody.validateInboundChecksumOrThrow(
-                mDataToAuthenticate, mHmacSha1IntegrityMac, mHmacSha1IntegrityKey, mChecksum);
-    }
-
-    @Test
-    public void testThrowForInvalidChecksum() throws Exception {
-        byte[] dataToAuthenticate = Arrays.copyOf(mDataToAuthenticate, mDataToAuthenticate.length);
-        dataToAuthenticate[0]++;
-
-        try {
-            IkeEncryptedPayloadBody.validateInboundChecksumOrThrow(
-                    dataToAuthenticate, mHmacSha1IntegrityMac, mHmacSha1IntegrityKey, mChecksum);
-            fail("Expected GeneralSecurityException due to mismatched checksum.");
-        } catch (GeneralSecurityException expected) {
-        }
-    }
-
-    @Test
-    public void testCalculatePaddingPlaintextShorterThanBlockSize() throws Exception {
-        int blockSize = 16;
-        int plainTextLength = 15;
-        int expectedPadLength = 0;
-
-        byte[] calculatedPadding =
-                IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize);
-        assertEquals(expectedPadLength, calculatedPadding.length);
-    }
-
-    @Test
-    public void testCalculatePaddingPlaintextInBlockSize() throws Exception {
-        int blockSize = 16;
-        int plainTextLength = 16;
-        int expectedPadLength = 15;
-
-        byte[] calculatedPadding =
-                IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize);
-        assertEquals(expectedPadLength, calculatedPadding.length);
-    }
-
-    @Test
-    public void testCalculatePaddingPlaintextLongerThanBlockSize() throws Exception {
-        int blockSize = 16;
-        int plainTextLength = 17;
-        int expectedPadLength = 14;
-
-        byte[] calculatedPadding =
-                IkeEncryptedPayloadBody.calculatePadding(plainTextLength, blockSize);
-        assertEquals(expectedPadLength, calculatedPadding.length);
-    }
-
-    @Test
-    public void testEncrypt() throws Exception {
-        byte[] calculatedData =
-                IkeEncryptedPayloadBody.normalModeEncrypt(
-                        mDataToPadAndEncrypt, mAesCbcCipher, mAesCbcKey, mIv, mPadding);
-
-        assertArrayEquals(mEncryptedPaddedData, calculatedData);
-    }
-
-    @Test
-    public void testDecrypt() throws Exception {
-        byte[] calculatedPlainText =
-                IkeEncryptedPayloadBody.normalModeDecrypt(
-                        mEncryptedPaddedData, mAesCbcCipher, mAesCbcKey, mIv);
-
-        assertArrayEquals(mDataToPadAndEncrypt, calculatedPlainText);
-    }
-
-    @Test
-    public void testBuildAndEncodeOutboundIkeEncryptedPayloadBody() throws Exception {
-        IkeHeader ikeHeader = new IkeHeader(mIkeMessage);
-
-        IkeEncryptedPayloadBody payloadBody =
-                new IkeEncryptedPayloadBody(
-                        ikeHeader,
-                        IkePayload.PAYLOAD_TYPE_ID_INITIATOR,
-                        new byte[0] /*skfHeader*/,
-                        mDataToPadAndEncrypt,
-                        mHmacSha1IntegrityMac,
-                        mAesCbcCipher,
-                        mHmacSha1IntegrityKey,
-                        mAesCbcKey,
-                        mIv,
-                        mPadding);
-
-        byte[] expectedEncodedData =
-                TestUtils.hexStringToByteArray(
-                        IKE_AUTH_INIT_REQUEST_IV
-                                + IKE_AUTH_INIT_REQUEST_ENCRYPT_PADDED_DATA
-                                + IKE_AUTH_INIT_REQUEST_CHECKSUM);
-        assertArrayEquals(expectedEncodedData, payloadBody.encode());
-    }
-
-    @Test
-    public void testAuthAndDecodeHmacSha1AesCbc() throws Exception {
-        IkeEncryptedPayloadBody payloadBody =
-                new IkeEncryptedPayloadBody(
-                        mIkeMessage,
-                        ENCRYPTED_BODY_SK_OFFSET,
-                        mHmacSha1IntegrityMac,
-                        mAesCbcCipher,
-                        mHmacSha1IntegrityKey,
-                        mAesCbcKey);
-
-        assertArrayEquals(mDataToPadAndEncrypt, payloadBody.getUnencryptedData());
-    }
-
-    @Test
-    public void testAuthAndDecodeHmacSha13Des() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_HEX_STRING);
-        byte[] expectedDecryptedData =
-                TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_DECRYPTED_BODY_HEX_STRING);
-
-        IkeEncryptedPayloadBody payloadBody =
-                new IkeEncryptedPayloadBody(
-                        message,
-                        ENCRYPTED_BODY_SK_OFFSET,
-                        mHmacSha1IntegrityMac,
-                        m3DesCipher,
-                        TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_INTE_KEY),
-                        TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_MSG_ENCR_KEY));
-
-        assertArrayEquals(expectedDecryptedData, payloadBody.getUnencryptedData());
-    }
-
-    @Test
-    public void testBuildAndEncodeWithHmacSha13Des() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_HEX_STRING);
-        IkeHeader ikeHeader = new IkeHeader(message);
-
-        byte[] skfHeaderBytes =
-                IkeSkfPayload.encodeSkfHeader(
-                        HMAC_SHA1_3DES_FRAGMENT_NUM, HMAC_SHA1_3DES_TOTAL_FRAGMENTS);
-
-        IkeEncryptedPayloadBody payloadBody =
-                new IkeEncryptedPayloadBody(
-                        ikeHeader,
-                        IkePayload.PAYLOAD_TYPE_NO_NEXT,
-                        skfHeaderBytes,
-                        TestUtils.hexStringToByteArray(
-                                HMAC_SHA1_3DES_FRAG_DECRYPTED_BODY_HEX_STRING),
-                        mHmacSha1IntegrityMac,
-                        m3DesCipher,
-                        TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_INTE_KEY),
-                        TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_ENCR_KEY),
-                        TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_IV),
-                        TestUtils.hexStringToByteArray(HMAC_SHA1_3DES_FRAG_PADDING));
-
-        byte[] expectedEncodedData =
-                Arrays.copyOfRange(message, ENCRYPTED_BODY_SKF_OFFSET, message.length);
-
-        assertArrayEquals(expectedEncodedData, payloadBody.encode());
-    }
-
-    @Test
-    public void testAuthAndDecodeFullMsgWithAesGcm() throws Exception {
-        IkeEncryptedPayloadBody encryptedBody =
-                new IkeEncryptedPayloadBody(
-                        mAesGcmMsg,
-                        ENCRYPTED_BODY_SK_OFFSET,
-                        null /*integrityMac*/,
-                        mAesGcm16Cipher,
-                        null /*integrityKey*/,
-                        mAesGcmMsgKey);
-
-        assertArrayEquals(mAesGcmUnencryptedData, encryptedBody.getUnencryptedData());
-    }
-
-    @Test
-    public void testBuildAndEncodeMsgWithAesGcm() throws Exception {
-        IkeHeader ikeHeader = new IkeHeader(mAesGcmMsg);
-
-        IkeEncryptedPayloadBody payloadBody =
-                new IkeEncryptedPayloadBody(
-                        ikeHeader,
-                        IkePayload.PAYLOAD_TYPE_AUTH,
-                        new byte[0],
-                        mAesGcmUnencryptedData,
-                        null /*integrityMac*/,
-                        mAesGcm16Cipher,
-                        null /*integrityKey*/,
-                        mAesGcmMsgKey,
-                        TestUtils.hexStringToByteArray(AES_GCM_MSG_IV),
-                        new byte[0] /*padding*/);
-
-        byte[] expectedEncodedData =
-                Arrays.copyOfRange(mAesGcmMsg, ENCRYPTED_BODY_SK_OFFSET, mAesGcmMsg.length);
-
-        assertArrayEquals(expectedEncodedData, payloadBody.encode());
-    }
-
-    @Test
-    public void testAuthAndDecodeFragMsgWithAesGcm() throws Exception {
-        IkeEncryptedPayloadBody encryptedBody =
-                new IkeEncryptedPayloadBody(
-                        mAesGcmFragMsg,
-                        ENCRYPTED_BODY_SKF_OFFSET,
-                        null /*integrityMac*/,
-                        mAesGcm16Cipher,
-                        null /*integrityKey*/,
-                        mAesGcmFragKey);
-
-        assertArrayEquals(mAesGcmFragUnencryptedData, encryptedBody.getUnencryptedData());
-    }
-
-    @Test
-    public void testBuildAndEncodeFragMsgWithAesGcm() throws Exception {
-        IkeHeader ikeHeader = new IkeHeader(mAesGcmFragMsg);
-        byte[] skfHeaderBytes =
-                IkeSkfPayload.encodeSkfHeader(AES_GCM_FRAGMENT_NUM, AES_GCM_TOTAL_FRAGMENTS);
-
-        IkeEncryptedPayloadBody payloadBody =
-                new IkeEncryptedPayloadBody(
-                        ikeHeader,
-                        IkePayload.PAYLOAD_TYPE_NO_NEXT,
-                        skfHeaderBytes,
-                        mAesGcmFragUnencryptedData,
-                        null /*integrityMac*/,
-                        mAesGcm16Cipher,
-                        null /*integrityKey*/,
-                        mAesGcmFragKey,
-                        TestUtils.hexStringToByteArray(AES_GCM_FRAG_IV),
-                        new byte[0] /*padding*/);
-
-        byte[] expectedEncodedData =
-                Arrays.copyOfRange(
-                        mAesGcmFragMsg, ENCRYPTED_BODY_SKF_OFFSET, mAesGcmFragMsg.length);
-
-        assertArrayEquals(expectedEncodedData, payloadBody.encode());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayloadTest.java
deleted file mode 100644
index 75552b3..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeIdPayloadTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import android.net.ipsec.ike.IkeFqdnIdentification;
-import android.net.ipsec.ike.IkeIdentification;
-import android.net.ipsec.ike.IkeIpv4AddrIdentification;
-import android.net.ipsec.ike.IkeIpv6AddrIdentification;
-import android.net.ipsec.ike.IkeKeyIdIdentification;
-import android.net.ipsec.ike.IkeRfc822AddrIdentification;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.nio.ByteBuffer;
-
-public final class IkeIdPayloadTest {
-
-    private static final String IPV4_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING =
-            "2700000c01000000c0000264";
-    private static final String IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING = "01000000c0000264";
-    private static final String IPV4_ADDR_STRING = "192.0.2.100";
-
-    private static final String IPV6_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING =
-            "27000018050000000000200100000db80000000000000001";
-    private static final String IPV6_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING =
-            "050000000000200100000db80000000000000001";
-    private static final String IPV6_ADDR_STRING = "0:2001:0:db8::1";
-
-    private static final String FQDN_ID_PAYLOAD_HEX_STRING =
-            "2500001702000000696B652E616E64726F69642E6E6574";
-    private static final String FQDN_ID_PAYLOAD_BODY_HEX_STRING =
-            "02000000696B652E616E64726F69642E6E6574";
-    private static final String FQDN = "ike.android.net";
-
-    private static final String RFC822_ADDR_ID_PAYLOAD_HEX_STRING =
-            "2500001e03000000616e64726f6964696b65406578616d706c652e636f6d";
-    private static final String RFC822_ADDR_ID_PAYLOAD_BODY_HEX_STRING =
-            "03000000616e64726f6964696b65406578616d706c652e636f6d";
-    private static final String RFC822_NAME = "androidike@example.com";
-
-    private static final String KEY_ID_PAYLOAD_HEX_STRING =
-            "250000170b000000616E64726F6964496B654B65794964";
-    private static final String KEY_ID_PAYLOAD_BODY_HEX_STRING =
-            "0b000000616E64726F6964496B654B65794964";
-    private static final byte[] KEY_ID = "androidIkeKeyId".getBytes();
-
-    private static final int ID_TYPE_OFFSET = 0;
-
-    @Test
-    public void testDecodeIpv4AddrIdPayload() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING);
-        IkeIdPayload payload = new IkeIdPayload(false, inputPacket, false);
-
-        assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType);
-        assertEquals(IkeIdentification.ID_TYPE_IPV4_ADDR, payload.ikeId.idType);
-        IkeIpv4AddrIdentification ikeId = (IkeIpv4AddrIdentification) payload.ikeId;
-        Inet4Address expectedAddr = (Inet4Address) Inet4Address.getByName(IPV4_ADDR_STRING);
-        assertEquals(expectedAddr, ikeId.ipv4Address);
-    }
-
-    @Test
-    public void testDecodeIpv6AddrIdPayload() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(IPV6_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING);
-        IkeIdPayload payload = new IkeIdPayload(false, inputPacket, false);
-
-        assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType);
-        assertEquals(IkeIdentification.ID_TYPE_IPV6_ADDR, payload.ikeId.idType);
-        IkeIpv6AddrIdentification ikeId = (IkeIpv6AddrIdentification) payload.ikeId;
-        Inet6Address expectedAddr = (Inet6Address) Inet6Address.getByName(IPV6_ADDR_STRING);
-        assertEquals(expectedAddr, ikeId.ipv6Address);
-    }
-
-    @Test
-    public void testDecodeFqdnIdPayload() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(FQDN_ID_PAYLOAD_BODY_HEX_STRING);
-        IkeIdPayload payload =
-                new IkeIdPayload(false /*critical*/, inputPacket, false /*isInitiator*/);
-
-        assertEquals(IkePayload.PAYLOAD_TYPE_ID_RESPONDER, payload.payloadType);
-        assertArrayEquals(inputPacket, payload.getEncodedPayloadBody());
-        assertEquals(IkeIdentification.ID_TYPE_FQDN, payload.ikeId.idType);
-        IkeFqdnIdentification ikeId = (IkeFqdnIdentification) payload.ikeId;
-        assertEquals(FQDN, ikeId.fqdn);
-    }
-
-    @Test
-    public void testDecodeRfc822AddrIdPayload() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(RFC822_ADDR_ID_PAYLOAD_BODY_HEX_STRING);
-        IkeIdPayload payload =
-                new IkeIdPayload(false /*critical*/, inputPacket, true /*isInitiator*/);
-
-        assertEquals(IkePayload.PAYLOAD_TYPE_ID_INITIATOR, payload.payloadType);
-        assertEquals(IkeIdentification.ID_TYPE_RFC822_ADDR, payload.ikeId.idType);
-        IkeRfc822AddrIdentification ikeId = (IkeRfc822AddrIdentification) payload.ikeId;
-        assertEquals(RFC822_NAME, ikeId.rfc822Name);
-    }
-
-    @Test
-    public void testDecodeKeyIdPayload() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(KEY_ID_PAYLOAD_BODY_HEX_STRING);
-        IkeIdPayload payload =
-                new IkeIdPayload(false /*critical*/, inputPacket, true /*isInitiator*/);
-
-        assertEquals(IkePayload.PAYLOAD_TYPE_ID_INITIATOR, payload.payloadType);
-        assertEquals(IkeIdentification.ID_TYPE_KEY_ID, payload.ikeId.idType);
-        IkeKeyIdIdentification ikeId = (IkeKeyIdIdentification) payload.ikeId;
-        assertArrayEquals(KEY_ID, ikeId.keyId);
-    }
-
-    @Test
-    public void testDecodeUnsupportedIdType() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_BODY_HEX_STRING);
-        inputPacket[ID_TYPE_OFFSET] = 0;
-
-        try {
-            new IkeIdPayload(false, inputPacket, true);
-            fail("Expected AuthenticationFailedException: ID Type is unsupported.");
-        } catch (AuthenticationFailedException expected) {
-        }
-    }
-
-    @Test
-    public void testConstructAndEncodeIpv4AddrIdPayload() throws Exception {
-        Inet4Address ipv4Address = (Inet4Address) Inet4Address.getByName(IPV4_ADDR_STRING);
-        IkeIdPayload payload = new IkeIdPayload(false, new IkeIpv4AddrIdentification(ipv4Address));
-
-        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_AUTH, inputBuffer);
-
-        byte[] expectedBytes =
-                TestUtils.hexStringToByteArray(IPV4_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING);
-        assertArrayEquals(expectedBytes, inputBuffer.array());
-    }
-
-    @Test
-    public void testConstructAndEncodeIpv6AddrIdPayload() throws Exception {
-        Inet6Address ipv6Address = (Inet6Address) Inet6Address.getByName(IPV6_ADDR_STRING);
-        IkeIdPayload payload = new IkeIdPayload(false, new IkeIpv6AddrIdentification(ipv6Address));
-
-        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_AUTH, inputBuffer);
-
-        byte[] expectedBytes =
-                TestUtils.hexStringToByteArray(IPV6_ADDR_ID_PAYLOAD_RESPONDER_HEX_STRING);
-        assertArrayEquals(expectedBytes, inputBuffer.array());
-    }
-
-    @Test
-    public void testConstructAndEncodeFqdnIdPayload() throws Exception {
-        IkeIdPayload payload =
-                new IkeIdPayload(false /*isInitiator*/, new IkeFqdnIdentification(FQDN));
-
-        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_CERT, inputBuffer);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(FQDN_ID_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedBytes, inputBuffer.array());
-    }
-
-    @Test
-    public void testConstructAndEncodeRfc822AddrIdPayload() throws Exception {
-        IkeIdPayload payload =
-                new IkeIdPayload(
-                        true /*isInitiator*/, new IkeRfc822AddrIdentification(RFC822_NAME));
-
-        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_CERT, inputBuffer);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(RFC822_ADDR_ID_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedBytes, inputBuffer.array());
-    }
-
-    @Test
-    public void testConstructAndEncodeKeyIdPayload() throws Exception {
-        IkeIdPayload payload =
-                new IkeIdPayload(true /*isInitiator*/, new IkeKeyIdIdentification(KEY_ID));
-
-        ByteBuffer inputBuffer = ByteBuffer.allocate(payload.getPayloadLength());
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_CERT, inputBuffer);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(KEY_ID_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedBytes, inputBuffer.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeMessageTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeMessageTest.java
deleted file mode 100644
index 38b4152..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeMessageTest.java
+++ /dev/null
@@ -1,935 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_OK;
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_PROTECTED_ERROR;
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_UNPROTECTED_ERROR;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_AUTH;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_ID_INITIATOR;
-import static com.android.internal.net.ipsec.ike.message.IkePayload.PAYLOAD_TYPE_NO_NEXT;
-import static com.android.internal.net.ipsec.ike.message.IkeTestUtils.makeDummySkfPayload;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyBoolean;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.net.ipsec.ike.exceptions.IkeException;
-import android.net.ipsec.ike.exceptions.IkeInternalException;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.SaRecord.IkeSaRecord;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidMessageIdException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.UnsupportedCriticalPayloadException;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultError;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultOk;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultPartial;
-import com.android.internal.net.ipsec.ike.message.IkePayloadFactory.IIkePayloadDecoder;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.security.GeneralSecurityException;
-import java.util.Arrays;
-import java.util.LinkedList;
-
-import javax.crypto.IllegalBlockSizeException;
-
-public final class IkeMessageTest {
-    private static final String IKE_SA_INIT_HEADER_RAW_PACKET =
-            "8f54bf6d8b48e6e10000000000000000212022080000000000000150";
-    private static final String IKE_SA_INIT_BODY_RAW_PACKET =
-            "220000300000002c010100040300000c0100000c"
-                    + "800e00800300000803000002030000080400000200000008"
-                    + "020000022800008800020000b4a2faf4bb54878ae21d6385"
-                    + "12ece55d9236fc5046ab6cef82220f421f3ce6361faf3656"
-                    + "4ecb6d28798a94aad7b2b4b603ddeaaa5630adb9ece8ac37"
-                    + "534036040610ebdd92f46bef84f0be7db860351843858f8a"
-                    + "cf87056e272377f70c9f2d81e29c7b0ce4f291a3a72476bb"
-                    + "0b278fd4b7b0a4c26bbeb08214c707137607958729000024"
-                    + "c39b7f368f4681b89fa9b7be6465abd7c5f68b6ed5d3b4c7"
-                    + "2cb4240eb5c464122900001c00004004e54f73b7d83f6beb"
-                    + "881eab2051d8663f421d10b02b00001c00004005d915368c"
-                    + "a036004cb578ae3e3fb268509aeab1900000002069936922"
-                    + "8741c6d4ca094c93e242c9de19e7b7c60000000500000500";
-    private static final String IKE_SA_INIT_RAW_PACKET =
-            IKE_SA_INIT_HEADER_RAW_PACKET + IKE_SA_INIT_BODY_RAW_PACKET;
-
-    // Byte offsets of first payload type in IKE message header.
-    private static final int FIRST_PAYLOAD_TYPE_OFFSET = 16;
-    // Byte offsets of first payload's critical bit in IKE message body.
-    private static final int PAYLOAD_CRITICAL_BIT_OFFSET = 1;
-    // Byte offsets of first payload length in IKE message body.
-    private static final int FIRST_PAYLOAD_LENGTH_OFFSET = 2;
-    // Byte offsets of last payload length in IKE message body.
-    private static final int LAST_PAYLOAD_LENGTH_OFFSET = 278;
-
-    private static final String IKE_AUTH_HEADER_HEX_STRING =
-            "5f54bf6d8b48e6e1909232b3d1edcb5c2e20230800000001000000ec";
-    private static final String IKE_AUTH_BODY_HEX_STRING =
-            "230000d0b9132b7bb9f658dfdc648e5017a6322a030c316c"
-                    + "e55f365760d46426ce5cfc78bd1ed9abff63eb9594c1bd58"
-                    + "46de333ecd3ea2b705d18293b130395300ba92a351041345"
-                    + "0a10525cea51b2753b4e92b081fd78d995659a98f742278f"
-                    + "f9b8fd3e21554865c15c79a5134d66b2744966089e416c60"
-                    + "a274e44a9a3f084eb02f3bdce1e7de9de8d9a62773ab563b"
-                    + "9a69ba1db03c752acb6136452b8a86c41addb4210d68c423"
-                    + "efed80e26edca5fa3fe5d0a5ca9375ce332c474b93fb1fa3"
-                    + "59eb4e81ae6e0f22abdad69ba8007d50";
-
-    private static final String IKE_AUTH_EXPECTED_CHECKSUM_HEX_STRING = "ae6e0f22abdad69ba8007d50";
-    private static final String IKE_AUTH_HEX_STRING =
-            IKE_AUTH_HEADER_HEX_STRING + IKE_AUTH_BODY_HEX_STRING;
-
-    private static final String IKE_AUTH_UNENCRYPTED_PADDED_DATA_HEX_STRING =
-            "2400000c010000000a50500d2700000c010000000a505050"
-                    + "2100001c02000000df7c038aefaaa32d3f44b228b52a3327"
-                    + "44dfb2c12c00002c00000028010304032ad4c0a20300000c"
-                    + "0100000c800e008003000008030000020000000805000000"
-                    + "2d00001801000000070000100000ffff00000000ffffffff"
-                    + "2900001801000000070000100000ffff00000000ffffffff"
-                    + "29000008000040000000000c000040010000000100000000"
-                    + "000000000000000b";
-
-    private static final String IKE_FRAG_HEX_STRING =
-            "939ae1251d18eb9077a99551b15c6e9335202320000000010000"
-                    + "00c0000000a400020002fd7c7931705af184b7be76bbd45a"
-                    + "8ecbb3ffd58b9438b93f67e9fe86b06229f80e9b52d2ff6a"
-                    + "fde3f2c13ae93ce55a801f62e1a818c9003880a36bbe986f"
-                    + "e6979ba233b9f4f0ddc992d06dbad5a2b998be18fae947e5"
-                    + "ccfb37775d069344e711fbf499bb289cf4cca245bd450ad8"
-                    + "9d18689207759507ba18d47247e920b9e000a25a7596e413"
-                    + "0929e5cdc37d5c1b0d90bbaae946c260f4d3cf815f6d";
-    private static final String ID_INIT_PAYLOAD_HEX_STRING = "2400000c010000000a50500d";
-    private static final String ID_RESP_PAYLOAD_HEX_STRING = "0000000c010000000a505050";
-
-    private static final long INIT_SPI = 0x5f54bf6d8b48e6e1L;
-    private static final long RESP_SPI = 0x909232b3d1edcb5cL;
-    private static final String IKE_EMPTY_INFO_MSG_HEX_STRING =
-            "5f54bf6d8b48e6e1909232b3d1edcb5c2e20252800000000"
-                    + "0000004c00000030e376871750fdba9f7012446c5dc3f97a"
-                    + "f83b48ba0dbc68bcc4a78136832100aa4192f251cd4d1b97"
-                    + "d298e550";
-    private static final String IKE_EMPTY_INFO_MSG_IV_HEX_STRING =
-            "e376871750fdba9f7012446c5dc3f97a";
-    private static final String IKE_EMPTY_INFO_MSG_ENCRYPTED_DATA_HEX_STRING =
-            "f83b48ba0dbc68bcc4a78136832100aa";
-    private static final String IKE_EMPTY_INFO_MSG_CHECKSUM_HEX_STRING = "4192f251cd4d1b97d298e550";
-
-    private static final byte[] FRAGMENT_ONE_UNENCRYPTED_DATA = "fragmentOne".getBytes();
-    private static final byte[] FRAGMENT_TWO_UNENCRYPTED_DATA = "fragmentTwo".getBytes();
-
-    private static final int TOTAL_FRAGMENTS = 2;
-    private static final int FRAGMENT_NUM_ONE = 1;
-    private static final int FRAGMENT_NUM_TWO = 2;
-
-    private static final int IKE_FRAG_EXPECTED_MESSAGE_ID = 1;
-
-    private static final int IKE_AUTH_EXPECTED_MESSAGE_ID = 1;
-    private static final int IKE_AUTH_CIPHER_IV_SIZE = 16;
-    private static final int IKE_AUTH_CIPHER_BLOCK_SIZE = 16;
-    private static final int IKE_AUTH_PAYLOAD_SIZE = 8;
-
-    private byte[] mIkeAuthPacket;
-    private byte[] mUnencryptedPaddedData;
-    private IkeHeader mIkeAuthHeader;
-
-    private IIkePayloadDecoder mSpyIkePayloadDecoder;
-
-    private IkeMacIntegrity mMockIntegrity;
-    private IkeNormalModeCipher mMockCipher;
-    private IkeSaRecord mMockIkeSaRecord;
-
-    private byte[] mIkeFragPacketOne;
-    private byte[] mIkeFragPacketTwo;
-    private IkeHeader mFragOneHeader;
-    private IkeHeader mFragTwoHeader;
-
-    private IkeSkfPayload mDummySkfPayloadOne;
-    private IkeSkfPayload mDummySkfPayloadTwo;
-
-    private static final int[] EXPECTED_IKE_INIT_PAYLOAD_LIST = {
-        IkePayload.PAYLOAD_TYPE_SA,
-        IkePayload.PAYLOAD_TYPE_KE,
-        IkePayload.PAYLOAD_TYPE_NONCE,
-        IkePayload.PAYLOAD_TYPE_NOTIFY,
-        IkePayload.PAYLOAD_TYPE_NOTIFY,
-        IkePayload.PAYLOAD_TYPE_VENDOR
-    };
-
-    class TestIkeSupportedPayload extends IkePayload {
-        TestIkeSupportedPayload(int payload, boolean critical) {
-            super(payload, critical);
-        }
-
-        @Override
-        protected void encodeToByteBuffer(@PayloadType int nextPayload, ByteBuffer byteBuffer) {
-            throw new UnsupportedOperationException(
-                    "It is not supported to encode " + getTypeString());
-        }
-
-        @Override
-        protected int getPayloadLength() {
-            throw new UnsupportedOperationException(
-                    "It is not supported to get payload length of " + getTypeString());
-        }
-
-        @Override
-        public String getTypeString() {
-            return "Test(" + payloadType + ")";
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mSpyIkePayloadDecoder = spy(new IkePayloadFactory.IkePayloadDecoder());
-        doAnswer(
-                (invocation) -> {
-                    int payloadType = (int) invocation.getArguments()[0];
-                    boolean isCritical = (boolean) invocation.getArguments()[1];
-                    if (support(payloadType)) {
-                        return new TestIkeSupportedPayload(payloadType, isCritical);
-                    }
-                    return new IkeUnsupportedPayload(payloadType, isCritical);
-                })
-                .when(mSpyIkePayloadDecoder)
-                .decodeIkePayload(anyInt(), anyBoolean(), anyBoolean(), any());
-
-        IkePayloadFactory.sDecoderInstance = mSpyIkePayloadDecoder;
-
-        mIkeAuthPacket = TestUtils.hexStringToByteArray(IKE_AUTH_HEX_STRING);
-        mUnencryptedPaddedData =
-                TestUtils.hexStringToByteArray(IKE_AUTH_UNENCRYPTED_PADDED_DATA_HEX_STRING);
-        mIkeAuthHeader = new IkeHeader(mIkeAuthPacket);
-
-        mMockIntegrity = mock(IkeMacIntegrity.class);
-        byte[] expectedChecksum =
-                TestUtils.hexStringToByteArray(IKE_AUTH_EXPECTED_CHECKSUM_HEX_STRING);
-        when(mMockIntegrity.generateChecksum(any(), any())).thenReturn(expectedChecksum);
-        when(mMockIntegrity.getChecksumLen()).thenReturn(expectedChecksum.length);
-
-        mMockCipher = mock(IkeNormalModeCipher.class);
-        when(mMockCipher.getIvLen()).thenReturn(IKE_AUTH_CIPHER_IV_SIZE);
-        when(mMockCipher.getBlockSize()).thenReturn(IKE_AUTH_CIPHER_BLOCK_SIZE);
-        when(mMockCipher.decrypt(any(), any(), any())).thenReturn(mUnencryptedPaddedData);
-
-        mMockIkeSaRecord = mock(IkeSaRecord.class);
-        when(mMockIkeSaRecord.getInboundDecryptionKey()).thenReturn(new byte[0]);
-        when(mMockIkeSaRecord.getInboundIntegrityKey()).thenReturn(new byte[0]);
-
-        mIkeFragPacketOne = makeFragmentBytes(1 /*fragNum*/, 2 /*totalFragments*/);
-        mIkeFragPacketTwo = makeFragmentBytes(2 /*fragNum*/, 2 /*totalFragments*/);
-
-        mFragOneHeader = new IkeHeader(mIkeFragPacketOne);
-        mFragTwoHeader = new IkeHeader(mIkeFragPacketTwo);
-
-        mDummySkfPayloadOne =
-                makeDummySkfPayload(
-                        FRAGMENT_ONE_UNENCRYPTED_DATA, FRAGMENT_NUM_ONE, TOTAL_FRAGMENTS);
-        mDummySkfPayloadTwo =
-                makeDummySkfPayload(
-                        FRAGMENT_TWO_UNENCRYPTED_DATA, FRAGMENT_NUM_TWO, TOTAL_FRAGMENTS);
-    }
-
-    private byte[] makeFragmentBytes(int fragNum, int totalFragments) {
-        byte[] packet = TestUtils.hexStringToByteArray(IKE_FRAG_HEX_STRING);
-        ByteBuffer byteBuffer = ByteBuffer.wrap(packet);
-        byteBuffer.get(new byte[IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH]);
-
-        byteBuffer.putShort((short) fragNum).putShort((short) totalFragments);
-        return byteBuffer.array();
-    }
-
-    @After
-    public void tearDown() {
-        IkePayloadFactory.sDecoderInstance = new IkePayloadFactory.IkePayloadDecoder();
-    }
-
-    private IkeMessage verifyDecodeResultOkAndGetMessage(
-            DecodeResult decodeResult, byte[] firstPacket) throws Exception {
-        assertEquals(DECODE_STATUS_OK, decodeResult.status);
-
-        DecodeResultOk resultOk = (DecodeResultOk) decodeResult;
-        assertNotNull(resultOk.ikeMessage);
-        assertArrayEquals(firstPacket, resultOk.firstPacket);
-
-        return resultOk.ikeMessage;
-    }
-
-    private IkeException verifyDecodeResultErrorAndGetIkeException(
-            DecodeResult decodeResult, int decodeStatus, byte[] firstPacket) throws Exception {
-        assertEquals(decodeStatus, decodeResult.status);
-
-        DecodeResultError resultError = (DecodeResultError) decodeResult;
-        assertNotNull(resultError.ikeException);
-
-        return resultError.ikeException;
-    }
-
-    @Test
-    public void testDecodeIkeMessage() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
-        IkeHeader header = new IkeHeader(inputPacket);
-
-        DecodeResult decodeResult = IkeMessage.decode(0, header, inputPacket);
-
-        IkeMessage message = verifyDecodeResultOkAndGetMessage(decodeResult, inputPacket);
-
-        assertEquals(EXPECTED_IKE_INIT_PAYLOAD_LIST.length, message.ikePayloadList.size());
-        for (int i = 0; i < EXPECTED_IKE_INIT_PAYLOAD_LIST.length; i++) {
-            assertEquals(
-                    EXPECTED_IKE_INIT_PAYLOAD_LIST[i], message.ikePayloadList.get(i).payloadType);
-        }
-    }
-
-    @Test
-    public void testDecodeMessageWithUnsupportedUncriticalPayload() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
-        // Set first payload unsupported uncritical
-        inputPacket[FIRST_PAYLOAD_TYPE_OFFSET] = (byte) 0xff;
-        IkeHeader header = new IkeHeader(inputPacket);
-
-        DecodeResult decodeResult = IkeMessage.decode(0, header, inputPacket);
-
-        IkeMessage message = verifyDecodeResultOkAndGetMessage(decodeResult, inputPacket);
-
-        assertEquals(EXPECTED_IKE_INIT_PAYLOAD_LIST.length - 1, message.ikePayloadList.size());
-        for (int i = 0; i < EXPECTED_IKE_INIT_PAYLOAD_LIST.length - 1; i++) {
-            assertEquals(
-                    EXPECTED_IKE_INIT_PAYLOAD_LIST[i + 1],
-                    message.ikePayloadList.get(i).payloadType);
-        }
-    }
-
-    @Test
-    public void testThrowUnsupportedCriticalPayloadException() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
-        // Set first payload unsupported critical
-        inputPacket[FIRST_PAYLOAD_TYPE_OFFSET] = (byte) 0xff;
-        inputPacket[IkeHeader.IKE_HEADER_LENGTH + PAYLOAD_CRITICAL_BIT_OFFSET] = (byte) 0x80;
-
-        UnsupportedCriticalPayloadException exception =
-                IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(
-                        inputPacket, UnsupportedCriticalPayloadException.class);
-
-        assertEquals(1, exception.payloadTypeList.size());
-    }
-
-    @Test
-    public void testDecodeMessageWithTooShortPayloadLength() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
-        // Set first payload length to 0
-        inputPacket[IkeHeader.IKE_HEADER_LENGTH + FIRST_PAYLOAD_LENGTH_OFFSET] = (byte) 0;
-        inputPacket[IkeHeader.IKE_HEADER_LENGTH + FIRST_PAYLOAD_LENGTH_OFFSET + 1] = (byte) 0;
-
-        IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class);
-    }
-
-    @Test
-    public void testDecodeMessageWithTooLongPayloadLength() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
-        // Increase last payload length by one byte
-        inputPacket[IkeHeader.IKE_HEADER_LENGTH + LAST_PAYLOAD_LENGTH_OFFSET]++;
-
-        IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class);
-    }
-
-    @Test
-    public void testDecodeMessageWithUnexpectedBytesInTheEnd() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET + "0000");
-
-        IkeTestUtils.decodeAndVerifyUnprotectedErrorMsg(inputPacket, InvalidSyntaxException.class);
-    }
-
-    @Test
-    public void testDecodeEncryptedMessage() throws Exception {
-        DecodeResult decodeResult =
-                IkeMessage.decode(
-                        IKE_AUTH_EXPECTED_MESSAGE_ID,
-                        mMockIntegrity,
-                        mMockCipher,
-                        mMockIkeSaRecord,
-                        mIkeAuthHeader,
-                        mIkeAuthPacket,
-                        null /*collectedFragments*/);
-        IkeMessage ikeMessage = verifyDecodeResultOkAndGetMessage(decodeResult, mIkeAuthPacket);
-
-        assertEquals(IKE_AUTH_PAYLOAD_SIZE, ikeMessage.ikePayloadList.size());
-    }
-
-    @Test
-    public void testDecodeEncryptedMessageWithWrongId() throws Exception {
-        DecodeResult decodeResult =
-                IkeMessage.decode(
-                        2,
-                        mMockIntegrity,
-                        mMockCipher,
-                        mMockIkeSaRecord,
-                        mIkeAuthHeader,
-                        mIkeAuthPacket,
-                        null /*collectedFragments*/);
-        IkeException ikeException =
-                verifyDecodeResultErrorAndGetIkeException(
-                        decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket);
-
-        assertTrue(ikeException instanceof InvalidMessageIdException);
-    }
-
-    @Test
-    public void testDecodeEncryptedMessageWithWrongChecksum() throws Exception {
-        when(mMockIntegrity.generateChecksum(any(), any())).thenReturn(new byte[0]);
-
-        DecodeResult decodeResult =
-                IkeMessage.decode(
-                        IKE_AUTH_EXPECTED_MESSAGE_ID,
-                        mMockIntegrity,
-                        mMockCipher,
-                        mMockIkeSaRecord,
-                        mIkeAuthHeader,
-                        mIkeAuthPacket,
-                        null /*collectedFragments*/);
-        IkeException ikeException =
-                verifyDecodeResultErrorAndGetIkeException(
-                        decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket);
-
-        assertTrue(
-                ((IkeInternalException) ikeException).getCause()
-                        instanceof GeneralSecurityException);
-    }
-
-    @Test
-    public void testDecryptFail() throws Exception {
-        when(mMockCipher.decrypt(any(), any(), any())).thenThrow(IllegalBlockSizeException.class);
-
-        DecodeResult decodeResult =
-                IkeMessage.decode(
-                        IKE_AUTH_EXPECTED_MESSAGE_ID,
-                        mMockIntegrity,
-                        mMockCipher,
-                        mMockIkeSaRecord,
-                        mIkeAuthHeader,
-                        mIkeAuthPacket,
-                        null /*collectedFragments*/);
-
-        IkeException ikeException =
-                verifyDecodeResultErrorAndGetIkeException(
-                        decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket);
-        assertTrue(
-                ((IkeInternalException) ikeException).getCause()
-                        instanceof IllegalBlockSizeException);
-    }
-
-    @Test
-    public void testParsingErrorInEncryptedMessage() throws Exception {
-        // Set first payload length to 0
-        byte[] decryptedData =
-                Arrays.copyOfRange(mUnencryptedPaddedData, 0, mUnencryptedPaddedData.length);
-        decryptedData[FIRST_PAYLOAD_LENGTH_OFFSET] = (byte) 0;
-        decryptedData[FIRST_PAYLOAD_LENGTH_OFFSET + 1] = (byte) 0;
-        when(mMockCipher.decrypt(any(), any(), any())).thenReturn(decryptedData);
-
-        DecodeResult decodeResult =
-                IkeMessage.decode(
-                        IKE_AUTH_EXPECTED_MESSAGE_ID,
-                        mMockIntegrity,
-                        mMockCipher,
-                        mMockIkeSaRecord,
-                        mIkeAuthHeader,
-                        mIkeAuthPacket,
-                        null /*collectedFragments*/);
-        IkeException ikeException =
-                verifyDecodeResultErrorAndGetIkeException(
-                        decodeResult, DECODE_STATUS_PROTECTED_ERROR, mIkeAuthPacket);
-
-        assertTrue(ikeException instanceof InvalidSyntaxException);
-    }
-
-    private boolean support(int payloadType) {
-        // Supports all payload typs from 33 to 46
-        return (payloadType >= 33 && payloadType <= 46);
-    }
-
-    @Test
-    public void testAttachEncodedHeader() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(IKE_SA_INIT_RAW_PACKET);
-        byte[] ikeBodyBytes = TestUtils.hexStringToByteArray(IKE_SA_INIT_BODY_RAW_PACKET);
-        IkeHeader header = new IkeHeader(inputPacket);
-        IkeMessage message =
-                ((DecodeResultOk) IkeMessage.decode(0, header, inputPacket)).ikeMessage;
-
-        byte[] encodedIkeMessage = message.attachEncodedHeader(ikeBodyBytes);
-        assertArrayEquals(inputPacket, encodedIkeMessage);
-    }
-
-    @Test
-    public void testEncodeAndEncryptEmptyMsg() throws Exception {
-        when(mMockCipher.generateIv())
-                .thenReturn(TestUtils.hexStringToByteArray(IKE_EMPTY_INFO_MSG_IV_HEX_STRING));
-        when(mMockCipher.encrypt(any(), any(), any()))
-                .thenReturn(
-                        TestUtils.hexStringToByteArray(
-                                IKE_EMPTY_INFO_MSG_ENCRYPTED_DATA_HEX_STRING));
-
-        byte[] checkSum = TestUtils.hexStringToByteArray(IKE_EMPTY_INFO_MSG_CHECKSUM_HEX_STRING);
-        when(mMockIntegrity.getChecksumLen()).thenReturn(checkSum.length);
-        when(mMockIntegrity.generateChecksum(any(), any())).thenReturn(checkSum);
-
-        IkeHeader ikeHeader =
-                new IkeHeader(
-                        INIT_SPI,
-                        RESP_SPI,
-                        IkePayload.PAYLOAD_TYPE_SK,
-                        IkeHeader.EXCHANGE_TYPE_INFORMATIONAL,
-                        true /*isResp*/,
-                        true /*fromInit*/,
-                        0);
-        IkeMessage ikeMessage = new IkeMessage(ikeHeader, new LinkedList<>());
-
-        byte[][] ikeMessageBytes =
-                ikeMessage.encryptAndEncode(
-                        mMockIntegrity,
-                        mMockCipher,
-                        mMockIkeSaRecord,
-                        true /*supportFragment*/,
-                        1280 /*fragSize*/);
-        byte[][] expectedBytes =
-                new byte[][] {TestUtils.hexStringToByteArray(IKE_EMPTY_INFO_MSG_HEX_STRING)};
-
-        assertArrayEquals(expectedBytes, ikeMessageBytes);
-    }
-
-    private DecodeResultPartial makeDecodeResultForFragOne(DecodeResultPartial collectedFrags) {
-        return new DecodeResultPartial(
-                mFragOneHeader,
-                mIkeFragPacketOne,
-                mDummySkfPayloadOne,
-                PAYLOAD_TYPE_AUTH,
-                collectedFrags);
-    }
-
-    private DecodeResultPartial makeDecodeResultForFragTwo(DecodeResultPartial collectedFrags) {
-        return new DecodeResultPartial(
-                mFragTwoHeader,
-                mIkeFragPacketTwo,
-                mDummySkfPayloadTwo,
-                PAYLOAD_TYPE_NO_NEXT,
-                collectedFrags);
-    }
-
-    @Test
-    public void testConstructDecodePartialFirstFragArriveFirst() throws Exception {
-        DecodeResultPartial resultPartial = makeDecodeResultForFragOne(null /*collectedFragments*/);
-
-        assertEquals(PAYLOAD_TYPE_AUTH, resultPartial.firstPayloadType);
-        assertArrayEquals(mIkeFragPacketOne, resultPartial.firstFragBytes);
-        assertEquals(mFragOneHeader, resultPartial.ikeHeader);
-
-        assertEquals(TOTAL_FRAGMENTS, resultPartial.collectedFragsList.length);
-        assertArrayEquals(
-                FRAGMENT_ONE_UNENCRYPTED_DATA,
-                resultPartial.collectedFragsList[FRAGMENT_NUM_ONE - 1]);
-        assertFalse(resultPartial.isAllFragmentsReceived());
-    }
-
-    @Test
-    public void testConstructDecodePartialSecondFragArriveFirst() throws Exception {
-        DecodeResultPartial resultPartial = makeDecodeResultForFragTwo(null /*collectedFragments*/);
-
-        assertEquals(PAYLOAD_TYPE_NO_NEXT, resultPartial.firstPayloadType);
-        assertNull(resultPartial.firstFragBytes);
-        assertEquals(mFragTwoHeader, resultPartial.ikeHeader);
-
-        assertEquals(TOTAL_FRAGMENTS, resultPartial.collectedFragsList.length);
-        assertArrayEquals(
-                FRAGMENT_TWO_UNENCRYPTED_DATA,
-                resultPartial.collectedFragsList[FRAGMENT_NUM_TWO - 1]);
-        assertFalse(resultPartial.isAllFragmentsReceived());
-    }
-
-    @Test
-    public void testConstructDecodeResultPartialWithCollectedFrags() throws Exception {
-        DecodeResultPartial resultPartialIncomplete =
-                makeDecodeResultForFragTwo(null /*collectedFragments*/);
-        DecodeResultPartial resultPartialComplete =
-                makeDecodeResultForFragOne(resultPartialIncomplete);
-
-        assertEquals(PAYLOAD_TYPE_AUTH, resultPartialComplete.firstPayloadType);
-        assertArrayEquals(mIkeFragPacketOne, resultPartialComplete.firstFragBytes);
-        assertEquals(mFragTwoHeader, resultPartialComplete.ikeHeader);
-
-        assertEquals(TOTAL_FRAGMENTS, resultPartialComplete.collectedFragsList.length);
-        assertTrue(resultPartialComplete.isAllFragmentsReceived());
-    }
-
-    @Test
-    public void testReassembleAllFrags() throws Exception {
-        DecodeResultPartial resultPartialIncomplete =
-                makeDecodeResultForFragOne(null /*collectedFragments*/);
-        DecodeResultPartial resultPartialComplete =
-                makeDecodeResultForFragTwo(resultPartialIncomplete);
-
-        assertEquals(PAYLOAD_TYPE_AUTH, resultPartialIncomplete.firstPayloadType);
-        assertArrayEquals(mIkeFragPacketOne, resultPartialIncomplete.firstFragBytes);
-        assertEquals(mFragOneHeader, resultPartialIncomplete.ikeHeader);
-
-        assertEquals(TOTAL_FRAGMENTS, resultPartialIncomplete.collectedFragsList.length);
-        assertTrue(resultPartialIncomplete.isAllFragmentsReceived());
-
-        // Verify reassembly result
-        ByteBuffer expectedBuffer =
-                ByteBuffer.allocate(
-                        FRAGMENT_ONE_UNENCRYPTED_DATA.length
-                                + FRAGMENT_TWO_UNENCRYPTED_DATA.length);
-        expectedBuffer.put(FRAGMENT_ONE_UNENCRYPTED_DATA).put(FRAGMENT_TWO_UNENCRYPTED_DATA);
-
-        byte[] reassembledBytes = resultPartialComplete.reassembleAllFrags();
-        assertArrayEquals(expectedBuffer.array(), reassembledBytes);
-    }
-
-    @Test
-    public void testReassembleIncompleteFragmentsThrows() throws Exception {
-        DecodeResultPartial resultPartial = makeDecodeResultForFragTwo(null /*collectedFragments*/);
-
-        assertFalse(resultPartial.isAllFragmentsReceived());
-
-        try {
-            resultPartial.reassembleAllFrags();
-            fail("Expected to fail because reassembly is not done");
-        } catch (IllegalStateException expected) {
-
-        }
-    }
-
-    private void setDecryptSkfPayload(IkeSkfPayload skf) throws Exception {
-        doReturn(skf)
-                .when(mSpyIkePayloadDecoder)
-                .decodeIkeSkPayload(
-                        eq(true),
-                        anyBoolean(),
-                        any(),
-                        eq(mMockIntegrity),
-                        eq(mMockCipher),
-                        any(),
-                        any());
-    }
-
-    private DecodeResult decodeSkf(
-            int expectedMsgId,
-            IkeHeader header,
-            byte[] packet,
-            DecodeResultPartial collectFragments)
-            throws Exception {
-        return IkeMessage.decode(
-                expectedMsgId,
-                mMockIntegrity,
-                mMockCipher,
-                mMockIkeSaRecord,
-                header,
-                packet,
-                collectFragments);
-    }
-
-    @Test
-    public void testRcvFirstArrivedFrag() throws Exception {
-        setDecryptSkfPayload(mDummySkfPayloadTwo);
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID,
-                        mFragTwoHeader,
-                        mIkeFragPacketTwo,
-                        null /* collectedFragments*/);
-
-        // Verify decoding result
-        assertTrue(decodeResult instanceof DecodeResultPartial);
-        DecodeResultPartial resultPartial = (DecodeResultPartial) decodeResult;
-
-        assertEquals(PAYLOAD_TYPE_NO_NEXT, resultPartial.firstPayloadType);
-        assertNull(resultPartial.firstFragBytes);
-        assertEquals(mFragTwoHeader, resultPartial.ikeHeader);
-
-        assertEquals(TOTAL_FRAGMENTS, resultPartial.collectedFragsList.length);
-        assertArrayEquals(
-                FRAGMENT_TWO_UNENCRYPTED_DATA,
-                resultPartial.collectedFragsList[FRAGMENT_NUM_TWO - 1]);
-        assertFalse(resultPartial.isAllFragmentsReceived());
-    }
-
-    @Test
-    public void testRcvLastArrivedFrag() throws Exception {
-        // Create two dummy SKF Payloads so that the complete unencrypted data is two ID payloads
-        byte[] idInitPayloadBytes = TestUtils.hexStringToByteArray(ID_INIT_PAYLOAD_HEX_STRING);
-        byte[] idRespPayloadBytes = TestUtils.hexStringToByteArray(ID_RESP_PAYLOAD_HEX_STRING);
-        IkeSkfPayload skfOne =
-                makeDummySkfPayload(idInitPayloadBytes, FRAGMENT_NUM_ONE, TOTAL_FRAGMENTS);
-        IkeSkfPayload skfTwo =
-                makeDummySkfPayload(idRespPayloadBytes, FRAGMENT_NUM_TWO, TOTAL_FRAGMENTS);
-
-        DecodeResultPartial resultPartialIncomplete =
-                new DecodeResultPartial(
-                        mFragOneHeader,
-                        mIkeFragPacketOne,
-                        skfOne,
-                        PAYLOAD_TYPE_ID_INITIATOR,
-                        null /* collectedFragments*/);
-
-        setDecryptSkfPayload(skfTwo);
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID,
-                        mFragTwoHeader,
-                        mIkeFragPacketTwo,
-                        resultPartialIncomplete);
-
-        // Verify fragments reassembly has been finished and complete message has been decoded.
-        assertTrue(decodeResult instanceof DecodeResultOk);
-        DecodeResultOk resultOk = (DecodeResultOk) decodeResult;
-        assertArrayEquals(mIkeFragPacketOne, resultOk.firstPacket);
-        assertEquals(2, resultOk.ikeMessage.ikePayloadList.size());
-    }
-
-    @Test
-    public void testRcvFirstArrivedFragWithUnprotectedError() throws Exception {
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID + 1,
-                        mFragTwoHeader,
-                        mIkeFragPacketTwo,
-                        null /* collectedFragments*/);
-
-        // Verify that unprotected error was returned
-        IkeException ikeException =
-                verifyDecodeResultErrorAndGetIkeException(
-                        decodeResult, DECODE_STATUS_UNPROTECTED_ERROR, mIkeAuthPacket);
-        assertTrue(ikeException instanceof InvalidMessageIdException);
-    }
-
-    @Test
-    public void testRcvLastArrivedFragWithUnprotectedError() throws Exception {
-        DecodeResultPartial resultPartialIncomplete =
-                makeDecodeResultForFragOne(null /* collectedFragments*/);
-
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID + 1,
-                        mFragTwoHeader,
-                        mIkeFragPacketTwo,
-                        resultPartialIncomplete);
-
-        // Verify that newly received fragment was discarded
-        assertEquals(resultPartialIncomplete, decodeResult);
-    }
-
-    @Test
-    public void testRcvFragWithLargerTotalFragments() throws Exception {
-        DecodeResultPartial resultPartialIncomplete =
-                new DecodeResultPartial(
-                        mFragOneHeader,
-                        mIkeFragPacketOne,
-                        mDummySkfPayloadOne,
-                        PAYLOAD_TYPE_NO_NEXT,
-                        null /* collectedFragments*/);
-
-        // Set total fragments of inbound fragment to 5
-        int totalFragments = 5;
-        byte[] fragPacket = makeFragmentBytes(2 /*fragNum*/, totalFragments);
-
-        byte[] unencryptedData = "testRcvFragWithLargerTotalFragments".getBytes();
-        IkeSkfPayload skfPayload =
-                makeDummySkfPayload(unencryptedData, FRAGMENT_NUM_TWO, totalFragments);
-        setDecryptSkfPayload(skfPayload);
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID,
-                        mFragTwoHeader,
-                        fragPacket,
-                        resultPartialIncomplete);
-
-        // Verify that previously collected fragments were all discarded
-        assertTrue(decodeResult instanceof DecodeResultPartial);
-        DecodeResultPartial resultPartial = (DecodeResultPartial) decodeResult;
-
-        assertEquals(PAYLOAD_TYPE_NO_NEXT, resultPartial.firstPayloadType);
-        assertNull(resultPartial.firstFragBytes);
-        assertEquals(mFragTwoHeader, resultPartial.ikeHeader);
-
-        assertEquals(totalFragments, resultPartial.collectedFragsList.length);
-        assertArrayEquals(unencryptedData, resultPartial.collectedFragsList[FRAGMENT_NUM_TWO - 1]);
-        assertFalse(resultPartial.isAllFragmentsReceived());
-    }
-
-    @Test
-    public void testRcvFragWithSmallerTotalFragments() throws Exception {
-        int totalFragments = 5;
-        byte[] unencryptedData = "testRcvFragWithSmallerTotalFragments".getBytes();
-        IkeSkfPayload skfPayload =
-                makeDummySkfPayload(unencryptedData, FRAGMENT_NUM_ONE, totalFragments);
-
-        DecodeResultPartial resultPartialIncomplete =
-                new DecodeResultPartial(
-                        mFragOneHeader,
-                        mIkeFragPacketOne,
-                        skfPayload,
-                        PAYLOAD_TYPE_AUTH,
-                        null /* collectedFragments*/);
-
-        setDecryptSkfPayload(mDummySkfPayloadTwo);
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID,
-                        mFragTwoHeader,
-                        mIkeFragPacketTwo,
-                        resultPartialIncomplete);
-
-        // Verify that newly received fragment was discarded
-        assertEquals(resultPartialIncomplete, decodeResult);
-    }
-
-    @Test
-    public void testRcvReplayFrag() throws Exception {
-        DecodeResultPartial resultPartialIncomplete =
-                makeDecodeResultForFragTwo(null /* collectedFragments*/);
-
-        setDecryptSkfPayload(mDummySkfPayloadTwo);
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_FRAG_EXPECTED_MESSAGE_ID,
-                        mFragTwoHeader,
-                        mIkeFragPacketTwo,
-                        resultPartialIncomplete);
-
-        // Verify that newly received fragment was discarded
-        assertEquals(resultPartialIncomplete, decodeResult);
-    }
-
-    @Test
-    public void testRcvCompleteMessageDuringReassembly() throws Exception {
-        DecodeResultPartial resultPartialIncomplete =
-                makeDecodeResultForFragTwo(null /* collectedFragments*/);
-
-        DecodeResult decodeResult =
-                decodeSkf(
-                        IKE_AUTH_EXPECTED_MESSAGE_ID,
-                        mIkeAuthHeader,
-                        mIkeAuthPacket,
-                        resultPartialIncomplete);
-
-        // Verify that newly received IKE message was discarded
-        assertEquals(resultPartialIncomplete, decodeResult);
-    }
-
-    @Test
-    public void testEncodeAndEncryptFragments() throws Exception {
-        int messageId = 1;
-        int fragSize = 140;
-        int expectedTotalFragments = 3;
-
-        byte[] integrityKey = new byte[0];
-        byte[] encryptionKey = new byte[0];
-        byte[] iv = new byte[IKE_AUTH_CIPHER_IV_SIZE];
-
-        when(mMockCipher.generateIv()).thenReturn(iv);
-        when(mMockCipher.encrypt(any(), any(), any()))
-                .thenAnswer(
-                        (invocation) -> {
-                            return (byte[]) invocation.getArguments()[0];
-                        });
-
-        IkeHeader ikeHeader =
-                new IkeHeader(
-                        INIT_SPI,
-                        RESP_SPI,
-                        IkePayload.PAYLOAD_TYPE_SK,
-                        IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                        true /*isResp*/,
-                        false /*fromInit*/,
-                        messageId);
-
-        byte[][] packetList =
-                new IkeMessage.IkeMessageHelper()
-                        .encryptAndEncode(
-                                ikeHeader,
-                                IkePayload.PAYLOAD_TYPE_AUTH,
-                                mUnencryptedPaddedData,
-                                mMockIntegrity,
-                                mMockCipher,
-                                integrityKey,
-                                encryptionKey,
-                                true /*supportFragment*/,
-                                fragSize);
-
-        assertEquals(expectedTotalFragments, packetList.length);
-
-        IkeHeader expectedIkeHeader =
-                new IkeHeader(
-                        INIT_SPI,
-                        RESP_SPI,
-                        IkePayload.PAYLOAD_TYPE_SKF,
-                        IkeHeader.EXCHANGE_TYPE_IKE_AUTH,
-                        true /*isResp*/,
-                        false /*fromInit*/,
-                        messageId);
-        for (int i = 0; i < packetList.length; i++) {
-            byte[] p = packetList[i];
-
-            // Verify fragment length
-            assertNotNull(p);
-            assertTrue(p.length <= fragSize);
-
-            ByteBuffer packetBuffer = ByteBuffer.wrap(p);
-
-            // Verify IKE header
-            byte[] headerBytes = new byte[IkeHeader.IKE_HEADER_LENGTH];
-            packetBuffer.get(headerBytes);
-
-            ByteBuffer expectedHeadBuffer = ByteBuffer.allocate(IkeHeader.IKE_HEADER_LENGTH);
-            expectedIkeHeader.encodeToByteBuffer(
-                    expectedHeadBuffer, p.length - IkeHeader.IKE_HEADER_LENGTH);
-
-            assertArrayEquals(expectedHeadBuffer.array(), headerBytes);
-
-            // Verify fragment payload header
-            packetBuffer.get(new byte[IkePayload.GENERIC_HEADER_LENGTH]);
-            assertEquals(i + 1 /*expetced fragNum*/, Short.toUnsignedInt(packetBuffer.getShort()));
-            assertEquals(expectedTotalFragments, Short.toUnsignedInt(packetBuffer.getShort()));
-        }
-
-        verify(mMockCipher, times(expectedTotalFragments + 1))
-                .encrypt(any(), eq(encryptionKey), eq(iv));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayloadTest.java
deleted file mode 100644
index 884c76e..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeNotifyPayloadTest.java
+++ /dev/null
@@ -1,249 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_INVALID_KE_PAYLOAD;
-import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import android.net.ipsec.ike.SaProposal;
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.exceptions.AuthenticationFailedException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidKeException;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.exceptions.UnrecognizedIkeProtocolException;
-
-import org.junit.Test;
-
-import java.net.InetAddress;
-import java.nio.ByteBuffer;
-
-public final class IkeNotifyPayloadTest {
-    private static final String NOTIFY_NAT_DETECTION_PAYLOAD_HEX_STRING =
-            "2900001c00004004e54f73b7d83f6beb881eab2051d8663f421d10b0";
-    private static final String NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING =
-            "00004004e54f73b7d83f6beb881eab2051d8663f421d10b0";
-    private static final String NAT_DETECTION_DATA_HEX_STRING =
-            "e54f73b7d83f6beb881eab2051d8663f421d10b0";
-
-    private static final String NOTIFY_REKEY_PAYLOAD_BODY_HEX_STRING = "030440092ad4c0a2";
-    private static final int REKEY_SPI = 0x2ad4c0a2;
-
-    private static final String IKE_INITIATOR_SPI_HEX_STRING = "5f54bf6d8b48e6e1";
-    private static final String IKE_RESPODNER_SPI_HEX_STRING = "0000000000000000";
-    private static final String IP_ADDR = "10.80.80.13";
-    private static final int PORT = 500;
-
-    private static final int PROTOCOL_ID_OFFSET = 0;
-
-    @Test
-    public void testDecodeNotifyPayloadSpiUnset() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING);
-        byte[] notifyData = TestUtils.hexStringToByteArray(NAT_DETECTION_DATA_HEX_STRING);
-
-        IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
-        assertEquals(IkePayload.PROTOCOL_ID_UNSET, payload.protocolId);
-        assertEquals(IkePayload.SPI_LEN_NOT_INCLUDED, payload.spiSize);
-        assertEquals(IkeNotifyPayload.NOTIFY_TYPE_NAT_DETECTION_SOURCE_IP, payload.notifyType);
-        assertEquals(IkePayload.SPI_NOT_INCLUDED, payload.spi);
-        assertArrayEquals(notifyData, payload.notifyData);
-    }
-
-    @Test
-    public void testDecodeNotifyPayloadSpiSet() throws Exception {
-        byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_REKEY_PAYLOAD_BODY_HEX_STRING);
-
-        IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
-        assertEquals(IkePayload.PROTOCOL_ID_ESP, payload.protocolId);
-        assertEquals(IkePayload.SPI_LEN_IPSEC, payload.spiSize);
-        assertEquals(IkeNotifyPayload.NOTIFY_TYPE_REKEY_SA, payload.notifyType);
-        assertEquals(REKEY_SPI, payload.spi);
-        assertArrayEquals(new byte[0], payload.notifyData);
-    }
-
-    @Test
-    public void testDecodeNotifyPayloadThrowException() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING);
-        // Change Protocol ID to ESP
-        inputPacket[PROTOCOL_ID_OFFSET] = (byte) (IkePayload.PROTOCOL_ID_ESP & 0xFF);
-        try {
-            IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
-            fail("Expected InvalidSyntaxException: Protocol ID should not be ESP");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testGenerateNatDetectionData() throws Exception {
-        long initiatorIkeSpi = Long.parseLong(IKE_INITIATOR_SPI_HEX_STRING, 16);
-        long responderIkespi = Long.parseLong(IKE_RESPODNER_SPI_HEX_STRING, 16);
-        InetAddress inetAddress = InetAddress.getByName(IP_ADDR);
-
-        byte[] netDetectionData =
-                IkeNotifyPayload.generateNatDetectionData(
-                        initiatorIkeSpi, responderIkespi, inetAddress, PORT);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(NAT_DETECTION_DATA_HEX_STRING);
-        assertArrayEquals(expectedBytes, netDetectionData);
-    }
-
-    @Test
-    public void testBuildIkeErrorNotifyWithData() throws Exception {
-        int payloadType = 1;
-        IkeNotifyPayload notifyPayload =
-                new IkeNotifyPayload(
-                        IkeProtocolException.ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD,
-                        new byte[] {(byte) payloadType});
-
-        assertArrayEquals(new byte[] {(byte) payloadType}, notifyPayload.notifyData);
-        assertTrue(notifyPayload.isErrorNotify());
-        assertFalse(notifyPayload.isNewChildSaNotify());
-    }
-
-    @Test
-    public void testBuildIkeErrorNotifyWithoutData() throws Exception {
-        IkeNotifyPayload notifyPayload =
-                new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_INVALID_SYNTAX);
-
-        assertArrayEquals(new byte[0], notifyPayload.notifyData);
-        assertTrue(notifyPayload.isErrorNotify());
-        assertFalse(notifyPayload.isNewChildSaNotify());
-    }
-
-    @Test
-    public void testBuildChildConfigNotify() throws Exception {
-        IkeNotifyPayload notifyPayload =
-                new IkeNotifyPayload(IkeNotifyPayload.NOTIFY_TYPE_USE_TRANSPORT_MODE);
-
-        assertArrayEquals(new byte[0], notifyPayload.notifyData);
-        assertFalse(notifyPayload.isErrorNotify());
-        assertTrue(notifyPayload.isNewChildSaNotify());
-    }
-
-    @Test
-    public void testBuildChildErrorNotify() throws Exception {
-        IkeNotifyPayload notifyPayload =
-                new IkeNotifyPayload(IkeProtocolException.ERROR_TYPE_INTERNAL_ADDRESS_FAILURE);
-
-        assertArrayEquals(new byte[0], notifyPayload.notifyData);
-        assertTrue(notifyPayload.isErrorNotify());
-        assertTrue(notifyPayload.isNewChildSaNotify());
-    }
-
-    @Test
-    public void testEncodeNotifyPayload() throws Exception {
-        byte[] inputPacket =
-                TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_BODY_HEX_STRING);
-        IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(payload.getPayloadLength());
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NOTIFY, byteBuffer);
-
-        byte[] expectedNoncePayload =
-                TestUtils.hexStringToByteArray(NOTIFY_NAT_DETECTION_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedNoncePayload, byteBuffer.array());
-    }
-
-    @Test
-    public void testValidateAndBuildIkeExceptionWithData() throws Exception {
-        // Invalid Message ID
-        byte[] dhGroup = new byte[] {(byte) 0x00, (byte) 0x0e};
-        int expectedDhGroup = SaProposal.DH_GROUP_2048_BIT_MODP;
-
-        IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_INVALID_KE_PAYLOAD, dhGroup);
-        IkeProtocolException exception = payload.validateAndBuildIkeException();
-
-        assertTrue(exception instanceof InvalidKeException);
-        assertEquals(ERROR_TYPE_INVALID_KE_PAYLOAD, exception.getErrorType());
-        assertArrayEquals(dhGroup, exception.getErrorData());
-        assertEquals(expectedDhGroup, ((InvalidKeException) exception).getDhGroup());
-    }
-
-    @Test
-    public void testValidateAndBuildIkeExceptionWithoutData() throws Exception {
-        // Invalid Syntax
-        IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED);
-        IkeProtocolException exception = payload.validateAndBuildIkeException();
-
-        assertTrue(exception instanceof AuthenticationFailedException);
-        assertEquals(ERROR_TYPE_AUTHENTICATION_FAILED, exception.getErrorType());
-        assertArrayEquals(new byte[0], exception.getErrorData());
-    }
-
-    @Test
-    public void testValidateAndBuildUnrecognizedIkeException() throws Exception {
-        int unrecognizedType = 0;
-        IkeNotifyPayload payload = new IkeNotifyPayload(unrecognizedType);
-        IkeProtocolException exception = payload.validateAndBuildIkeException();
-
-        assertTrue(exception instanceof UnrecognizedIkeProtocolException);
-        assertEquals(unrecognizedType, exception.getErrorType());
-        assertArrayEquals(new byte[0], exception.getErrorData());
-    }
-
-    @Test
-    public void testValidateAndBuildIkeExceptionWithInvalidPayload() throws Exception {
-        // Build a invalid notify payload
-        IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_UNSUPPORTED_CRITICAL_PAYLOAD);
-
-        try {
-            payload.validateAndBuildIkeException();
-            fail("Expected to fail due to invalid error data");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testBuildIkeExceptionWithStatusNotify() throws Exception {
-        // Rekey notification
-        byte[] inputPacket = TestUtils.hexStringToByteArray(NOTIFY_REKEY_PAYLOAD_BODY_HEX_STRING);
-        IkeNotifyPayload payload = new IkeNotifyPayload(false, inputPacket);
-
-        assertFalse(payload.isErrorNotify());
-
-        try {
-            payload.validateAndBuildIkeException();
-            fail("Expected to fail because it is not error notification");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testGetNotifyTypeString() throws Exception {
-        IkeNotifyPayload payload = new IkeNotifyPayload(ERROR_TYPE_AUTHENTICATION_FAILED);
-
-        assertEquals("Notify(Authentication failed)", payload.getTypeString());
-    }
-
-    @Test
-    public void testGetNotifyTypeStringForUnrecoginizedNotify() throws Exception {
-        int unrecognizedType = 0;
-        IkeNotifyPayload payload = new IkeNotifyPayload(unrecognizedType);
-
-        assertEquals("Notify(0)", payload.getTypeString());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayloadTest.java
deleted file mode 100644
index 3374a7d..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeSkfPayloadTest.java
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.spy;
-
-import android.net.ipsec.ike.SaProposal;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.crypto.IkeCipher;
-import com.android.internal.net.ipsec.ike.crypto.IkeMacIntegrity;
-import com.android.internal.net.ipsec.ike.crypto.IkeNormalModeCipher;
-import com.android.internal.net.ipsec.ike.exceptions.InvalidSyntaxException;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.EncryptionTransform;
-import com.android.internal.net.ipsec.ike.message.IkeSaPayload.IntegrityTransform;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-public final class IkeSkfPayloadTest {
-    private static final String IKE_FRAG_MSG_HEX_STRING =
-            "bb3d5237aa558779db24aeb6c9ea183e352023200000000100000134"
-                    + "0000011800020002c1471fc7714a3b77a2bfd78dd2df4c048dfed913"
-                    + "c5de76cb1f4463ef541df2442b43c65308a47b873502268cc1195f99"
-                    + "4f6f1a945f56cb342969936af97d79c560c8e0f8bb1a0874ebfb5d0e"
-                    + "610b0fcff96d4197c06e7aef07a3a9ae487555bec95c78b87fe6483c"
-                    + "be07e3d132f8594c34dba5b5b463b871d0272af6a1ee701fc6b7b70a"
-                    + "22a1b8f63eed50ce6b2253ee63fe2cf0289a5eb715e56b389f72b5ba"
-                    + "ecfb7340f4abf9253a8c973d281ed62f3516d130fcaaf2c2145b3047"
-                    + "f3a243e60beb2fc28bf05183839caf46bfbfc4f28c9a2224e7d49686"
-                    + "52a236a403ecb203a1de1e2144a6f5ce28acc2f93989608af17381fc"
-                    + "f965cabe1a448274264b22167abfa047dc88e4bfdc5a492847d36d8b";
-
-    private static final String IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING =
-            "dc89d82f4fccff8d3f0c4f4848571e57205f7dbdce954203983d2147"
-                    + "3a9e10ba36876b860d33afbdfe6ebf000240e31f2039f4213e882d1f"
-                    + "6f0a24887aed0584f4b50a016d989990fd58297757c7b842cd72b57c"
-                    + "2f68cba8a5f06d899ce3fcfbd0419402a1d59f1c5b5b23bd0a4ed525"
-                    + "27ed6cef9fd238552fcf6e4cd9f794d2b01ba61438fd21714fbc3e3f"
-                    + "443a816751e55d46009ae7fb9f52db0977e453a2d28b0453a9393778"
-                    + "3a0b625c27d186c052a7169807537d97e731a3543fc10dca605ca86d"
-                    + "1496882e1d009a9216d07d0000001801850014120a00000f02000200"
-                    + "0100000d010000";
-
-    private static final String IKE_FRAG_MSG_CHECKSUM = "7abfa047dc88e4bfdc5a492847d36d8b";
-    private static final String IKE_FRAG_MSG_PADDING = "05d925c1b3804aee08";
-
-    private static final int FRAGMENT_NUM = 2;
-    private static final int TOTAL_FRAGMENTS = 2;
-
-    private static final int FRAGMENT_NUM_OFFSET =
-            IkeHeader.IKE_HEADER_LENGTH + IkePayload.GENERIC_HEADER_LENGTH;
-    private static final int TOTAL_FRAGMENTS_OFFET = FRAGMENT_NUM_OFFSET + 2;
-
-    private byte[] mDecryptedData;
-
-    private IkeMacIntegrity mSpyHmacSha256IntegrityMac;
-    private IkeNormalModeCipher mSpyAesCbcCipher;
-
-    @Before
-    public void setUp() throws Exception {
-        mDecryptedData = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING);
-
-        // Set up integrity algorithm
-        mSpyHmacSha256IntegrityMac =
-                spy(
-                        IkeMacIntegrity.create(
-                                new IntegrityTransform(
-                                        SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128),
-                                IkeMessage.getSecurityProvider()));
-        byte[] expectedChecksum = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_CHECKSUM);
-        doReturn(expectedChecksum).when(mSpyHmacSha256IntegrityMac).generateChecksum(any(), any());
-
-        // Set up encryption algorithm
-        mSpyAesCbcCipher =
-                spy(
-                        (IkeNormalModeCipher)
-                                IkeCipher.create(
-                                        new EncryptionTransform(
-                                                SaProposal.ENCRYPTION_ALGORITHM_AES_CBC,
-                                                SaProposal.KEY_LEN_AES_128),
-                                        IkeMessage.getSecurityProvider()));
-        byte[] expectedDecryptedPaddedData =
-                TestUtils.hexStringToByteArray(
-                        IKE_FRAG_MSG_DECRYPTED_BODY_HEX_STRING + IKE_FRAG_MSG_PADDING);
-        doReturn(expectedDecryptedPaddedData).when(mSpyAesCbcCipher).decrypt(any(), any(), any());
-    }
-
-    private IkeSkfPayload decodeAndDecryptFragMsg(byte[] message) throws Exception {
-        IkeSkfPayload payload =
-                (IkeSkfPayload)
-                        IkePayloadFactory.getIkeSkPayload(
-                                        true /*isSkf*/,
-                                        message,
-                                        mSpyHmacSha256IntegrityMac,
-                                        mSpyAesCbcCipher,
-                                        new byte[0] /*integrityKey*/,
-                                        new byte[0] /*decryptionKey*/)
-                                .first;
-        return payload;
-    }
-
-    @Test
-    public void testDecode() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);
-
-        IkeSkfPayload payload = decodeAndDecryptFragMsg(message);
-
-        assertEquals(IkePayload.PAYLOAD_TYPE_SKF, payload.payloadType);
-        assertEquals(FRAGMENT_NUM, payload.fragmentNum);
-        assertEquals(TOTAL_FRAGMENTS, payload.totalFragments);
-        assertArrayEquals(mDecryptedData, payload.getUnencryptedData());
-    }
-
-    @Test
-    public void testDecodeThrowsForZeroFragNum() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);
-
-        // Set Fragment Number to zero
-        message[FRAGMENT_NUM_OFFSET] = 0;
-        message[FRAGMENT_NUM_OFFSET + 1] = 0;
-
-        try {
-            decodeAndDecryptFragMsg(message);
-            fail("Expected to fail because Fragment Number is zero.");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeThrowsForZeroTotalFragments() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);
-
-        // Set Total Fragments Number to zero
-        message[TOTAL_FRAGMENTS_OFFET] = 0;
-        message[TOTAL_FRAGMENTS_OFFET + 1] = 0;
-
-        try {
-            decodeAndDecryptFragMsg(message);
-            fail("Expected to fail because Total Fragments Number is zero.");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testDecodeThrowsWhenFragNumIsLargerThanTotalFragments() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);
-
-        // Set Fragment Number to 5
-        message[FRAGMENT_NUM_OFFSET] = 0;
-        message[FRAGMENT_NUM_OFFSET + 1] = 5;
-
-        // Set Total Fragments Number to 2
-        message[TOTAL_FRAGMENTS_OFFET] = 0;
-        message[TOTAL_FRAGMENTS_OFFET + 1] = 2;
-
-        try {
-            decodeAndDecryptFragMsg(message);
-            fail(
-                    "Expected to fail because Fragment Number is larger than"
-                            + " Total Fragments Number");
-        } catch (InvalidSyntaxException expected) {
-        }
-    }
-
-    @Test
-    public void testEncode() throws Exception {
-        byte[] message = TestUtils.hexStringToByteArray(IKE_FRAG_MSG_HEX_STRING);
-        IkeSkfPayload payload = decodeAndDecryptFragMsg(message);
-
-        int payloadLength = payload.getPayloadLength();
-        ByteBuffer buffer = ByteBuffer.allocate(payloadLength);
-        payload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_NO_NEXT, buffer);
-
-        byte[] expectedPayloadBytes =
-                Arrays.copyOfRange(message, IkeHeader.IKE_HEADER_LENGTH, message.length);
-        assertArrayEquals(expectedPayloadBytes, buffer.array());
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTestUtils.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTestUtils.java
deleted file mode 100644
index 0547437..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTestUtils.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static com.android.internal.net.ipsec.ike.message.IkeMessage.DECODE_STATUS_UNPROTECTED_ERROR;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.net.ipsec.ike.exceptions.IkeProtocolException;
-import android.util.Pair;
-
-import com.android.internal.net.TestUtils;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResult;
-import com.android.internal.net.ipsec.ike.message.IkeMessage.DecodeResultError;
-
-import java.nio.ByteBuffer;
-
-/**
- * IkeTestUtils provides utility methods for testing IKE library.
- *
- * <p>TODO: Consider moving it under ikev2/
- */
-public final class IkeTestUtils {
-    public static IkePayload hexStringToIkePayload(
-            @IkePayload.PayloadType int payloadType, boolean isResp, String payloadHexString)
-            throws IkeProtocolException {
-        byte[] payloadBytes = TestUtils.hexStringToByteArray(payloadHexString);
-        // Returned Pair consists of the IkePayload and the following IkePayload's type.
-        Pair<IkePayload, Integer> pair =
-                IkePayloadFactory.getIkePayload(payloadType, isResp, ByteBuffer.wrap(payloadBytes));
-        return pair.first;
-    }
-
-    public static <T extends IkeProtocolException> T decodeAndVerifyUnprotectedErrorMsg(
-            byte[] inputPacket, Class<T> expectedException) throws Exception {
-        IkeHeader header = new IkeHeader(inputPacket);
-        DecodeResult decodeResult = IkeMessage.decode(0, header, inputPacket);
-
-        assertEquals(DECODE_STATUS_UNPROTECTED_ERROR, decodeResult.status);
-        DecodeResultError resultError = (DecodeResultError) decodeResult;
-        assertNotNull(resultError.ikeException);
-        assertTrue(expectedException.isInstance(resultError.ikeException));
-
-        return (T) resultError.ikeException;
-    }
-
-    public static IkeSkfPayload makeDummySkfPayload(
-            byte[] unencryptedData, int fragNum, int totalFrags) throws Exception {
-        IkeEncryptedPayloadBody mockEncryptedBody = mock(IkeEncryptedPayloadBody.class);
-        when(mockEncryptedBody.getUnencryptedData()).thenReturn(unencryptedData);
-        return new IkeSkfPayload(mockEncryptedBody, fragNum, totalFrags);
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayloadTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayloadTest.java
deleted file mode 100644
index cbd6f93..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/message/IkeTsPayloadTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.message;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import android.net.ipsec.ike.IkeTrafficSelector;
-
-import com.android.internal.net.TestUtils;
-
-import libcore.net.InetAddressUtils;
-
-import org.junit.Test;
-
-import java.net.Inet4Address;
-import java.nio.ByteBuffer;
-
-public final class IkeTsPayloadTest {
-    private static final String TS_INITIATOR_PAYLOAD_HEX_STRING =
-            "2d00002802000000070000100010fff0c0000264c0000365070000100000ffffc0000464c0000466";
-
-    private static final int NUMBER_OF_TS = 2;
-
-    private static final int TS_ONE_START_PORT = 16;
-    private static final int TS_ONE_END_PORT = 65520;
-    private static final Inet4Address TS_ONE_START_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.100"));
-    private static final Inet4Address TS_ONE_END_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.3.101"));
-
-    private static final int TS_TWO_START_PORT = 0;
-    private static final int TS_TWO_END_PORT = 65535;
-    private static final Inet4Address TS_TWO_START_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.100"));
-    private static final Inet4Address TS_TWO_END_ADDRESS =
-            (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.4.102"));
-
-    private IkeTrafficSelector mTsOne;
-    private IkeTrafficSelector mTsTwo;
-
-    public IkeTsPayloadTest() {
-        mTsOne =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT,
-                        TS_ONE_END_PORT,
-                        TS_ONE_START_ADDRESS,
-                        TS_ONE_END_ADDRESS);
-        mTsTwo =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_TWO_START_PORT,
-                        TS_TWO_END_PORT,
-                        TS_TWO_START_ADDRESS,
-                        TS_TWO_END_ADDRESS);
-    }
-
-    @Test
-    public void testDecodeTsInitiatorPayload() throws Exception {
-        ByteBuffer inputBuffer =
-                ByteBuffer.wrap(TestUtils.hexStringToByteArray(TS_INITIATOR_PAYLOAD_HEX_STRING));
-
-        IkePayload payload =
-                IkePayloadFactory.getIkePayload(
-                                IkePayload.PAYLOAD_TYPE_TS_INITIATOR, false, inputBuffer)
-                        .first;
-        assertTrue(payload instanceof IkeTsPayload);
-
-        IkeTsPayload tsPayload = (IkeTsPayload) payload;
-        assertEquals(IkePayload.PAYLOAD_TYPE_TS_INITIATOR, tsPayload.payloadType);
-        assertEquals(NUMBER_OF_TS, tsPayload.numTs);
-    }
-
-    @Test
-    public void testBuildAndEncodeTsPayload() throws Exception {
-        IkeTsPayload tsPayload =
-                new IkeTsPayload(true /*isInitiator*/, new IkeTrafficSelector[] {mTsOne, mTsTwo});
-
-        ByteBuffer byteBuffer = ByteBuffer.allocate(tsPayload.getPayloadLength());
-        tsPayload.encodeToByteBuffer(IkePayload.PAYLOAD_TYPE_TS_RESPONDER, byteBuffer);
-
-        byte[] expectedBytes = TestUtils.hexStringToByteArray(TS_INITIATOR_PAYLOAD_HEX_STRING);
-        assertArrayEquals(expectedBytes, byteBuffer.array());
-    }
-
-    @Test
-    public void testContains() throws Exception {
-        IkeTrafficSelector tsOneNarrowPortRange =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT + 1,
-                        TS_ONE_END_PORT,
-                        TS_ONE_START_ADDRESS,
-                        TS_ONE_END_ADDRESS);
-
-        IkeTrafficSelector tsOneNarrowAddressRange =
-                new IkeTrafficSelector(
-                        IkeTrafficSelector.TRAFFIC_SELECTOR_TYPE_IPV4_ADDR_RANGE,
-                        TS_ONE_START_PORT,
-                        TS_ONE_END_PORT,
-                        (Inet4Address) (InetAddressUtils.parseNumericAddress("192.0.2.200")),
-                        TS_ONE_END_ADDRESS);
-
-        IkeTsPayload tsPayload =
-                new IkeTsPayload(true /*isInitiator*/, new IkeTrafficSelector[] {mTsOne, mTsTwo});
-
-        IkeTsPayload tsNarrowPortRangePayload =
-                new IkeTsPayload(
-                        true /*isInitiator*/,
-                        new IkeTrafficSelector[] {tsOneNarrowPortRange, mTsTwo});
-
-        IkeTsPayload tsNarrowAddressRangePayload =
-                new IkeTsPayload(
-                        true /*isInitiator*/,
-                        new IkeTrafficSelector[] {tsOneNarrowAddressRange, mTsTwo});
-
-        assertTrue(tsPayload.contains(tsPayload));
-        assertTrue(tsPayload.contains(tsNarrowPortRangePayload));
-        assertTrue(tsPayload.contains(tsNarrowAddressRangePayload));
-
-        assertFalse(tsNarrowPortRangePayload.contains(tsPayload));
-        assertFalse(tsNarrowAddressRangePayload.contains(tsPayload));
-        assertFalse(tsNarrowAddressRangePayload.contains(tsNarrowPortRangePayload));
-        assertFalse(tsNarrowPortRangePayload.contains(tsNarrowAddressRangePayload));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/CertUtils.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/CertUtils.java
deleted file mode 100644
index db128c8..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/CertUtils.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.testutils;
-
-import android.content.Context;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-import com.android.org.bouncycastle.util.io.pem.PemObject;
-import com.android.org.bouncycastle.util.io.pem.PemReader;
-
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.security.KeyFactory;
-import java.security.cert.CertificateFactory;
-import java.security.cert.X509Certificate;
-import java.security.interfaces.RSAPrivateKey;
-import java.security.spec.PKCS8EncodedKeySpec;
-
-/** CertUtils provides utility methods for creating X509 certificate and private key. */
-public final class CertUtils {
-    private static final String PEM_FOLDER_NAME = "pem";
-    private static final String KEY_FOLDER_NAME = "key";
-
-    /** Creates an X509Certificate with a pem file */
-    public static X509Certificate createCertFromPemFile(String fileName) throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        InputStream inputStream =
-                context.getResources().getAssets().open(PEM_FOLDER_NAME + "/" + fileName);
-
-        CertificateFactory factory =
-                CertificateFactory.getInstance("X.509", IkeMessage.getSecurityProvider());
-        return (X509Certificate) factory.generateCertificate(inputStream);
-    }
-
-    /** Creates an private key from a PKCS8 format key file */
-    public static RSAPrivateKey createRsaPrivateKeyFromKeyFile(String fileName) throws Exception {
-        Context context = InstrumentationRegistry.getContext();
-        InputStream inputStream =
-                context.getResources().getAssets().open(KEY_FOLDER_NAME + "/" + fileName);
-
-        PemObject pemObject = new PemReader(new InputStreamReader(inputStream)).readPemObject();
-
-        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
-        return (RSAPrivateKey)
-                keyFactory.generatePrivate(new PKCS8EncodedKeySpec(pemObject.getContent()));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/MockIpSecTestUtils.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/MockIpSecTestUtils.java
deleted file mode 100644
index 742ff24..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/testutils/MockIpSecTestUtils.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.testutils;
-
-import static android.system.OsConstants.AF_INET;
-import static android.system.OsConstants.IPPROTO_UDP;
-import static android.system.OsConstants.SOCK_DGRAM;
-
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.net.IpSecManager;
-import android.net.IpSecSpiResponse;
-import android.net.IpSecUdpEncapResponse;
-import android.system.Os;
-
-import androidx.test.InstrumentationRegistry;
-
-import com.android.server.IpSecService;
-
-/** This class provides utility methods for mocking IPsec surface. */
-public final class MockIpSecTestUtils {
-    private static final int DUMMY_CHILD_SPI = 0x2ad4c0a2;
-    private static final int DUMMY_CHILD_SPI_RESOURCE_ID = 0x1234;
-
-    private static final int DUMMY_UDP_ENCAP_PORT = 34567;
-    private static final int DUMMY_UDP_ENCAP_RESOURCE_ID = 0x3234;
-
-    private Context mContext;
-    private IpSecService mMockIpSecService;
-    private IpSecManager mIpSecManager;
-
-    private MockIpSecTestUtils() throws Exception {
-        mMockIpSecService = mock(IpSecService.class);
-        mContext = InstrumentationRegistry.getContext();
-        mIpSecManager = new IpSecManager(mContext, mMockIpSecService);
-
-        when(mMockIpSecService.allocateSecurityParameterIndex(anyString(), anyInt(), anyObject()))
-                .thenReturn(
-                        new IpSecSpiResponse(
-                                IpSecManager.Status.OK,
-                                DUMMY_CHILD_SPI_RESOURCE_ID,
-                                DUMMY_CHILD_SPI));
-
-        when(mMockIpSecService.openUdpEncapsulationSocket(anyInt(), anyObject()))
-                .thenReturn(
-                        new IpSecUdpEncapResponse(
-                                IpSecManager.Status.OK,
-                                DUMMY_UDP_ENCAP_RESOURCE_ID,
-                                DUMMY_UDP_ENCAP_PORT,
-                                Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)));
-    }
-
-    public static MockIpSecTestUtils setUpMockIpSec() throws Exception {
-        return new MockIpSecTestUtils();
-    }
-
-    public static IpSecSpiResponse buildDummyIpSecSpiResponse(int spi) throws Exception {
-        return new IpSecSpiResponse(IpSecManager.Status.OK, DUMMY_CHILD_SPI_RESOURCE_ID, spi);
-    }
-
-    public Context getContext() {
-        return mContext;
-    }
-
-    public IpSecManager getIpSecManager() {
-        return mIpSecManager;
-    }
-
-    public IpSecService getIpSecService() {
-        return mMockIpSecService;
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java b/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java
deleted file mode 100644
index 1fddb1d..0000000
--- a/tests/iketests/src/java/com/android/internal/net/ipsec/ike/utils/RetransmitterTest.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.ipsec.ike.utils;
-
-import static com.android.internal.net.ipsec.ike.IkeSessionStateMachine.CMD_RETRANSMIT;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.when;
-
-import android.os.Handler;
-import android.os.Message;
-
-import com.android.internal.net.ipsec.ike.message.IkeMessage;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public final class RetransmitterTest {
-    private Handler mMockHandler;
-    private IkeMessage mMockIkeMessage;
-    private TestRetransmitter mRetransmitter;
-
-    private class TestRetransmitter extends Retransmitter {
-        int mSendCallCount; // Defaults to 0
-        boolean mFailed; // Defaults to false
-
-        TestRetransmitter(Handler handler, IkeMessage message) {
-            super(handler, message);
-        }
-
-        @Override
-        public void send(IkeMessage msg) {
-            mSendCallCount++;
-        }
-
-        @Override
-        public void handleRetransmissionFailure() {
-            mFailed = true;
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        mMockHandler = mock(Handler.class);
-        when(mMockHandler.obtainMessage(eq(CMD_RETRANSMIT), anyObject()))
-                .thenReturn(mock(Message.class));
-
-        mMockIkeMessage = mock(IkeMessage.class);
-        mRetransmitter = new TestRetransmitter(mMockHandler, mMockIkeMessage);
-    }
-
-    @Test
-    public void testSendRequestAndQueueRetransmit() throws Exception {
-        mRetransmitter.retransmit();
-        assertEquals(1, mRetransmitter.mSendCallCount);
-        verify(mMockHandler).obtainMessage(eq(CMD_RETRANSMIT), eq(mRetransmitter));
-        verify(mMockHandler)
-                .sendMessageDelayed(any(Message.class), eq(Retransmitter.RETRANSMIT_TIMEOUT_MS));
-    }
-
-    @Test
-    public void testRetransmitQueuesExponentialRetransmit() throws Exception {
-        mRetransmitter.retransmit();
-
-        for (int i = 0; i <= Retransmitter.RETRANSMIT_MAX_ATTEMPTS; i++) {
-            long expectedTimeout =
-                    (long)
-                            (Retransmitter.RETRANSMIT_TIMEOUT_MS
-                                    * Math.pow(Retransmitter.RETRANSMIT_BACKOFF_FACTOR, i));
-
-            assertEquals(i + 1, mRetransmitter.mSendCallCount);
-            assertFalse(mRetransmitter.mFailed);
-
-            // This call happens with the same arguments each time
-            verify(mMockHandler, times(i + 1))
-                    .obtainMessage(eq(CMD_RETRANSMIT), eq(mRetransmitter));
-
-            // But the expected timeout changes every time
-            verify(mMockHandler).sendMessageDelayed(any(Message.class), eq(expectedTimeout));
-
-            verifyNoMoreInteractions(mMockHandler);
-
-            // Trigger next round of retransmissions.
-            mRetransmitter.retransmit();
-        }
-    }
-
-    @Test
-    public void testRetransmitterCallsRetranmissionsFailedOnMaxTries() throws Exception {
-        mRetransmitter.retransmit();
-
-        // Exhaust all retransmit attempts
-        for (int i = 0; i <= Retransmitter.RETRANSMIT_MAX_ATTEMPTS; i++) {
-            mRetransmitter.retransmit();
-        }
-
-        assertTrue(mRetransmitter.mFailed);
-    }
-
-    @Test
-    public void testRetransmitterStopsRetransmitting() throws Exception {
-        mRetransmitter.stopRetransmitting();
-
-        verify(mMockHandler).removeMessages(eq(CMD_RETRANSMIT), eq(mRetransmitter));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/utils/LogTest.java b/tests/iketests/src/java/com/android/internal/net/utils/LogTest.java
deleted file mode 100644
index 23305aa..0000000
--- a/tests/iketests/src/java/com/android/internal/net/utils/LogTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.utils;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class LogTest {
-    private static final String TAG = "IkeLogTest";
-    private static final String PII = "123456789ABCDEF"; // "IMSI"
-    private static final String HEX_STRING = "00112233445566778899AABBCCDDEEFF";
-    private static final byte[] HEX_BYTES = new byte[] {
-            (byte) 0x00, (byte) 0x11, (byte) 0x22, (byte) 0x33, (byte) 0x44, (byte) 0x55,
-            (byte) 0x66, (byte) 0x77, (byte) 0x88, (byte) 0x99, (byte) 0xAA, (byte) 0xBB,
-            (byte) 0xCC, (byte) 0xDD, (byte) 0xEE, (byte) 0xFF
-    };
-
-    @Test
-    public void testPii() {
-        // Log(String tag, boolean isEngBuild, boolean logSensitive);
-        String result = new Log(TAG, false, false).pii(PII);
-        assertEquals(Integer.toString(PII.hashCode()), result);
-
-        result = new Log(TAG,  true, false).pii(PII);
-        assertEquals(Integer.toString(PII.hashCode()), result);
-
-        result = new Log(TAG,  false, true).pii(PII);
-        assertEquals(Integer.toString(PII.hashCode()), result);
-
-        result = new Log(TAG,  true, true).pii(PII);
-        assertEquals(PII, result);
-
-        result = new Log(TAG, true, true).pii(HEX_BYTES);
-        assertEquals(HEX_STRING, result);
-    }
-
-    @Test
-    public void testByteArrayToHexString() {
-        assertEquals("", Log.byteArrayToHexString(null));
-
-        assertEquals("", Log.byteArrayToHexString(new byte[0]));
-
-        assertEquals(HEX_STRING, Log.byteArrayToHexString(HEX_BYTES));
-    }
-}
diff --git a/tests/iketests/src/java/com/android/internal/net/utils/SimpleStateMachineTest.java b/tests/iketests/src/java/com/android/internal/net/utils/SimpleStateMachineTest.java
deleted file mode 100644
index 2ee8dc5..0000000
--- a/tests/iketests/src/java/com/android/internal/net/utils/SimpleStateMachineTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.net.utils;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import com.android.internal.net.utils.SimpleStateMachine.SimpleState;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class SimpleStateMachineTest {
-    private static final String INPUT = "input";
-    private static final String OUTPUT = "output";
-
-    private SimpleStateMachine<String, String> mSimpleStateMachine;
-    private SimpleState mMockStartState;
-    private SimpleState mMockFinalState;
-
-    @Before
-    public void setUp() {
-        mMockStartState = mock(SimpleState.class);
-        mMockFinalState = mock(SimpleState.class);
-
-        mSimpleStateMachine = new SimpleStateMachine(){};
-        mSimpleStateMachine.transitionTo(mMockStartState);
-    }
-
-    @Test
-    public void testProcess() {
-        when(mMockStartState.process(INPUT)).thenReturn(OUTPUT);
-        String result = mSimpleStateMachine.process(INPUT);
-        assertEquals(OUTPUT, result);
-        verify(mMockStartState).process(INPUT);
-    }
-
-    @Test
-    public void testTransitionTo() {
-        mSimpleStateMachine.transitionTo(mMockFinalState);
-        assertEquals(mMockFinalState, mSimpleStateMachine.mState);
-    }
-
-    @Test
-    public void testTransitionToNull() {
-        try {
-            mSimpleStateMachine.transitionTo(null);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testTransitionAndProcess() {
-        when(mMockFinalState.process(INPUT)).thenReturn(OUTPUT);
-        String result = mSimpleStateMachine.transitionAndProcess(mMockFinalState, INPUT);
-        assertEquals(OUTPUT, result);
-        verify(mMockFinalState).process(INPUT);
-    }
-
-    @Test
-    public void testTransitionAndProcessToNull() {
-        try {
-            mSimpleStateMachine.transitionAndProcess(null, INPUT);
-            fail("IllegalArgumentException expected");
-        } catch (IllegalArgumentException expected) {
-        }
-    }
-
-    @Test
-    public void testProcessNullState() {
-        SimpleStateMachine simpleStateMachine = new SimpleStateMachine() {};
-        try {
-            simpleStateMachine.process(new Object());
-            fail("IllegalStateException expected");
-        } catch (IllegalStateException expected) {
-        }
-    }
-}