Merge "Updating allowed keymaster attestation versions"
diff --git a/apps/CtsVerifier/AndroidManifest.xml b/apps/CtsVerifier/AndroidManifest.xml
index 878619d..fccfde0 100644
--- a/apps/CtsVerifier/AndroidManifest.xml
+++ b/apps/CtsVerifier/AndroidManifest.xml
@@ -199,7 +199,7 @@
                 <category android:name="android.cts.intent.category.MANUAL_TEST" />
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_device_admin" />
-            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.software.lockscreen_disabled" />
+            <meta-data android:name="test_excluded_features" android:value="android.hardware.type.automotive:android.hardware.type.television:android.software.lockscreen_disabled" />
             <meta-data android:name="test_required_features"
                     android:value="android.software.device_admin" />
         </activity>
@@ -2188,7 +2188,7 @@
             </intent-filter>
             <meta-data android:name="test_category" android:value="@string/test_category_notifications" />
             <meta-data android:name="test_excluded_features"
-                       android:value="android.hardware.type.watch:android.software.leanback" />
+                       android:value="android.hardware.type.watch:android.software.leanback:android.hardware.type.automotive" />
         </activity>
 
         <activity android:name=".notifications.BubbleActivity"
diff --git a/apps/CtsVerifier/src/com/android/cts/verifier/sensors/OWNERS b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/OWNERS
new file mode 100644
index 0000000..e9e78a3
--- /dev/null
+++ b/apps/CtsVerifier/src/com/android/cts/verifier/sensors/OWNERS
@@ -0,0 +1,4 @@
+# Bug component: 62965
+bduddie@google.com
+stange@google.com
+arthuri@google.com
\ No newline at end of file
diff --git a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
index ac30d80..10364af 100644
--- a/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
+++ b/common/device-side/device-info/src/com/android/compatibility/common/deviceinfo/PackageDeviceInfo.java
@@ -256,3 +256,4 @@
                 .getIdentifier(name, type, "android");
     }
 }
+
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
index 301a626..a5791a2f 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/BlockingBroadcastReceiver.java
@@ -43,7 +43,7 @@
 public class BlockingBroadcastReceiver extends BroadcastReceiver {
     private static final String TAG = "BlockingBroadcast";
 
-    private static final int DEFAULT_TIMEOUT_SECONDS = 10;
+    private static final int DEFAULT_TIMEOUT_SECONDS = 60;
 
     private final BlockingQueue<Intent> mBlockingQueue;
     private final String mExpectedAction;
@@ -68,15 +68,10 @@
 
     /**
      * Wait until the broadcast and return the received broadcast intent. {@code null} is returned
-     * if no broadcast with expected action is received within 10 seconds.
+     * if no broadcast with expected action is received within 60 seconds.
      */
     public @Nullable Intent awaitForBroadcast() {
-        try {
-            return mBlockingQueue.poll(DEFAULT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-        } catch (InterruptedException e) {
-            Log.e(TAG, "waitForBroadcast get interrupted: ", e);
-        }
-        return null;
+        return awaitForBroadcast(DEFAULT_TIMEOUT_SECONDS * 1000);
     }
 
     /**
diff --git a/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
index f8f20c3..119525d 100644
--- a/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ b/common/device-side/util-axt/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
@@ -94,13 +94,15 @@
             }
 
             mReceivedProfileProvisionedIntent =
-                    managedProfileProvisionedReceiver.awaitForBroadcast();
+                    managedProfileProvisionedReceiver.awaitForBroadcast(
+                            TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS));
             if (mReceivedProfileProvisionedIntent == null) {
                 Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
 
-            if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
+            if (managedProfileAddedReceiver.awaitForBroadcast(
+                    TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS)) == null) {
                 Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
diff --git a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
index 05edf1a..59f3ebf 100644
--- a/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
+++ b/common/device-side/util/src/com/android/compatibility/common/util/devicepolicy/provisioning/SilentProvisioningTestManager.java
@@ -93,13 +93,15 @@
             }
 
             mReceivedProfileProvisionedIntent =
-                    managedProfileProvisionedReceiver.awaitForBroadcast();
+                    managedProfileProvisionedReceiver.awaitForBroadcast(
+                            TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS));
             if (mReceivedProfileProvisionedIntent == null) {
                 Log.i(TAG, "managedProfileProvisionedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
 
-            if (managedProfileAddedReceiver.awaitForBroadcast() == null) {
+            if (managedProfileAddedReceiver.awaitForBroadcast(
+                    TimeUnit.SECONDS.toMillis(TIMEOUT_SECONDS)) == null) {
                 Log.i(TAG, "managedProfileAddedReceiver.awaitForBroadcast(): failed");
                 return false;
             }
diff --git a/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp b/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp
index 48ad35a..56e0eab 100644
--- a/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp
+++ b/hostsidetests/appsecurity/test-apps/V3SigningSchemeRotation/Android.bp
@@ -20,6 +20,7 @@
         "cts",
         "vts10",
         "general-tests",
+        "sts",
     ],
     srcs: ["src/**/*.java"],
     sdk_version: "current",
diff --git a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java
index 7fa39b4..d1fc73e 100644
--- a/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java
+++ b/hostsidetests/appsecurity/test-apps/WriteExternalStorageApp/src/com/android/cts/writeexternalstorageapp/ChangeDefaultUris.java
@@ -24,20 +24,22 @@
 import android.test.AndroidTestCase;
 import com.android.compatibility.common.util.FileCopyHelper;
 import java.io.File;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 /** Sets up providers and notifications using external storage. */
 public class ChangeDefaultUris extends AndroidTestCase {
 
     /** Unique title for provider insert and delete. */
     private static final String RINGER_TITLE = "CTS ringer title";
+    private static final int MAX_NUMBER_OF_ATTEMPTS = 10;
 
     public void testChangeDefaultUris() throws Exception {
         File mediaFile =
                 new File(
                         Environment.getExternalStorageDirectory(),
                         "ringer" + System.currentTimeMillis() + ".mp3");
-        FileCopyHelper copier = new FileCopyHelper(mContext);
-        copier.copyToExternalStorage(R.raw.ringer, mediaFile);
+        copyToExternalStorage(R.raw.ringer, mediaFile);
 
         ContentValues values = new ContentValues();
         values.put(MediaStore.MediaColumns.DATA, mediaFile.getPath());
@@ -73,4 +75,21 @@
         RingtoneManager.setActualDefaultRingtoneUri(
                 mContext, RingtoneManager.TYPE_NOTIFICATION, uri);
     }
+
+    /** After the apk installed in secondary user, it may take some time to update permissions. */
+    private void copyToExternalStorage(int resId, File path)
+            throws InterruptedException, TimeoutException {
+        FileCopyHelper copier = new FileCopyHelper(mContext);
+        int currentAttempt = 0;
+        while (currentAttempt < MAX_NUMBER_OF_ATTEMPTS) {
+            try {
+                copier.copyToExternalStorage(resId, path);
+                return;
+            } catch (Exception e) {
+                currentAttempt++;
+                TimeUnit.MILLISECONDS.sleep(500);
+            }
+        }
+        throw new TimeoutException();
+    }
 }
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java
index 2e5f479..791f207 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/CaCertManagementTest.java
@@ -158,7 +158,7 @@
         // a trusted certificate isn't even installed we should fail now, loudly.
         assertEquals(installed, listed);
         int numTries = 0;
-        while (numTries < (maxWaitForCertificateTrustedSec * 10) && (installed != trusted)) {
+        while (numTries < (maxWaitForCertificateTrustedSec * 20) && (installed != trusted)) {
             try {
                 Thread.sleep(100);
                 trusted = Arrays.asList(tm.getAcceptedIssuers()).contains(caCert);
diff --git a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
index bc33910..653fd57 100644
--- a/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceAndProfileOwner/src/com/android/cts/deviceandprofileowner/DelegatedCertInstallerTest.java
@@ -349,7 +349,7 @@
 
     private void assertResult(String testName, Boolean expectSuccess) throws InterruptedException {
         assertTrue("Cert installer did not respond in time.",
-                mAvailableResultSemaphore.tryAcquire(10, TimeUnit.SECONDS));
+                mAvailableResultSemaphore.tryAcquire(60, TimeUnit.SECONDS));
         synchronized (this) {
             if (expectSuccess) {
                 assertTrue(testName + " failed unexpectedly.", mReceivedResult);
diff --git a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
index 257ac7b..3c31a86 100644
--- a/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
+++ b/hostsidetests/devicepolicy/app/DeviceOwner/src/com/android/cts/deviceowner/CreateAndManageUserTest.java
@@ -52,7 +52,7 @@
 public class CreateAndManageUserTest extends BaseDeviceOwnerTest {
     private static final String TAG = "CreateAndManageUserTest";
 
-    private static final int BROADCAST_TIMEOUT = 30_000;
+    private static final int BROADCAST_TIMEOUT = 60_000;
 
     private static final String AFFILIATION_ID = "affiliation.id";
     private static final String EXTRA_AFFILIATION_ID = "affiliationIdExtra";
diff --git a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
index c91a86a..348348c 100644
--- a/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
+++ b/hostsidetests/devicepolicy/app/ManagedProfile/src/com/android/cts/managedprofile/DisallowSharingIntoProfileTest.java
@@ -176,7 +176,7 @@
                         UserManager.DISALLOW_SHARE_INTO_MANAGED_PROFILE);
             }
             // Wait for the restriction to apply
-            assertTrue("Restriction not applied after 30 seconds", latch.await(30, SECONDS));
+            assertTrue("Restriction not applied after 60 seconds", latch.await(60, SECONDS));
         } finally {
             mContext.unregisterReceiver(receiver);
         }
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
index 3bf5758..81a8700 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/BaseDevicePolicyTest.java
@@ -612,6 +612,12 @@
         return userId;
     }
 
+    protected int createUserAndWaitStart() throws Exception {
+        int userId = createUser(0);
+        startUserAndWait(userId);
+        return userId;
+    }
+
     protected int createUser(int flags) throws Exception {
         boolean guest = FLAG_GUEST == (flags & FLAG_GUEST);
         boolean ephemeral = FLAG_EPHEMERAL == (flags & FLAG_EPHEMERAL);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
index a914bda..acb48aa 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/ManagedProfileTest.java
@@ -89,7 +89,7 @@
 
     private static final String PROFILE_CREDENTIAL = "1234";
     // This should be sufficiently larger than ProfileTimeoutTestHelper.TIMEOUT_MS
-    private static final int PROFILE_TIMEOUT_DELAY_MS = 40_000;
+    private static final int PROFILE_TIMEOUT_DELAY_MS = 60_000;
 
     //The maximum time to wait for user to be unlocked.
     private static final long USER_UNLOCK_TIMEOUT_NANO = 30_000_000_000L;
@@ -1720,6 +1720,9 @@
                     "settings put --user " + mProfileUserId
                     + " secure managed_profile_contact_remote_search 1");
 
+            // Wait for updating cache
+            waitForBroadcastIdle();
+
             // Add test account
             runDeviceTestsAsUser(MANAGED_PROFILE_PKG, ".ContactsTest",
                     "testAddTestAccount", mParentUserId);
diff --git a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
index 9c594b43..e1a26b7 100644
--- a/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
+++ b/hostsidetests/devicepolicy/src/com/android/cts/devicepolicy/UserRestrictionsTest.java
@@ -157,7 +157,7 @@
         setDo();
 
         // Create another user and set PO.
-        final int secondaryUserId = createUser();
+        final int secondaryUserId = createUserAndWaitStart();
         setPoAsUser(secondaryUserId);
 
         // Let DO set all restrictions.
@@ -223,7 +223,7 @@
         setDo();
 
         // Create another user with PO.
-        final int secondaryUserId = createUser();
+        final int secondaryUserId = createUserAndWaitStart();
         setPoAsUser(secondaryUserId);
 
         final int[] usersToCheck = {mDeviceOwnerUserId, secondaryUserId};
diff --git a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
index 5aaef193..53ec2c0 100755
--- a/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
+++ b/hostsidetests/dumpsys/src/android/dumpsys/cts/BatteryStatsDumpsysTest.java
@@ -575,8 +575,8 @@
     }
 
     private void checkDataConnection(String[] parts) {
-        assertEquals(26, parts.length);
-        assertInteger(parts[4]);  // none
+        assertEquals(27, parts.length);
+        assertInteger(parts[4]);  // oos
         assertInteger(parts[5]);  // gprs
         assertInteger(parts[6]);  // edge
         assertInteger(parts[7]);  // umts
@@ -597,7 +597,8 @@
         assertInteger(parts[22]); // iwlan
         assertInteger(parts[23]); // lte_ca
         assertInteger(parts[24]); // nr
-        assertInteger(parts[25]); // other
+        assertInteger(parts[25]); // emngcy
+        assertInteger(parts[26]); // other
     }
 
     private void checkWifiState(String[] parts) {
diff --git a/hostsidetests/net/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java b/hostsidetests/net/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
index f3cd8a9..aa59959 100644
--- a/hostsidetests/net/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
+++ b/hostsidetests/net/app/src/com/android/cts/net/hostside/NetworkCallbackTest.java
@@ -83,6 +83,7 @@
     }
 
     private class TestNetworkCallback extends INetworkCallback.Stub {
+        private static final int TEST_CONNECT_TIMEOUT_MS = 30_000;
         private static final int TEST_CALLBACK_TIMEOUT_MS = 5_000;
 
         private final LinkedBlockingQueue<CallbackInfo> mCallbacks = new LinkedBlockingQueue<>();
@@ -131,7 +132,7 @@
         }
 
         public Network expectAvailableCallbackAndGetNetwork() {
-            final CallbackInfo cb = nextCallback(TEST_CALLBACK_TIMEOUT_MS);
+            final CallbackInfo cb = nextCallback(TEST_CONNECT_TIMEOUT_MS);
             if (cb.state != CallbackState.AVAILABLE) {
                 fail("Network is not available. Instead obtained the following callback :"
                         + cb);
diff --git a/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java b/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java
index b5a456c..1f1772b 100644
--- a/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java
+++ b/hostsidetests/security/src/android/security/cts/ProcessMustUseSeccompTest.java
@@ -101,8 +101,18 @@
 
     private void assertSeccompFilter(String Name, String Cmd, boolean prefix)
                 throws DeviceNotAvailableException {
+        assertSeccompFilter(Name, Cmd, prefix, true /* mustHaveProcess */);
+    }
+
+    private void assertSeccompFilter(String Name, String Cmd, boolean prefix, boolean mustHaveProcess)
+                throws DeviceNotAvailableException {
         String Pid = getPidFromCmd(Name, Cmd, prefix);
-        assertFalse(Name + " process not found.", Pid.equals(""));
+        boolean processFound = !Pid.equals("");
+        if (!processFound && !mustHaveProcess) {
+            // don't bother if the existence of the process isn't guaranteed
+            return;
+        }
+        assertTrue(Name + " process not found.", processFound);
         assertTrue(Name + " must have a seccomp filter enabled.\n"
                    + "The \"Seccomp\" field of " + Name + "'s "
                    + "/proc/" + Pid + "/status file should be set to \"2\"",
@@ -111,7 +121,8 @@
 
     public void testConfigStoreHalHasSeccompFilter() throws DeviceNotAvailableException {
         if (CpuFeatures.isArm64(mDevice)) {
-            assertSeccompFilter("android.hardware.configstore", PS_CMD, true);
+            assertSeccompFilter("android.hardware.configstore", PS_CMD, true,
+                    false /* mustHaveProcess */);
         }
     }
 
diff --git a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
index 6b7dd04..de90629 100644
--- a/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
+++ b/hostsidetests/security/src/android/security/cts/SELinuxHostTest.java
@@ -1258,10 +1258,11 @@
         assertDomainZeroOrOne("u:r:wpa:s0", "/system/bin/wpa_supplicant");
     }
 
-    /* permissioncontroller may or may not be running */
+    /* permissioncontroller, if running, always runs in permissioncontroller_app */
     @CddTest(requirement="9.7")
     public void testPermissionControllerDomain() throws DeviceNotAvailableException {
-        assertDomainZeroOrOne("u:r:permissioncontroller_app:s0", "com.google.android.permissioncontroller");
+        assertExecutableHasDomain("com.google.android.permissioncontroller", "u:r:permissioncontroller_app:s0");
+        assertExecutableHasDomain("com.android.permissioncontroller", "u:r:permissioncontroller_app:s0");
     }
 
     /* vzwomatrigger may or may not be running */
diff --git a/hostsidetests/securitybulletin/AndroidTest.xml b/hostsidetests/securitybulletin/AndroidTest.xml
index 0b00684..e7e2d56 100644
--- a/hostsidetests/securitybulletin/AndroidTest.xml
+++ b/hostsidetests/securitybulletin/AndroidTest.xml
@@ -191,6 +191,7 @@
         <!--__________________-->
         <!-- Bulletin 2018-11 -->
         <!-- Please add tests solely from this bulletin below to avoid merge conflict -->
+        <option name="push" value="CVE-2018-9536->/data/local/tmp/CVE-2018-9536" />
         <option name="push" value="CVE-2018-9539->/data/local/tmp/CVE-2018-9539" />
 
         <!--__________________-->
@@ -202,6 +203,20 @@
         <option name="append-bitness" value="true" />
     </target_preparer>
 
+    <!-- The following tests hit either 32-bit or 64-bit, but not both. All tests in this -->
+    <!-- section should take care to build either 32 bit or 64 bit binary, but not both.  -->
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+        <option name="cleanup" value="true" />
+
+        <!-- Please add 32-bit binary tests below to avoid merge conflict -->
+
+
+        <!-- Please add 64-bit binary tests below to avoid merge conflict -->
+
+
+        <option name="append-bitness" value="false" />
+    </target_preparer>
+
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
         <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="CtsHostLaunchAnyWhereApp.apk" />
diff --git a/hostsidetests/securitybulletin/res/CVE-2018-9490.pac b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
index 9fb7ba8..999518a 100644
--- a/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2018-9490.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     alert("enter");
     let arr = [];
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2045.pac b/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
index 1cb28ff..a6b0166 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2045.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     opttest();
     opttest();
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2047.pac b/hostsidetests/securitybulletin/res/CVE-2019-2047.pac
index 5e39e9b..b70e24a 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2047.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2047.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     for(var i = 0;i<0x10000;i++){
         change_elements_kind(x);
@@ -40,4 +56,4 @@
 var evil = new Array(1.1,2.2);
 evil.x = {};
 
-var x = new Array({});
\ No newline at end of file
+var x = new Array({});
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2051.pac b/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
index b014a16..b24b160 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2051.pac
@@ -1,5 +1,21 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     this.__defineGetter__("x", (a = (function f() { return; (function() {}); })()) => { });
     x;
     return "DIRECT";
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2052.pac b/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
index ab5ed69..670e870 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2052.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     for(var i = 0;i < 0x1000;i++){
         tt();
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2097.pac b/hostsidetests/securitybulletin/res/CVE-2019-2097.pac
index 6c0a8b0..4880f54 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2097.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2097.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     for (var  i = 0; i < 0x10000; i++){
         f();
@@ -19,4 +35,4 @@
         array[i][0] = {"abcd":0x4321};
     }
     double_arr[1] = 6.176516726456e-312;
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/res/CVE-2019-2130.pac b/hostsidetests/securitybulletin/res/CVE-2019-2130.pac
index 79d1967..77a0cb5 100644
--- a/hostsidetests/securitybulletin/res/CVE-2019-2130.pac
+++ b/hostsidetests/securitybulletin/res/CVE-2019-2130.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     function opt() {
         opt['x'] = 1.1;
@@ -18,4 +34,4 @@
     return "DIRECT";
 }
 
-var object;
\ No newline at end of file
+var object;
diff --git a/hostsidetests/securitybulletin/res/bug_138441919.pac b/hostsidetests/securitybulletin/res/bug_138441919.pac
index 61a9ee2..006fb6a 100644
--- a/hostsidetests/securitybulletin/res/bug_138441919.pac
+++ b/hostsidetests/securitybulletin/res/bug_138441919.pac
@@ -1,6 +1,22 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     Object.defineProperty(Promise, Symbol.species, { value: 0 });
     var p = new Promise(function() {});
     p.then();
     return "DIRECT";
-}
\ No newline at end of file
+}
diff --git a/hostsidetests/securitybulletin/res/bug_139806216.pac b/hostsidetests/securitybulletin/res/bug_139806216.pac
index 3a1e34d0..256108d 100644
--- a/hostsidetests/securitybulletin/res/bug_139806216.pac
+++ b/hostsidetests/securitybulletin/res/bug_139806216.pac
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 function FindProxyForURL(url, host){
     var x = new ArrayBuffer(1);
     return "DIRECT";
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
index 238bb0b..b5386e1 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5862/poc.c
@@ -1,4 +1,20 @@
 /*
+ * 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.
+ */
+
+/*
  * CVE-2016-5862
  */
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
index c8e4a20..3b8771f 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2016-5867/poc.c
@@ -1,4 +1,20 @@
 /*
+ * 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.
+ */
+
+/*
  * CVE-2016-5867
  */
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h
index 1622b39..8dad1b8 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2017-0333/local_poc.h
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #ifndef __LOCAL_POC_H__
 #define __LOCAL_POC_H__
 
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c
index a89d596..d8f3471 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9515/poc.c
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #define _GNU_SOURCE
 #include <pthread.h>
 #include <err.h>
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.bp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.bp
new file mode 100644
index 0000000..16f9474
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/Android.bp
@@ -0,0 +1,27 @@
+// Copyright (C) 2020 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+cc_test {
+    name: "CVE-2018-9536",
+    defaults: ["cts_hostsidetests_securitybulletin_defaults"],
+    srcs: ["poc.cpp"],
+    include_dirs: [
+        "external/aac/libFDK/include",
+        "external/aac/libSYS/include",
+        "cts/hostsidetests/securitybulletin/securityPatch/includes",
+    ],
+    shared_libs: [
+        "libbluetooth"
+    ],
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/poc.cpp
new file mode 100644
index 0000000..47d20e6
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9536/poc.cpp
@@ -0,0 +1,51 @@
+/**
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <signal.h>
+#include <string>
+#include <common.h>
+#include <FDK_bitbuffer.h>
+#define MAX_PATH_LENGTH 1035
+
+int main() {
+    FILE *fp;
+    char path[MAX_PATH_LENGTH];
+    void *libHandle;
+    static int (*real_FDK_getBitCnt)(HANDLE_FDK_BITBUF) = NULL;
+    fp = popen("find / -name libbluetooth.so 2>/dev/null ", "r");
+    if (fp == NULL) {
+        return EXIT_SUCCESS;
+    }
+    while (fgets(path, sizeof(path) - 1, fp) != NULL) {
+        path[strlen(path) - 1] = '\0'; /* remove \n */
+
+        libHandle = dlopen(path, RTLD_LAZY);
+        if (libHandle) {
+            real_FDK_getBitCnt = (int (*)(
+                    HANDLE_FDK_BITBUF))dlsym(libHandle, "FDK_getBitCnt");
+            dlclose(libHandle);
+            if (real_FDK_getBitCnt) {
+                pclose(fp);
+                /* The symbol of function is present, it means there is no fix patch */
+                return EXIT_VULNERABLE;
+            }
+        }
+    }
+    pclose(fp);
+    return EXIT_SUCCESS;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp
index 5f9bd37..0b464e5 100644
--- a/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/CVE-2018-9539/poc.cpp
@@ -1,3 +1,19 @@
+/*
+ * 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.
+ */
+
 #include <android/hardware/cas/1.0/ICas.h>
 #include <android/hardware/cas/1.0/IMediaCasService.h>
 #include <android/hardware/cas/native/1.0/IDescrambler.h>
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils.c b/hostsidetests/securitybulletin/securityPatch/includes/memutils.c
new file mode 100644
index 0000000..650d2f6
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils.c
@@ -0,0 +1,267 @@
+/**
+ * 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.
+ */
+#define _GNU_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <string.h>
+#include <unistd.h>
+#include <signal.h>
+#include "memutils.h"
+
+void exit_handler(void) {
+    size_t page_size = getpagesize();
+    for (int i = 0; i < s_mem_map_index; i++) {
+        if (NULL != s_mem_map[i].start_ptr) {
+            ENABLE_MEM_ACCESS(s_mem_map[i].start_ptr,
+                              (s_mem_map[i].num_pages * page_size));
+        }
+    }
+#ifdef CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE
+    for (int i = 0; i < MAX_ENTRIES; i++) {
+        if (NULL != s_free_list[i].start_ptr) {
+            ENABLE_MEM_ACCESS(s_free_list[i].start_ptr,
+                    (s_free_list[i].num_pages * page_size));
+            real_free(s_free_list[i].start_ptr);
+            memset(&s_free_list[i], 0, sizeof(map_struct_t));
+        }
+    }
+#endif /* CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE */
+}
+
+void sigsegv_handler(int signum, siginfo_t *info, void* context) {
+    exit_handler();
+    (*old_sa.sa_sigaction)(signum, info, context);
+}
+
+void sighandler_init(void) {
+    sigemptyset(&new_sa.sa_mask);
+    new_sa.sa_flags = SA_SIGINFO;
+    new_sa.sa_sigaction = sigsegv_handler;
+    sigaction(SIGSEGV, &new_sa, &old_sa);
+}
+
+void memutils_init(void) {
+    real_memalign = dlsym(RTLD_NEXT, "memalign");
+    if (NULL == real_memalign) {
+        return;
+    }
+    real_calloc = dlsym(RTLD_NEXT, "calloc");
+    if (NULL == real_calloc) {
+        return;
+    }
+    real_malloc = dlsym(RTLD_NEXT, "malloc");
+    if (NULL == real_malloc) {
+        return;
+    }
+    real_realloc = dlsym(RTLD_NEXT, "realloc");
+    if (NULL == real_realloc) {
+        return;
+    }
+    real_free = dlsym(RTLD_NEXT, "free");
+    if (NULL == real_free) {
+        return;
+    }
+    memset(&s_mem_map, 0, MAX_ENTRIES * sizeof(map_struct_t));
+    sighandler_init();
+    atexit(exit_handler);
+    s_memutils_initialized = 1;
+}
+
+void *memalign(size_t alignment, size_t size) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_MEMALIGN_CHECK) != ENABLE_MEMALIGN_CHECK) {
+        return real_memalign(alignment, size);
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+    char* start_ptr;
+    char* mem_ptr;
+    size_t total_size;
+    size_t aligned_size = size;
+    size_t num_pages;
+    size_t page_size = getpagesize();
+
+    /* User specified alignment is not respected and is overridden by
+     * "new_alignment". This is required to catch OOB read when read offset is
+     * less than user specified alignment. "new_alignment" is derived based on
+     * size_t, and helps to avoid bus errors due to non-aligned memory.
+     * "new_alignment", whenever used, is checked to ensure sizeof(size_t)
+     * has returned proper value                                            */
+    size_t new_alignment = sizeof(size_t);
+
+    if (s_mem_map_index == MAX_ENTRIES) {
+        return real_memalign(alignment, size);
+    }
+
+    if (alignment > page_size) {
+        return real_memalign(alignment, size);
+    }
+
+    if ((0 == page_size) || (0 == alignment) || (0 == size)
+            || (0 == new_alignment)) {
+        return real_memalign(alignment, size);
+    }
+#ifdef CHECK_OVERFLOW
+    if (0 != (size % new_alignment)) {
+        aligned_size = size + (new_alignment - (size % new_alignment));
+    }
+#endif
+
+    if (0 != (aligned_size % page_size)) {
+        num_pages = (aligned_size / page_size) + 2;
+    } else {
+        num_pages = (aligned_size / page_size) + 1;
+    }
+
+    total_size = (num_pages * page_size);
+    start_ptr = (char *) real_memalign(page_size, total_size);
+#ifdef CHECK_OVERFLOW
+#ifdef FORCE_UNALIGN
+    mem_ptr = (char *) start_ptr + ((num_pages - 1) * page_size) - size;
+#else
+    mem_ptr = (char *) start_ptr + ((num_pages - 1) * page_size) - aligned_size;
+#endif /* FORCE_UNALIGN */
+    DISABLE_MEM_ACCESS((start_ptr + ((num_pages - 1) * page_size)), page_size);
+#endif /* CHECK_OVERFLOW */
+#ifdef CHECK_UNDERFLOW
+    mem_ptr = (char *) start_ptr + page_size;
+    DISABLE_MEM_ACCESS(start_ptr, page_size);
+#endif /* CHECK_UNDERFLOW */
+    s_mem_map[s_mem_map_index].start_ptr = start_ptr;
+    s_mem_map[s_mem_map_index].mem_ptr = mem_ptr;
+    s_mem_map[s_mem_map_index].num_pages = num_pages;
+    s_mem_map[s_mem_map_index].mem_size = size;
+    s_mem_map_index++;
+    memset(mem_ptr, INITIAL_VAL, size);
+    return mem_ptr;
+}
+
+void *malloc(size_t size) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_MALLOC_CHECK) != ENABLE_MALLOC_CHECK) {
+        return real_malloc(size);
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+    return memalign(sizeof(size_t), size);
+}
+
+void *calloc(size_t nitems, size_t size) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_CALLOC_CHECK) != ENABLE_CALLOC_CHECK) {
+        return real_calloc(nitems, size);
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+    void *ptr = memalign(sizeof(size_t), (nitems * size));
+    if (ptr)
+        memset(ptr, 0, (nitems * size));
+    return ptr;
+}
+
+void *realloc(void *ptr, size_t size) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_REALLOC_CHECK) != ENABLE_REALLOC_CHECK) {
+        return real_realloc(ptr, size);
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+    if (ptr != NULL) {
+        int i = 0;
+        for (i = 0; i < s_mem_map_index; i++) {
+            if (ptr == s_mem_map[i].mem_ptr) {
+                void* temp = malloc(size);
+                if (temp == NULL) {
+                    return NULL;
+                }
+                if (s_mem_map[i].mem_size > size) {
+                    memcpy(temp, ptr, size);
+                } else {
+                    memcpy(temp, ptr, s_mem_map[i].mem_size);
+                }
+                free(s_mem_map[i].mem_ptr);
+                return temp;
+            }
+        }
+    }
+    return real_realloc(ptr, size);
+}
+
+void free(void *ptr) {
+    if (s_memutils_initialized == 0) {
+        memutils_init();
+    }
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+    if ((enable_selective_overload & ENABLE_FREE_CHECK) != ENABLE_FREE_CHECK) {
+        return real_free(ptr);
+    }
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+    if (ptr != NULL) {
+        int i = 0;
+        size_t page_size = getpagesize();
+        for (i = 0; i < s_mem_map_index; i++) {
+            if (ptr == s_mem_map[i].mem_ptr) {
+#ifdef CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE
+                s_free_list[s_free_write_index].start_ptr =
+                s_mem_map[i].start_ptr;
+                s_free_list[s_free_write_index].mem_ptr = s_mem_map[i].mem_ptr;
+                s_free_list[s_free_write_index].num_pages =
+                s_mem_map[i].num_pages;
+                s_free_list[s_free_write_index].mem_size = s_mem_map[i].mem_size;
+                s_free_write_index++;
+                s_free_list_size += s_mem_map[i].mem_size;
+                DISABLE_MEM_ACCESS(s_mem_map[i].start_ptr,
+                        (s_mem_map[i].num_pages * page_size));
+                memset(&s_mem_map[i], 0, sizeof(map_struct_t));
+                while (s_free_list_size > CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE) {
+                    ENABLE_MEM_ACCESS(
+                            s_free_list[s_free_read_index].start_ptr,
+                            (s_free_list[s_free_read_index].num_pages * page_size));
+                    real_free(s_free_list[s_free_read_index].start_ptr);
+                    s_free_list_size -= s_free_list[s_free_read_index].mem_size;
+                    memset(&s_free_list[s_free_read_index], 0,
+                            sizeof(map_struct_t));
+                    s_free_read_index++;
+                    if ((s_free_read_index == MAX_ENTRIES)
+                            || (s_free_read_index >= s_free_write_index)) {
+                        break;
+                    }
+                }
+                return;
+#else
+                ENABLE_MEM_ACCESS(s_mem_map[i].start_ptr,
+                                  (s_mem_map[i].num_pages * page_size));
+                real_free(s_mem_map[i].start_ptr);
+                memset(&s_mem_map[i], 0, sizeof(map_struct_t));
+                return;
+#endif /* CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE */
+            }
+        }
+    }
+    real_free(ptr);
+    return;
+}
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/memutils.h b/hostsidetests/securitybulletin/securityPatch/includes/memutils.h
new file mode 100644
index 0000000..10ee31e
--- /dev/null
+++ b/hostsidetests/securitybulletin/securityPatch/includes/memutils.h
@@ -0,0 +1,68 @@
+/**
+ * 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.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#define MAX_ENTRIES        (1024 * 1024)
+#define INITIAL_VAL        (0xBE)
+
+#define DISABLE_MEM_ACCESS(mem, size)\
+    mprotect((char *) mem, size, PROT_NONE);
+
+#define ENABLE_MEM_ACCESS(mem, size)\
+    mprotect((char *) mem, size, PROT_READ | PROT_WRITE);
+
+#define ENABLE_NONE               0x00
+#define ENABLE_MEMALIGN_CHECK     0x01
+#define ENABLE_MALLOC_CHECK       0x02
+#define ENABLE_CALLOC_CHECK       0x04
+#define ENABLE_REALLOC_CHECK      0x08
+#define ENABLE_FREE_CHECK         0x10
+#define ENABLE_ALL                ENABLE_MEMALIGN_CHECK | ENABLE_MALLOC_CHECK |\
+    ENABLE_CALLOC_CHECK | ENABLE_REALLOC_CHECK | ENABLE_FREE_CHECK
+
+typedef struct _map_struct_t {
+    void *start_ptr;
+    void *mem_ptr;
+    int num_pages;
+    size_t mem_size;
+} map_struct_t;
+
+static void* (*real_memalign)(size_t, size_t) = NULL;
+static void* (*real_calloc)(size_t, size_t) = NULL;
+static void* (*real_malloc)(size_t) = NULL;
+static void* (*real_realloc)(void *ptr, size_t size) = NULL;
+static void (*real_free)(void *) = NULL;
+static int s_memutils_initialized = 0;
+static int s_mem_map_index = 0;
+static struct sigaction new_sa, old_sa;
+#ifdef ENABLE_SELECTIVE_OVERLOADING
+extern char enable_selective_overload;
+#endif /* ENABLE_SELECTIVE_OVERLOADING */
+#ifdef CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE
+static int s_free_write_index = 0;
+static int s_free_read_index = 0;
+static int s_free_list_size = 0;
+map_struct_t s_free_list[MAX_ENTRIES];
+#endif /* CHECK_USE_AFTER_FREE_WITH_WINDOW_SIZE */
+map_struct_t s_mem_map[MAX_ENTRIES];
+#if (!(defined CHECK_OVERFLOW) && !(defined CHECK_UNDERFLOW))
+    #error "CHECK MACROS NOT DEFINED"
+#endif
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
index 85b8422..38834d2 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.cpp
@@ -24,6 +24,7 @@
 int32_t mLastMsgGeneration;
 int32_t mCurGeneration;
 List<omx_message> mMessageQueue;
+int numCallbackEmptyBufferDone;
 
 struct CodecObserver : public BnOMXObserver {
  public:
@@ -42,7 +43,11 @@
     Mutex::Autolock autoLock(mLock);
     for (std::list<omx_message>::const_iterator it = messages.cbegin();
             it != messages.cend();) {
-        mMessageQueue.push_back(*it++);
+        mMessageQueue.push_back(*it);
+        const omx_message &msg = *it++;
+        if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
+            numCallbackEmptyBufferDone++;
+        }
         mLastMsgGeneration = gen;
     }
     mMessageAddedCondition.signal();
@@ -51,6 +56,22 @@
     handleMessages(mGeneration, messages);
 }
 
+struct DeathNotifier : public IBinder::DeathRecipient,
+        public ::android::hardware::hidl_death_recipient {
+    explicit DeathNotifier() {
+    }
+    virtual void binderDied(const wp<IBinder> &) {
+        ALOGE("Binder Died");
+        exit (EXIT_FAILURE);
+    }
+    virtual void serviceDied(
+            uint64_t /* cookie */,
+            const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
+        ALOGE("Service Died");
+        exit (EXIT_FAILURE);
+    }
+};
+sp<DeathNotifier> mDeathNotifier;
 status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs) {
     int64_t finishBy = ALooper::GetNowUs() + timeoutUs;
     status_t err = OK;
@@ -91,14 +112,26 @@
 }
 status_t omxUtilsInit(char *codecName) {
     android::ProcessState::self()->startThreadPool();
-    using namespace ::android::hardware::media::omx::V1_0;
-    sp<IOmx> tOmx = IOmx::getService();
-    if (tOmx == nullptr) {
+    OMXClient client;
+    if (client.connect() != OK) {
+        ALOGE("Failed to connect to OMX to create persistent input surface.");
         return NO_INIT;
     }
-    mOMX = new utils::LWOmx(tOmx);
+    mOMX = client.interface();
     sp<CodecObserver> observer = new CodecObserver(++mCurGeneration);
-    return mOMX->allocateNode(codecName, observer, &mOMXNode);
+    status_t ret = mOMX->allocateNode(codecName, observer, &mOMXNode);
+    if (ret == OK) {
+        mDeathNotifier = new DeathNotifier();
+        auto tOmxNode = mOMXNode->getHalInterface<IOmxNode>();
+        if (tOmxNode != NULL) {
+            tOmxNode->linkToDeath(mDeathNotifier, 0);
+        } else {
+            ALOGE("No HAL Interface");
+            exit (EXIT_FAILURE);
+        }
+    }
+    numCallbackEmptyBufferDone = 0;
+    return ret;
 }
 status_t omxUtilsGetParameter(int portIndex,
                               OMX_PARAM_PORTDEFINITIONTYPE *params) {
@@ -118,7 +151,7 @@
     return mOMXNode->setPortMode(portIndex, mode);
 }
 status_t omxUtilsUseBuffer(OMX_U32 portIndex, const OMXBuffer &omxBuf,
-                           android::BnOMX::buffer_id *buffer) {
+                           android::IOMX::buffer_id *buffer) {
     return mOMXNode->useBuffer(portIndex, omxBuf, buffer);
 }
 status_t omxUtilsSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param) {
@@ -126,17 +159,17 @@
     omxUtilsCheckCmdExecution((char *) __FUNCTION__);
     return ret;
 }
-status_t omxUtilsEmptyBuffer(android::BnOMX::buffer_id buffer,
+status_t omxUtilsEmptyBuffer(android::IOMX::buffer_id buffer,
                              const OMXBuffer &omxBuf, OMX_U32 flags,
                              OMX_TICKS timestamp, int fenceFd) {
     return mOMXNode->emptyBuffer(buffer, omxBuf, flags, timestamp, fenceFd);
 }
-status_t omxUtilsFillBuffer(android::BnOMX::buffer_id buffer,
+status_t omxUtilsFillBuffer(android::IOMX::buffer_id buffer,
                             const OMXBuffer &omxBuf, int fenceFd) {
     return mOMXNode->fillBuffer(buffer, omxBuf, fenceFd);
 }
 status_t omxUtilsFreeBuffer(OMX_U32 portIndex,
-                            android::BnOMX::buffer_id buffer) {
+                            android::IOMX::buffer_id buffer) {
     return mOMXNode->freeBuffer(portIndex, buffer);
 }
 status_t omxUtilsFreeNode() {
diff --git a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
index ab81bae..32da687 100644
--- a/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
+++ b/hostsidetests/securitybulletin/securityPatch/includes/omxUtils.h
@@ -43,6 +43,7 @@
 #include <utils/threads.h>
 #include <inttypes.h>
 #include <utils/Log.h>
+#include <media/stagefright/OMXClient.h>
 
 #define DEFAULT_TIMEOUT   5000000
 #define OMX_UTILS_IP_PORT 0
@@ -73,15 +74,15 @@
                               OMX_PARAM_PORTDEFINITIONTYPE *params);
 status_t omxUtilsSetPortMode(OMX_U32 port_index, IOMX::PortMode mode);
 status_t omxUtilsUseBuffer(OMX_U32 portIndex, const OMXBuffer &omxBuf,
-                           android::BnOMX::buffer_id *buffer);
+                           android::IOMX::buffer_id *buffer);
 status_t omxUtilsSendCommand(OMX_COMMANDTYPE cmd, OMX_S32 param);
-status_t omxUtilsEmptyBuffer(android::BnOMX::buffer_id buffer,
+status_t omxUtilsEmptyBuffer(android::IOMX::buffer_id buffer,
                              const OMXBuffer &omxBuf, OMX_U32 flags,
                              OMX_TICKS timestamp, int fenceFd);
-status_t omxUtilsFillBuffer(android::BnOMX::buffer_id buffer,
+status_t omxUtilsFillBuffer(android::IOMX::buffer_id buffer,
                             const OMXBuffer &omxBuf, int fenceFd);
 status_t omxUtilsFreeBuffer(OMX_U32 portIndex,
-                            android::BnOMX::buffer_id buffer);
+                            android::IOMX::buffer_id buffer);
 status_t omxUtilsFreeNode();
 status_t dequeueMessageForNode(omx_message *msg, int64_t timeoutUs);
 void omxExitOnError(status_t ret);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
index e640172..ac8908b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/AdbUtils.java
@@ -33,6 +33,9 @@
 import java.util.regex.Pattern;
 import java.util.concurrent.TimeUnit;
 import java.util.Scanner;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.concurrent.Callable;
 
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -45,6 +48,10 @@
 
 public class AdbUtils {
 
+    final static String TMP_PATH = "/data/local/tmp/";
+    final static int TIMEOUT_SEC = 9 * 60;
+    final static String RESOURCE_ROOT = "/";
+
     /** Runs a commandline on the specified device
      *
      * @param command the command to be ran
@@ -220,6 +227,40 @@
         }
     }
 
+    /**
+     * Pushes the specified files to the specified destination directory
+     *
+     * @param inputFiles files required as input
+     * @param inputFilesDestination destination directory to which input files are
+     *        pushed
+     * @param device device to be run on
+     */
+    public static void pushResources(String[] inputFiles, String inputFilesDestination,
+            ITestDevice device) throws Exception {
+        if ( (inputFiles != null) && (inputFilesDestination != null)) {
+            for (String tempFile : inputFiles) {
+                pushResource(RESOURCE_ROOT + tempFile, inputFilesDestination + tempFile, device);
+            }
+        }
+    }
+
+    /**
+     * Removes the specified files from the specified destination directory
+     *
+     * @param inputFiles files required as input
+     * @param inputFilesDestination destination directory where input files are
+     *        present
+     * @param device device to be run on
+     */
+    public static void removeResources(String[] inputFiles, String inputFilesDestination,
+            ITestDevice device) throws Exception {
+        if ( (inputFiles != null) && (inputFilesDestination != null)) {
+            for (String tempFile : inputFiles) {
+                runCommandLine("rm " + inputFilesDestination + tempFile, device);
+            }
+        }
+    }
+
    /**
      * Extracts the binary data from a resource and writes it to a temp file
      */
@@ -280,9 +321,22 @@
      */
     public static int runPocGetExitStatus(String pocName, ITestDevice device, int timeout)
             throws Exception {
-        device.executeShellCommand("chmod +x /data/local/tmp/" + pocName);
+       return runPocGetExitStatus(pocName, null, device, timeout);
+    }
+
+    /**
+     * Pushes and runs a binary to the device and returns the exit status.
+     * @param pocName a string path to poc from the /res folder
+     * @param arguments input arguments for the poc
+     * @param device device to be ran on
+     * @param timeout time to wait for output in seconds
+
+     */
+    public static int runPocGetExitStatus(String pocName, String arguments, ITestDevice device,
+            int timeout) throws Exception {
+        device.executeShellCommand("chmod +x " + TMP_PATH + pocName);
         CollectingOutputReceiver receiver = new CollectingOutputReceiver();
-        String cmd = "/data/local/tmp/" + pocName + " > /dev/null 2>&1; echo $?";
+        String cmd = TMP_PATH + pocName + " " + arguments + " > /dev/null 2>&1; echo $?";
         long time = System.currentTimeMillis();
         device.executeShellCommand(cmd, receiver, timeout, TimeUnit.SECONDS, 0);
         time = System.currentTimeMillis() - time;
@@ -304,10 +358,23 @@
      */
     public static void runPocAssertExitStatusNotVulnerable(
             String pocName, ITestDevice device, int timeout) throws Exception {
-        assertTrue("PoC returned exit status 113: vulnerable",
-                runPocGetExitStatus(pocName, device, timeout) != 113);
+        runPocAssertExitStatusNotVulnerable(pocName, null, device, timeout);
     }
 
+    /**
+     * Pushes and runs a binary and asserts that the exit status isn't 113: vulnerable.
+     * @param pocName a string path to poc from the /res folder
+     * @param arguments input arguments for the poc
+     * @param device device to be ran on
+     * @param timeout time to wait for output in seconds
+     */
+    public static void runPocAssertExitStatusNotVulnerable(String pocName, String arguments,
+            ITestDevice device, int timeout) throws Exception {
+        assertTrue("PoC returned exit status 113: vulnerable",
+                runPocGetExitStatus(pocName, arguments, device, timeout) != 113);
+    }
+
+
     public static int runProxyAutoConfig(String pacName, ITestDevice device) throws Exception {
         runCommandLine("chmod +x /data/local/tmp/pacrunner", device);
         String targetPath = "/data/local/tmp/" + pacName + ".pac";
@@ -326,9 +393,115 @@
      */
     public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
             String... processPatternStrings) throws Exception {
+        runPocAssertNoCrashes(pocName, device,
+                new CrashUtils.Config().setProcessPatterns(processPatternStrings));
+    }
+
+    /**
+     * Runs the poc binary and asserts that there are no security crashes that match the expected
+     * process pattern.
+     * @param pocName a string path to poc from the /res folder
+     * @param device device to be ran on
+     * @param config a crash parser configuration
+     */
+    public static void runPocAssertNoCrashes(String pocName, ITestDevice device,
+            CrashUtils.Config config) throws Exception {
         AdbUtils.runCommandLine("logcat -c", device);
         AdbUtils.runPocNoOutput(pocName, device, SecurityTestCase.TIMEOUT_NONDETERMINISTIC);
-        assertNoCrashes(device, processPatternStrings);
+        assertNoCrashes(device, config);
+    }
+
+    /**
+     * Runs the poc binary and asserts following 2 conditions.
+     *  1. There are no security crashes in the binary.
+     *  2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+     *
+     * @param binaryName name of the binary
+     * @param arguments arguments for running the binary
+     * @param device device to be run on
+     */
+    public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
+            ITestDevice device) throws Exception {
+        runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, null, device, null);
+    }
+
+    /**
+     * Runs the poc binary and asserts following 2 conditions.
+     *  1. There are no security crashes in the binary.
+     *  2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+     *
+     * @param binaryName name of the binary
+     * @param arguments arguments for running the binary
+     * @param device device to be run on
+     * @param processPatternStrings a Pattern string to match the crash tombstone
+     *        process
+     */
+    public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
+            ITestDevice device, String processPatternStrings[]) throws Exception {
+        runPocAssertNoCrashesNotVulnerable(binaryName, arguments, null, null, device,
+                processPatternStrings);
+    }
+
+    /**
+     * Runs the poc binary and asserts following 2 conditions.
+     *  1. There are no security crashes in the binary.
+     *  2. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+     *
+     * @param binaryName name of the binary
+     * @param arguments arguments for running the binary
+     * @param inputFiles files required as input
+     * @param inputFilesDestination destination directory to which input files are
+     *        pushed
+     * @param device device to be run on
+     */
+    public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
+            String inputFiles[], String inputFilesDestination, ITestDevice device)
+            throws Exception {
+        runPocAssertNoCrashesNotVulnerable(binaryName, arguments, inputFiles, inputFilesDestination,
+                device, null);
+    }
+
+    /**
+     * Runs the poc binary and asserts following 3 conditions.
+     *  1. There are no security crashes in the binary.
+     *  2. There are no security crashes that match the expected process pattern.
+     *  3. The exit status isn't 113 (Code 113 is used to indicate the vulnerability condition).
+     *
+     * @param binaryName name of the binary
+     * @param arguments arguments for running the binary
+     * @param inputFiles files required as input
+     * @param inputFilesDestination destination directory to which input files are
+     *        pushed
+     * @param device device to be run on
+     * @param processPatternStrings a Pattern string to match the crash tombstone
+     *        process
+     */
+    public static void runPocAssertNoCrashesNotVulnerable(String binaryName, String arguments,
+            String inputFiles[], String inputFilesDestination, ITestDevice device,
+            String processPatternStrings[]) throws Exception {
+        pushResources(inputFiles, inputFilesDestination, device);
+        runCommandLine("logcat -c", device);
+        try {
+            runPocAssertExitStatusNotVulnerable(binaryName, arguments, device, TIMEOUT_SEC);
+        } catch (IllegalArgumentException e) {
+            /*
+             * Since 'runPocGetExitStatus' method raises IllegalArgumentException upon
+             * hang/timeout, catching the exception here and ignoring it. Hangs are of
+             * Moderate severity and hence patches may not be ported. This piece of code can
+             * be removed once 'runPocGetExitStatus' is updated to handle hangs.
+             */
+            CLog.w("Ignoring IllegalArgumentException: " + e);
+        } finally {
+            removeResources(inputFiles, inputFilesDestination, device);
+        }
+        List<String> processPatternList = new ArrayList<>();
+        if (processPatternStrings != null) {
+            processPatternList.addAll(Arrays.asList(processPatternStrings));
+        }
+        processPatternList.add(binaryName);
+        String[] processPatternStringsWithSelf = new String[processPatternList.size()];
+        processPatternList.toArray(processPatternStringsWithSelf);
+        assertNoCrashes(device, processPatternStringsWithSelf);
     }
 
     /**
@@ -340,19 +513,17 @@
      */
     public static void assertNoCrashes(ITestDevice device, String... processPatternStrings)
             throws Exception {
-        assertNoCrashes(device, new CrashUtils.Config()
-                .checkMinAddress(true)
-                .setProcessPatterns(processPatternStrings));
+        assertNoCrashes(device, new CrashUtils.Config().setProcessPatterns(processPatternStrings));
     }
 
     /**
      * Dumps logcat and asserts that there are no security crashes that match the expected process
      * pattern. Ensure that adb logcat -c is called beforehand.
      * @param device device to be ran on
-     * @param config crash detection configuration object
+     * @param config a crash parser configuration
      */
-    public static void assertNoCrashes(ITestDevice device, CrashUtils.Config config)
-            throws Exception {
+    public static void assertNoCrashes(ITestDevice device,
+            CrashUtils.Config config) throws Exception {
         String logcat = AdbUtils.runCommandLine("logcat -d *:S DEBUG:V", device);
 
         JSONArray crashes = CrashUtils.addAllCrashes(logcat, new JSONArray());
@@ -377,39 +548,4 @@
         }
         fail(error.toString());
      }
-
-    /**
-     * Executes a given poc within a given timeout. Returns error if the
-     * given poc doesnt complete its execution within timeout. It also deletes
-     * the list of files provided.
-     *
-     * @param runner the thread which will be run
-     * @param timeout the timeout within which the thread's execution should
-     *        complete
-     * @param device device to be ran on
-     * @param inputFiles list of files to be deleted
-     */
-    public static void runWithTimeoutDeleteFiles(Runnable runner, int timeout, ITestDevice device,
-            String[] inputFiles) throws Exception {
-        Thread t = new Thread(runner);
-        t.start();
-        boolean test_failed = false;
-        try {
-            t.join(timeout);
-        } catch (InterruptedException e) {
-            test_failed = true;
-        } finally {
-            if (inputFiles != null) {
-                for (String tempFile : inputFiles) {
-                    AdbUtils.runCommandLine("rm /data/local/tmp/" + tempFile, device);
-                }
-            }
-            if (test_failed) {
-                fail("PoC was interrupted");
-            }
-        }
-        if (t.isAlive()) {
-            Assert.fail("PoC not completed within timeout of " + timeout + " ms");
-        }
-    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java b/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
index e62a7b3..1d57cb6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/HostsideMainlineModuleDetector.java
@@ -1,3 +1,19 @@
+/*
+ * 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.security.cts;
 
 import com.android.ddmlib.Log;
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_02.java
index 4a638a9..04a8f03 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_02.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,15 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_02 extends SecurityTestCase {
     /**
      *  b/25800375
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-02")
     public void testPocCVE_2016_0811() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-0811", getDevice(), "mediaserver");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
index 25c1373..b0f0ddc 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_04.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,13 +16,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_04 extends SecurityTestCase {
 
     /**
      * b/26323455
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testPocCVE_2016_2419() throws Exception {
         AdbUtils.runCommandLine("logcat -c" , getDevice());
@@ -34,6 +40,7 @@
     /**
     *  b/26324307
     */
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testPocCVE_2016_0844() throws Exception {
         AdbUtils.runPoc("CVE-2016-0844", getDevice(), 60);
@@ -42,6 +49,7 @@
     /**
      * b/26593930
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testPocCVE_2016_2412() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-2412", getDevice(), "system_server");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
index d8df1c6..39b7ada 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,12 +17,18 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_05 extends SecurityTestCase {
     /**
      *  b/27555981
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-05")
     public void testPocCVE_2016_2460() throws Exception {
         AdbUtils.runCommandLine("logcat -c" , getDevice());
@@ -35,8 +41,10 @@
     /**
      *  b/27275324
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-05")
     public void testPocCVE_2015_1805() throws Exception {
+      getOomCatcher().setHighMemoryTest();
       AdbUtils.runPoc("CVE-2015-1805", getDevice(), TIMEOUT_NONDETERMINISTIC);
     }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
index b414a55..58c604e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_06.java
@@ -1,27 +1,34 @@
 /**
-* 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.
-*/
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_06 extends SecurityTestCase {
     /**
      *  b/27661749
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-06")
     public void testPocCVE_2016_2482() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-2482", getDevice(), "mediaserver");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
index b634645..4367a61 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_07.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,15 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_07 extends SecurityTestCase {
     /**
      *  b/28740702
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2016_3818() throws Exception {
         AdbUtils.runPoc("CVE-2016-3818", getDevice(), 60);
@@ -30,6 +37,7 @@
     /**
      *  b/27890802
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2016_3746() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-3746", getDevice(), "mediaserver");
@@ -38,6 +46,7 @@
     /**
      *  b/28557020
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2014_9803() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2014-9803", getDevice(), 60);
@@ -46,6 +55,7 @@
     /**
      * b/27903498
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testPocCVE_2016_3747() throws Exception {
         getOomCatcher().setHighMemoryTest();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
index 3280a68..a253619 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_09.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,15 +13,22 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_09 extends SecurityTestCase {
     /**
      * b/27773913
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-09")
     public void testPocCVE_2016_2471() throws Exception {
         AdbUtils.runPoc("CVE-2016-2471", getDevice(), 60);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
index 6daa385..d1550d2 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_10.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_10 extends SecurityTestCase {
 
     /**
      *  b/30204103
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-10")
     public void testPocCVE_2016_3913() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2016-3913", getDevice(), "mediaserver");
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
index bb18b0d..60a15e6 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_11 extends SecurityTestCase {
 
     /**
      *  b/29149404
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2012_6702() throws Exception {
         AdbUtils.runCommandLine("logcat -c", getDevice());
@@ -35,6 +41,7 @@
     /**
      *  b/30904789
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6730() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -45,6 +52,7 @@
     /**
      *  b/30906023
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6731() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -55,6 +63,7 @@
     /**
      *  b/30906599
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6732() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -65,6 +74,7 @@
     /**
      *  b/30906694
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6733() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -75,6 +85,7 @@
     /**
      *  b/30907120
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6734() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -85,6 +96,7 @@
     /**
      *  b/30907701
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6735() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -95,6 +107,7 @@
     /**
      *  b/30953284
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testPocCVE_2016_6736() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
index 65a6931..4e2031b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc16_12.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc16_12 extends SecurityTestCase {
 
     //Criticals
     /**
      *  b/31796940
      */
+    @Test
     @SecurityTest(minPatchLevel = "2016-12")
     public void testPocCVE_2016_8406() throws Exception {
         assertNotKernelPointer(() -> {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
index 107ac45..a7ae370 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_01.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_01 extends SecurityTestCase {
 
     //Criticals
     /**
      *  b/31797770
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8425() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
@@ -35,6 +41,7 @@
     /**
      *  b/31799206
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8426() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-gpu")) {
@@ -45,6 +52,7 @@
     /**
      *  b/31799885
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8427() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-gpu") ||
@@ -56,6 +64,7 @@
     /**
      *  b/31993456
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8428() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
@@ -66,6 +75,7 @@
     /**
      *  b/32160775
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8429() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
@@ -76,6 +86,7 @@
     /**
      *  b/32225180
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8430() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvhost-vic")) {
@@ -86,6 +97,7 @@
    /**
      *  b/32402179
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8431() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -96,6 +108,7 @@
     /**
      *  b/32447738
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8432() throws Exception {
         if(containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -106,6 +119,7 @@
     /**
      *  b/32125137
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8434() throws Exception {
         if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
@@ -117,6 +131,7 @@
     /**
      *  b/31668540
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2016_8460() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
@@ -128,6 +143,7 @@
     /**
      *  b/32255299
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testPocCVE_2017_0386() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2017-0386", getDevice(), 60);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
index f9d4e1d..3f94a62 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_02.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,30 +17,39 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_02 extends SecurityTestCase {
-  /**
-   *  b/32799236
-   */
-  @SecurityTest(minPatchLevel = "2017-02")
-  public void testPocCVE_2017_0426() throws Exception {
-      AdbUtils.runCommandLine("logcat -c", getDevice());
-      AdbUtils.runPoc("CVE-2017-0426", getDevice(), 60);
-      String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
-      assertNotMatchesMultiLine("Bugreports file in wrong path", logcatOut);
-  }
+    /**
+     *  b/32799236
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-02")
+    public void testPocCVE_2017_0426() throws Exception {
+        AdbUtils.runCommandLine("logcat -c", getDevice());
+        AdbUtils.runPoc("CVE-2017-0426", getDevice(), 60);
+        String logcatOut = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatchesMultiLine("Bugreports file in wrong path", logcatOut);
+    }
 
-   /**
-   *  b/32706020
-   */
-  @SecurityTest(minPatchLevel = "2017-02")
-  public void testPocCVE_2017_0415() throws Exception {
-      AdbUtils.runPocAssertNoCrashes("CVE-2017-0415", getDevice(), "mediaserver");
-  }
+    /**
+     *  b/32706020
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-02")
+    public void testPocCVE_2017_0415() throws Exception {
+        AdbUtils.runPocAssertNoCrashes("CVE-2017-0415", getDevice(), "mediaserver");
+    }
 
     /**
      *  b/31799863
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-02")
     public void testPocCVE_2016_8482() throws Exception {
         if(containsDriver(getDevice(), "/dev/nvmap")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
index f61e843..3dacc96 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_03.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,14 +16,22 @@
 
 package android.security.cts;
 
-import android.platform.test.annotations.SecurityTest;
 import java.util.concurrent.Callable;
 
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_03 extends SecurityTestCase {
 
     /**
      *  b/31824853
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2016_8479() throws Exception {
         if (containsDriver(getDevice(), "/dev/kgsl-3d0")) {
@@ -37,6 +45,7 @@
     /**
      *  b/33940449
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0508() throws Exception {
         if (containsDriver(getDevice(), "/dev/ion") &&
@@ -51,6 +60,7 @@
     /**
      *  b/33899363
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0333() throws Exception {
         if (containsDriver(getDevice(), "/dev/dri/renderD128")) {
@@ -63,6 +73,7 @@
     /**
      *  b/33245849
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0334() throws Exception {
         if (containsDriver(getDevice(), "/dev/dri/renderD129")) {
@@ -92,6 +103,7 @@
     /**
      * b/32707507
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0479() throws Exception {
         AdbUtils.runPocAssertNoCrashes("CVE-2017-0479", getDevice(), "audioserver");
@@ -100,6 +112,7 @@
     /*
      *  b/33178389
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testPocCVE_2017_0490() throws Exception {
         String bootCountBefore =
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
index 248e257..f5c8fe3 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_04.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,42 +17,51 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_04 extends SecurityTestCase {
 
-  /**
-   * b/32342065
-   */
-  @SecurityTest(minPatchLevel = "2017-04")
-  public void testPocCVE_2017_0553() throws Exception {
-    // Error code of 139 represents segmentation fault
-    getDevice().executeShellCommand("chmod +x /data/local/tmp/CVE-2017-0553");
-    assertFalse("Segfault found",
-        AdbUtils.runCommandGetExitCode("/data/local/tmp/CVE-2017-0553", getDevice())==139);
-  }
+    /**
+     * b/32342065
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-04")
+    public void testPocCVE_2017_0553() throws Exception {
+      // Error code of 139 represents segmentation fault
+      getDevice().executeShellCommand("chmod +x /data/local/tmp/CVE-2017-0553");
+      assertFalse("Segfault found",
+          AdbUtils.runCommandGetExitCode("/data/local/tmp/CVE-2017-0553", getDevice())==139);
+    }
 
-  /**
-   * b/72460737
-   */
-  @SecurityTest(minPatchLevel = "2017-04")
-  public void testPocCVE_2014_3145() throws Exception {
-    assertFalse("VULNERABLE DEVICE DETECTED",
-                AdbUtils.runPocCheckExitCode("CVE-2014-3145", getDevice(), 60));
-  }
+    /**
+     * b/72460737
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-04")
+    public void testPocCVE_2014_3145() throws Exception {
+      assertFalse("VULNERABLE DEVICE DETECTED",
+                  AdbUtils.runPocCheckExitCode("CVE-2014-3145", getDevice(), 60));
+    }
 
-  /**
-   * b/32813456
-   */
-  @SecurityTest(minPatchLevel = "2017-04")
-  public void testPocCVE_2016_10229() throws Exception {
-    String out = AdbUtils.runPoc("CVE-2016-10229", getDevice());
-    assertNotMatchesMultiLine("OVERWRITE", out);
-  }
+    /**
+     * b/32813456
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-04")
+    public void testPocCVE_2016_10229() throws Exception {
+      String out = AdbUtils.runPoc("CVE-2016-10229", getDevice());
+      assertNotMatchesMultiLine("OVERWRITE", out);
+    }
 
     /**
      * b/33621647
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testPocCVE_2017_0477() throws Exception {
         AdbUtils.pushResource("/CVE-2017-0477.gif", "/data/local/tmp/CVE-2017-0477.gif",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
index 70e224a..1ec6d89 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,16 +16,23 @@
 
 package android.security.cts;
 
-import android.platform.test.annotations.SecurityTest;
 import java.util.Arrays;
 import java.util.concurrent.Callable;
 
-@SecurityTest
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_05 extends SecurityTestCase {
 
     /**
      *  b/34277115
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testPocCVE_2017_0630() throws Exception {
         if (containsDriver(getDevice(), "/sys/kernel/debug/tracing/printk_formats")) {
@@ -54,6 +61,7 @@
     /*
      * CVE-2016-5862
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testPocCVE_2016_5862() throws Exception {
         if (containsDriver(getDevice(), "/dev/snd/controlC0")) {
@@ -64,6 +72,7 @@
     /**
      * CVE-2016-5867
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testPocCVE_2016_5867() throws Exception {
         if (containsDriver(getDevice(), "/dev/snd/controlC0")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
index c2c3e29..1f7e5e9 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_06.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
-import java.util.concurrent.TimeUnit;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_06 extends SecurityTestCase {
 
     /**
      * b/36392138
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testPocCVE_2017_0647() throws Exception {
         AdbUtils.pushResource("/CVE-2017-0647.zip", "/data/local/tmp/CVE-2017-0647.zip",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
index 29b7a39..d3a086a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_07.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_07 extends SecurityTestCase {
 
     /**
      * b/35443725
      **/
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testPocCVE_2016_2109() throws Exception {
       assertFalse("Overallocation detected!",
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
index 1659397..de7381e 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_09.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_09 extends SecurityTestCase {
 
     /**
      * b/63852675
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testPocCve_2017_6983() throws Exception {
       // Error code of 139 represents segmentation fault
@@ -53,14 +59,15 @@
                                       )==139);
     }
 
-  /**
-   * b/38195738
-   * b/36590192
-   */
-  @SecurityTest(minPatchLevel = "2017-09")
-  public void testPocBug_38195738() throws Exception {
-    if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
-      AdbUtils.runPocNoOutput("Bug-38195738", getDevice(), 60);
+    /**
+     * b/38195738
+     * b/36590192
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2017-09")
+    public void testPocBug_38195738() throws Exception {
+        if(containsDriver(getDevice(), "/dev/kgsl-3d0")) {
+            AdbUtils.runPocNoOutput("Bug-38195738", getDevice(), 60);
+        }
     }
-  }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
index 3fbf3d2..e592d0f 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_11 extends SecurityTestCase {
 
     /**
      * b/36075131
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-11")
     public void testPocCVE_2017_0859() throws Exception {
         AdbUtils.runCommandLine("logcat -c", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
index fed0ab5..71607c8 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc17_12.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc17_12 extends SecurityTestCase {
 
     /**
      * b/38045794
      */
+    @Test
     @SecurityTest(minPatchLevel = "2017-12")
     public void testPocCVE_2017_6262() throws Exception {
         if(containsDriver(getDevice(),"/dev/dri/renderD128")) {
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
index c9f48f9..377e219 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_02.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2016 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,26 +17,33 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_02 extends SecurityTestCase {
 
     /**
      * b/68953950
      */
-     @SecurityTest(minPatchLevel = "2018-02")
-     public void testPocCVE_2017_13232() throws Exception {
-       AdbUtils.runCommandLine("logcat -c" , getDevice());
-       AdbUtils.runPocNoOutput("CVE-2017-13232", getDevice(), 60);
-       String logcatOutput = AdbUtils.runCommandLine("logcat -d", getDevice());
-       assertNotMatchesMultiLine("APM_AudioPolicyManager: getOutputForAttr\\(\\) " +
-                                 "invalid attributes: usage=.{1,15} content=.{1,15} " +
-                                 "flags=.{1,15} tags=\\[A{256,}\\]", logcatOutput);
-     }
+    @Test
+    @SecurityTest(minPatchLevel = "2018-02")
+    public void testPocCVE_2017_13232() throws Exception {
+        AdbUtils.runCommandLine("logcat -c" , getDevice());
+        AdbUtils.runPocNoOutput("CVE-2017-13232", getDevice(), 60);
+        String logcatOutput = AdbUtils.runCommandLine("logcat -d", getDevice());
+        assertNotMatchesMultiLine("APM_AudioPolicyManager: getOutputForAttr\\(\\) " +
+                                  "invalid attributes: usage=.{1,15} content=.{1,15} " +
+                                  "flags=.{1,15} tags=\\[A{256,}\\]", logcatOutput);
+    }
 
     /**
      *  b/65853158
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testPocCVE_2017_13273() throws Exception {
         AdbUtils.runCommandLine("dmesg -c" ,getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
index 4bf7b80..c8f9c65 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_03.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,15 +17,22 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_03 extends SecurityTestCase {
 
-  /**
-   *  b/71389378
-   */
-  @SecurityTest(minPatchLevel = "2018-03")
-  public void testPocCVE_2017_13253() throws Exception {
-    String output = AdbUtils.runPoc("CVE-2017-13253", getDevice());
-    assertNotMatchesMultiLine("OVERFLOW DETECTED",output);
-  }
+    /**
+     *  b/71389378
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-03")
+    public void testPocCVE_2017_13253() throws Exception {
+        String output = AdbUtils.runPoc("CVE-2017-13253", getDevice());
+        assertNotMatchesMultiLine("OVERFLOW DETECTED",output);
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
index 99a4692..44b0d89 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_04.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
 import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_04 extends SecurityTestCase {
     /**
      * b/69683251
      * Does not require root but must be a hostside test to avoid
      * a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testPocCVE_2017_13286() throws Exception {
         getOomCatcher().setHighMemoryTest();
@@ -35,6 +41,7 @@
      * b/69634768
      * Does not require root but must be a hostside test to avoid a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testPocCVE_2017_13288() throws Exception {
         getOomCatcher().setHighMemoryTest();
@@ -45,6 +52,7 @@
      * b/70398564
      * Does not require root but must be a hostside test to avoid a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testPocCVE_2017_13289() throws Exception {
         getOomCatcher().setHighMemoryTest();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
index 69a4ed5..6b51f0a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,20 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_05 extends SecurityTestCase {
     /**
      * b/70721937
      * Does not require root but must be a hostside test to avoid a race
      * condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-05")
     public void testPocCVE_2017_13315() throws Exception {
         getOomCatcher().setHighMemoryTest();
@@ -35,6 +41,7 @@
      * b/73085795
      * Does not require root but must be a hostside test to avoid a race condition
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-05")
     public void testPocCVE_2017_13312() throws Exception {
         getOomCatcher().setHighMemoryTest();
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
index b270c69..c0aab3b 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_06.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,31 +17,38 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_06 extends SecurityTestCase {
 
-  /**
-   * CVE-2018-5884
-   */
-  @SecurityTest(minPatchLevel = "2018-06")
-  public void testPocCVE_2018_5884() throws Exception {
-    String wfd_service = AdbUtils.runCommandLine(
-        "pm list package com.qualcomm.wfd.service", getDevice());
-    if (wfd_service.contains("com.qualcomm.wfd.service")) {
-      String result = AdbUtils.runCommandLine(
-          "am broadcast -a qualcomm.intent.action.WIFI_DISPLAY_BITRATE --ei format 3 --ei value 32",
-          getDevice());
-      assertNotMatchesMultiLine("Broadcast completed", result);
+    /**
+     * CVE-2018-5884
+     */
+    @Test
+    @SecurityTest(minPatchLevel = "2018-06")
+    public void testPocCVE_2018_5884() throws Exception {
+        String wfd_service = AdbUtils.runCommandLine(
+                "pm list package com.qualcomm.wfd.service", getDevice());
+        if (wfd_service.contains("com.qualcomm.wfd.service")) {
+            String result = AdbUtils.runCommandLine(
+                    "am broadcast -a qualcomm.intent.action.WIFI_DISPLAY_BITRATE --ei format 3 --ei value 32",
+            getDevice());
+            assertNotMatchesMultiLine("Broadcast completed", result);
+        }
     }
-  }
 
-  /**
-   *  b/73172817
-   */
-  @SecurityTest
-  public void testPocCVE_2018_9344() throws Exception {
-      AdbUtils.runPocAssertNoCrashes(
-          "CVE-2018-9344", getDevice(), "android\\.hardware\\.drm@\\d\\.\\d-service");
-  }
+    /**
+     *  b/73172817
+     */
+    @Test
+    @SecurityTest
+    public void testPocCVE_2018_9344() throws Exception {
+        AdbUtils.runPocAssertNoCrashes("CVE-2018-9344", getDevice(),
+                "android\\.hardware\\.cas@\\d+?\\.\\d+?-service");
+    }
 }
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
index 173508c..172f0fc 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_07.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,17 +14,22 @@
  * limitations under the License.
  */
 
-
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_07 extends SecurityTestCase {
 
    /**
     * b/76221123
     */
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testPocCVE_2018_9424() throws Exception {
         AdbUtils.runPocAssertNoCrashes(
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
index dfc3de0..ef5b726 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_10.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_10 extends SecurityTestCase {
 
     /**
      *  b/111641492
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-10")
     public void testPocCVE_2018_9515() throws Exception {
         AdbUtils.runCommandLine("rm /sdcard/Android/data/CVE-2018-9515", getDevice());
@@ -40,6 +46,7 @@
     /**
      *  b/111274046
      */
+    @Test
     @SecurityTest
     public void testPocCVE_2018_9490() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2018-9490", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
index 81911ed..0abe1bb 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc18_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,24 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
 import static org.junit.Assert.*;
 
-@SecurityTest
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc18_11 extends SecurityTestCase {
 
     /**
-     *  b/111330641
-     */
-    @SecurityTest(minPatchLevel = "2018-11")
-    public void testPocCVE_2018_9525() throws Exception {
-        assertTrue(AdbUtils.runCommandGetExitCode(
-                "pm dump com.android.settings | grep SliceBroadcastReceiver", getDevice()) != 0);
-    }
-
-    /**
      *  b/113027383
      */
+    @Test
     @SecurityTest(minPatchLevel = "2018-11")
     public void testPocCVE_2018_9539() throws Exception {
         AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2018-9539", getDevice(), 300);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
index 520c9fc..5977b4a 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_03.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,16 +17,18 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
-import static org.junit.Assert.assertFalse;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_03 extends SecurityTestCase {
     /**
      * b/115739809
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-03")
     public void testPocBug_115739809() throws Exception {
         assertFalse(AdbUtils.runPocCheckExitCode("Bug-115739809", getDevice(), 30));
@@ -35,6 +37,7 @@
     /**
      * b/116855682
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-03")
     public void testPocCVE_2019_2025() throws Exception {
         AdbUtils.runPocNoOutput("CVE-2019-2025", getDevice(), 300);
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
index b9be0af..fd3b638 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_05.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,15 +18,18 @@
 
 import android.platform.test.annotations.SecurityTest;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.*;
 
-@SecurityTest
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_05 extends SecurityTestCase {
 
     /**
      * b/129556464
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2052() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2052", getDevice());
@@ -36,6 +39,7 @@
     /**
      * b/129556111
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2045() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2045", getDevice());
@@ -45,6 +49,7 @@
     /*
      * b/129556718
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2047() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2047", getDevice());
@@ -54,6 +59,7 @@
     /**
      * CVE-2019-2257
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2257() throws Exception {
         String result = AdbUtils.runCommandLine(
@@ -65,6 +71,7 @@
     /**
      * b/117555811
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-05")
     public void testPocCVE_2019_2051() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2051", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java
index c3651fb..67986fe 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_06.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_06 extends SecurityTestCase {
 
     /**
      * b/129556445
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-06")
     public void testPocCVE_2019_2097() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2097", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java
index b7fd2f2..c2ce29d 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_08.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,13 +17,19 @@
 package android.security.cts;
 
 import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-@SecurityTest
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_08 extends SecurityTestCase {
 
     /**
      * b/129556445
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-08")
     public void testPocCVE_2019_2130() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("CVE-2019-2130", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
index 07257fa..a79e2b1 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/Poc19_11.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,15 +18,18 @@
 
 import android.platform.test.annotations.SecurityTest;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
 
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.*;
 
-@SecurityTest
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class Poc19_11 extends SecurityTestCase {
 
     /**
      * b/138441919
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-11")
     public void testPocBug_138441919() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("bug_138441919", getDevice());
@@ -36,6 +39,7 @@
     /**
      * b/139806216
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-11")
     public void testPocBug_139806216() throws Exception {
         int code = AdbUtils.runProxyAutoConfig("bug_139806216", getDevice());
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
index ee38deb..a605358 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/SecurityTestCase.java
@@ -16,19 +16,27 @@
 
 package android.security.cts;
 
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.device.NativeDevice;
-import com.android.tradefed.testtype.DeviceTestCase;
 import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.ddmlib.Log;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.runner.RunWith;
 
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
-import com.android.ddmlib.Log;
 import java.util.concurrent.Callable;
 import java.math.BigInteger;
 
-public class SecurityTestCase extends DeviceTestCase {
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+public class SecurityTestCase extends BaseHostJUnit4Test {
 
     private static final String LOG_TAG = "SecurityTestCase";
     private static final int RADIX_HEX = 16;
@@ -45,10 +53,8 @@
     /**
      * Waits for device to be online, marks the most recent boottime of the device
      */
-    @Override
+    @Before
     public void setUp() throws Exception {
-        super.setUp();
-
         getDevice().waitForDeviceAvailable();
         getDevice().disableAdbRoot();
         updateKernelStartTime();
@@ -62,7 +68,7 @@
      * Makes sure the phone is online, and the ensure the current boottime is within 2 seconds
      * (due to rounding) of the previous boottime to check if The phone has crashed.
      */
-    @Override
+    @After
     public void tearDown() throws Exception {
         oomCatcher.stop(getDevice().getSerialNumber());
 
diff --git a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
index ecc086c..c4ae6b5 100644
--- a/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
+++ b/hostsidetests/securitybulletin/src/android/security/cts/TestMedia.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2019 The Android Open Source Project
+ * Copyright (C) 2020 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  * use this file except in compliance with the License. You may obtain a copy of
@@ -18,67 +18,46 @@
 
 import com.android.tradefed.device.ITestDevice;
 import com.android.tradefed.log.LogUtil.CLog;
-import android.platform.test.annotations.SecurityTest;
-import java.util.regex.Pattern;
 
-@SecurityTest
+import android.platform.test.annotations.SecurityTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+
+import static org.junit.Assert.*;
+
+@RunWith(DeviceJUnit4ClassRunner.class)
 public class TestMedia extends SecurityTestCase {
 
-    final static int TIMEOUT_SEC = 9 * 60;
-    final static String RESOURCE_ROOT = "/";
-    final static String TMP_FILE_PATH = "/data/local/tmp/";
 
-    /****************************************************************
-     * To prevent merge conflicts, add tests for N below this comment,
-     * before any existing test methods
-     ****************************************************************/
+    /******************************************************************************
+     * To prevent merge conflicts, add tests for N below this comment, before any
+     * existing test methods
+     ******************************************************************************/
+
+    /******************************************************************************
+     * To prevent merge conflicts, add tests for O below this comment, before any
+     * existing test methods
+     ******************************************************************************/
 
 
-    /****************************************************************
-     * To prevent merge conflicts, add tests for O below this comment,
-     * before any existing test methods
-     ****************************************************************/
-
-
-    /****************************************************************
-     * To prevent merge conflicts, add tests for P below this comment,
-     * before any existing test methods
-     ****************************************************************/
+    /******************************************************************************
+     * To prevent merge conflicts, add tests for P below this comment, before any
+     * existing test methods
+     ******************************************************************************/
 
     /**
-     * Pushes input files, runs the PoC and checks for crash and hang
-     *
-     * @param binaryName name of the binary
-     * @param inputFiles files required as input
-     * @param arguments arguments for running the binary
-     * @param device device to be run on
-     * @param errPattern error patterns to be checked for
-     */
-    public static void runMediaTest(String binaryName,
-            String inputFiles[], String arguments, ITestDevice device,
-            String processPatternStrings[]) throws Exception {
-        if (inputFiles != null) {
-            for (String tempFile : inputFiles) {
-                AdbUtils.pushResource(RESOURCE_ROOT + tempFile,
-                        TMP_FILE_PATH + tempFile, device);
-            }
-        }
-        AdbUtils.runCommandLine("logcat -c", device);
-        AdbUtils.runWithTimeoutDeleteFiles(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    AdbUtils.runPocNoOutput(binaryName, device,
-                            TIMEOUT_SEC + 30, arguments);
-                } catch (Exception e) {
-                    CLog.w("Exception: " + e.getMessage());
-                }
-            }
-        }, TIMEOUT_SEC * 1000, device, inputFiles);
-
-        AdbUtils.assertNoCrashes(device, binaryName);
-        if (processPatternStrings != null) {
-            AdbUtils.assertNoCrashes(device, processPatternStrings);
-        }
+     * b/112662184
+     * Vulnerability Behaviour: EXIT_VULNERABLE (113)
+     **/
+    @SecurityTest(minPatchLevel = "2018-11")
+    @Test
+    public void testPocCVE_2018_9536() throws Exception {
+        AdbUtils.runPocAssertExitStatusNotVulnerable("CVE-2018-9536", getDevice(), 60);
     }
+
+    /******************************************************************************
+     * To prevent merge conflicts, add tests for Q below this comment, before any
+     * existing test methods
+     ******************************************************************************/
 }
diff --git a/hostsidetests/shortcuts/deviceside/upgrade/Android.bp b/hostsidetests/shortcuts/deviceside/upgrade/Android.bp
index f72ead1..7f9d2a7 100644
--- a/hostsidetests/shortcuts/deviceside/upgrade/Android.bp
+++ b/hostsidetests/shortcuts/deviceside/upgrade/Android.bp
@@ -21,6 +21,9 @@
     ],
     srcs: ["src/**/*.java"],
     resource_dirs: ["version1/res"],
+    static_libs: [
+        "compatibility-device-util-axt",
+    ],
     // Tag this module as a cts test artifact
     test_suites: [
         "cts",
diff --git a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
index ec6291d..f4887e9 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/atom/DeviceAtomTestCase.java
@@ -51,6 +51,7 @@
         super.setUp();
         getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
         installTestApp();
+        Thread.sleep(1000);
     }
 
     @Override
diff --git a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
index ae40111..90a7f6e 100644
--- a/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
+++ b/hostsidetests/statsd/src/android/cts/statsd/validation/ValidationTests.java
@@ -145,6 +145,12 @@
             return;
         }
         if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return;
+
+        // getUid() needs shell command via ADB. turnScreenOff() sometimes let system go to suspend.
+        // ADB disconnection causes failure of getUid(). Move up here before turnScreenOff().
+        final int EXPECTED_UID = getUid();
+
+
         turnScreenOn(); // To ensure that the ScreenOff later gets logged.
         // AoD needs to be turned off because the screen should go into an off state. But, if AoD is
         // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON.
@@ -164,7 +170,6 @@
 
         final String EXPECTED_TAG = "StatsdPartialWakelock";
         final long EXPECTED_TAG_HASH = Long.parseUnsignedLong("15814523794762874414");
-        final int EXPECTED_UID = getUid();
         final int MIN_DURATION = 350;
         final int MAX_DURATION = 700;
 
diff --git a/hostsidetests/telephony/src/android/telephony/cts/TelephonyHostTest.java b/hostsidetests/telephony/src/android/telephony/cts/TelephonyHostTest.java
index c814a64..06f545f 100644
--- a/hostsidetests/telephony/src/android/telephony/cts/TelephonyHostTest.java
+++ b/hostsidetests/telephony/src/android/telephony/cts/TelephonyHostTest.java
@@ -41,11 +41,4 @@
                 /*enabledChanges*/ImmutableSet.of(PHONE_STATE_LISTENER_LIMIT_CHANGE_ID),
                 /*disabledChanges*/ ImmutableSet.of());
     }
-
-    public void testWithChangeDisabled() throws Exception {
-        runDeviceCompatTest(TEST_PKG, ".TelephonyTest",
-                "testListenerRegistrationWithChangeDisabled",
-                /*enabledChanges*/ImmutableSet.of(),
-                /*disabledChanges*/ ImmutableSet.of(PHONE_STATE_LISTENER_LIMIT_CHANGE_ID));
-    }
 }
diff --git a/tests/app/src/android/app/cts/NotificationManagerTest.java b/tests/app/src/android/app/cts/NotificationManagerTest.java
index fb6854a..72b2936 100644
--- a/tests/app/src/android/app/cts/NotificationManagerTest.java
+++ b/tests/app/src/android/app/cts/NotificationManagerTest.java
@@ -98,9 +98,11 @@
 
 import junit.framework.Assert;
 
+import java.io.BufferedReader;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
@@ -989,6 +991,38 @@
         }
     }
 
+    public void testSuspendPackage_withoutShellPermission() throws Exception {
+        if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
+            return;
+        }
+
+        try {
+            Process proc = Runtime.getRuntime().exec("cmd notification suspend_package "
+                    + mContext.getPackageName());
+
+            // read output of command
+            BufferedReader reader =
+                    new BufferedReader(new InputStreamReader(proc.getInputStream()));
+            StringBuilder output = new StringBuilder();
+            String line = reader.readLine();
+            while (line != null) {
+                output.append(line);
+                line = reader.readLine();
+            }
+            reader.close();
+            final String outputString = output.toString();
+
+            proc.waitFor();
+
+            // check that the output string had an error / disallowed call since it didn't have
+            // shell permission to suspend the package
+            assertTrue(outputString.contains("Error"));
+            assertTrue(outputString.contains("Disallowed call"));
+        } catch (InterruptedException e) {
+            fail("Unsuccessful shell command");
+        }
+    }
+
     public void testSuspendPackage() throws Exception {
         if (mActivityManager.isLowRamDevice() && !mPackageManager.hasSystemFeature(FEATURE_WATCH)) {
             return;
diff --git a/tests/media/AndroidTest.xml b/tests/media/AndroidTest.xml
index ccf41c7..a618ac0 100644
--- a/tests/media/AndroidTest.xml
+++ b/tests/media/AndroidTest.xml
@@ -25,7 +25,7 @@
     </target_preparer>
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.MediaPreparer">
         <option name="push-all" value="true" />
-        <option name="media-folder-name" value="CtsMediaV2TestCases" />
+        <option name="media-folder-name" value="CtsMediaV2TestCases-1.2" />
         <option name="dynamic-config-module" value="CtsMediaV2TestCases" />
     </target_preparer>
     <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
diff --git a/tests/media/DynamicConfig.xml b/tests/media/DynamicConfig.xml
index 4d6d9d9..384d3d7 100644
--- a/tests/media/DynamicConfig.xml
+++ b/tests/media/DynamicConfig.xml
@@ -1,6 +1,6 @@
 <dynamicConfig>
     <entry key="media_files_url">
-      <value>https://storage.googleapis.com/android_media/cts/tests/media/CtsMediaV2TestCases-1.1.zip</value>
+      <value>https://storage.googleapis.com/android_media/cts/tests/media/CtsMediaV2TestCases-1.2.zip</value>
     </entry>
 </dynamicConfig>
 
diff --git a/tests/media/jni/NativeCodecTestBase.cpp b/tests/media/jni/NativeCodecTestBase.cpp
index 750abe6..b07c1c3 100644
--- a/tests/media/jni/NativeCodecTestBase.cpp
+++ b/tests/media/jni/NativeCodecTestBase.cpp
@@ -528,10 +528,11 @@
 
 int CodecTestBase::getWidth(AMediaFormat* format) {
     int width = -1;
-    int cropLeft, cropRight;
+    int cropLeft, cropRight, cropTop, cropBottom;
     AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_WIDTH, &width);
-    if (AMediaFormat_getInt32(format, "crop-left", &cropLeft) &&
-        AMediaFormat_getInt32(format, "crop-right", &cropRight)) {
+    if (AMediaFormat_getRect(format, "crop", &cropLeft, &cropTop, &cropRight, &cropBottom) ||
+        (AMediaFormat_getInt32(format, "crop-left", &cropLeft) &&
+        AMediaFormat_getInt32(format, "crop-right", &cropRight))) {
         width = cropRight + 1 - cropLeft;
     }
     return width;
@@ -539,10 +540,11 @@
 
 int CodecTestBase::getHeight(AMediaFormat* format) {
     int height = -1;
-    int cropTop, cropBottom;
+    int cropLeft, cropRight, cropTop, cropBottom;
     AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_HEIGHT, &height);
-    if (AMediaFormat_getInt32(format, "crop-top", &cropTop) &&
-        AMediaFormat_getInt32(format, "crop-bottom", &cropBottom)) {
+    if (AMediaFormat_getRect(format, "crop", &cropLeft, &cropTop, &cropRight, &cropBottom) ||
+        (AMediaFormat_getInt32(format, "crop-top", &cropTop) &&
+        AMediaFormat_getInt32(format, "crop-bottom", &cropBottom))) {
         height = cropBottom + 1 - cropTop;
     }
     return height;
diff --git a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
index 515f455..4185d7c 100644
--- a/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
+++ b/tests/media/src/android/mediav2/cts/EncoderColorAspectsTest.java
@@ -57,7 +57,6 @@
     private int mTrackID = -1;
 
     private ArrayList<MediaCodec.BufferInfo> mInfoList = new ArrayList<>();
-    private int mTotalSize;
 
     private ArrayList<String> mCheckESList = new ArrayList<>();
 
@@ -100,8 +99,8 @@
                 mMuxer.writeSampleData(mTrackID, buf, info);
             }
             MediaCodec.BufferInfo copy = new MediaCodec.BufferInfo();
-            copy.set(mTotalSize + info.offset, info.size, info.presentationTimeUs, info.flags);
-            mTotalSize += info.size;
+            copy.set(mOutputBuff.getOutStreamSize(), info.size, info.presentationTimeUs,
+                    info.flags);
             mInfoList.add(copy);
         }
         super.dequeueOutput(bufferIndex, info);
@@ -166,7 +165,6 @@
             mCodec = MediaCodec.createByCodecName(encoder);
             mOutputBuff.reset();
             mInfoList.clear();
-            mTotalSize = 0;
             /* TODO(b/157523045) */
             if (mRange <= UNSPECIFIED || mStandard <= UNSPECIFIED ||
                     mTransferCurve <= UNSPECIFIED) {
diff --git a/tests/media/src/android/mediav2/cts/ExtractorTest.java b/tests/media/src/android/mediav2/cts/ExtractorTest.java
index a0aaef1..cbfc9c6 100644
--- a/tests/media/src/android/mediav2/cts/ExtractorTest.java
+++ b/tests/media/src/android/mediav2/cts/ExtractorTest.java
@@ -864,6 +864,10 @@
         public void testExtract() throws IOException {
             assumeTrue(shouldRunTest(mMime));
             assertTrue(mSrcFiles.length > 1);
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_OPUS));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_MPEG));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC));
             MediaExtractor refExtractor = new MediaExtractor();
             refExtractor.setDataSource(mInpPrefix + mSrcFiles[0]);
             boolean isOk = true;
@@ -952,6 +956,9 @@
         @Test
         public void testSeekToZero() throws IOException {
             assumeTrue(shouldRunTest(mMime));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_MPEG));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC));
             boolean isOk = true;
             for (String srcFile : mSrcFiles) {
                 MediaExtractor extractor = new MediaExtractor();
@@ -1033,6 +1040,10 @@
         public void testExtractNative() {
             assumeTrue(shouldRunTest(mMime));
             assertTrue(mSrcFiles.length > 1);
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_OPUS));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_MPEG));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC));
             boolean isOk = true;
             for (int i = 1; i < mSrcFiles.length; i++) {
                 if (!nativeTestExtract(mInpPrefix + mSrcFiles[0], mInpPrefix + mSrcFiles[i],
@@ -1085,6 +1096,9 @@
         @Test
         public void testSeekToZeroNative() {
             assumeTrue(shouldRunTest(mMime));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_MPEG));
+            assumeTrue("TODO(b/146925481)", !mMime.equals(MediaFormat.MIMETYPE_AUDIO_AAC));
             boolean isOk = true;
             for (String srcFile : mSrcFiles) {
                 if (!nativeTestSeekToZero(mInpPrefix + srcFile, mMime)) {
diff --git a/tests/media/src/android/mediav2/cts/MuxerTest.java b/tests/media/src/android/mediav2/cts/MuxerTest.java
index 7311dc9..44c5591 100644
--- a/tests/media/src/android/mediav2/cts/MuxerTest.java
+++ b/tests/media/src/android/mediav2/cts/MuxerTest.java
@@ -845,6 +845,10 @@
         public void testOffsetPresentationTime() throws IOException {
             final int OFFSET_TS = 111000;
             Assume.assumeTrue(shouldRunTest(mOutFormat));
+            Assume.assumeTrue("TODO(b/148978457)",
+                    mOutFormat != MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+            Assume.assumeTrue("TODO(b/148978457)",
+                    mOutFormat != MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP);
             Assume.assumeTrue("TODO(b/146423022)",
                     mOutFormat != MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM);
             Assume.assumeTrue("TODO(b/146421018)",
@@ -874,6 +878,10 @@
         @Test
         public void testOffsetPresentationTimeNative() {
             Assume.assumeTrue(shouldRunTest(mOutFormat));
+            Assume.assumeTrue("TODO(b/148978457)",
+                    mOutFormat != MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
+            Assume.assumeTrue("TODO(b/148978457)",
+                    mOutFormat != MediaMuxer.OutputFormat.MUXER_OUTPUT_3GPP);
             Assume.assumeTrue("TODO(b/146423022)",
                     mOutFormat != MediaMuxer.OutputFormat.MUXER_OUTPUT_WEBM);
             Assume.assumeTrue("TODO(b/146421018)",
@@ -985,6 +993,8 @@
         public void testSimpleMux() throws IOException {
             Assume.assumeTrue("TODO(b/146421018)",
                     !mMime.equals(MediaFormat.MIMETYPE_AUDIO_OPUS));
+            Assume.assumeTrue("TODO(b/146923287)",
+                    !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
             MuxerTestHelper mediaInfo = new MuxerTestHelper(mInpPath, mMime);
             assertEquals("error! unexpected track count", 1, mediaInfo.getTrackCount());
             for (int format = MUXER_OUTPUT_FIRST; format <= MUXER_OUTPUT_LAST; format++) {
@@ -1014,6 +1024,8 @@
         public void testSimpleMuxNative() {
             Assume.assumeTrue("TODO(b/146421018)",
                     !mMime.equals(MediaFormat.MIMETYPE_AUDIO_OPUS));
+            Assume.assumeTrue("TODO(b/146923287)",
+                    !mMime.equals(MediaFormat.MIMETYPE_AUDIO_VORBIS));
             assertTrue(nativeTestSimpleMux(mInpPath, mOutPath, mMime, selector));
         }
     }
diff --git a/tests/media/src/android/mediav2/cts/WorkDir.java b/tests/media/src/android/mediav2/cts/WorkDir.java
index 581e9ad..a5e635c 100644
--- a/tests/media/src/android/mediav2/cts/WorkDir.java
+++ b/tests/media/src/android/mediav2/cts/WorkDir.java
@@ -40,7 +40,7 @@
             // user has specified the mediaDirString via instrumentation-arg
             return mediaDirString + ((mediaDirString.endsWith("/")) ? "" : "/");
         } else {
-            return (getTopDirString() + "test/CtsMediaV2TestCases/");
+            return (getTopDirString() + "test/CtsMediaV2TestCases-1.2/");
         }
     }
 }
\ No newline at end of file
diff --git a/tests/signature/api-check/android-test-base-28-api/Android.bp b/tests/signature/api-check/android-test-base-28-api/Android.bp
index 2b24bc1..31263b4 100644
--- a/tests/signature/api-check/android-test-base-28-api/Android.bp
+++ b/tests/signature/api-check/android-test-base-28-api/Android.bp
@@ -18,7 +18,7 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-android-test-base-current-txt",
+        ":cts-android-test-base-current-api-gz",
     ],
     min_sdk_version: "27",
 
diff --git a/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml b/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml
index ef43237..e048dc3 100644
--- a/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-base-28-api/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.android_test_base_28" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.api28.test.SignatureTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.txt" />
+        <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/android-test-base-current-api/Android.bp b/tests/signature/api-check/android-test-base-current-api/Android.bp
index ead699b..8ef01a1 100644
--- a/tests/signature/api-check/android-test-base-current-api/Android.bp
+++ b/tests/signature/api-check/android-test-base-current-api/Android.bp
@@ -18,7 +18,7 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-android-test-base-current-txt",
+        ":cts-android-test-base-current-api-gz",
     ],
 
     use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml
index bbf942e..30da659 100644
--- a/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-base-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.android_test_base_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.current.test.SignatureTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.txt" />
+        <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/android-test-mock-current-api/Android.bp b/tests/signature/api-check/android-test-mock-current-api/Android.bp
index 9f3ccbf..44c7a8a 100644
--- a/tests/signature/api-check/android-test-mock-current-api/Android.bp
+++ b/tests/signature/api-check/android-test-mock-current-api/Android.bp
@@ -18,7 +18,7 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-android-test-mock-current-txt",
+        ":cts-android-test-mock-current-api-gz",
     ],
 
     use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
index 19dbe7b..f8ab351 100644
--- a/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-mock-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.android_test_mock_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.current.mock.SignatureTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.txt" />
+        <option name="instrumentation-arg" key="expected-api-files" value="android-test-mock-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/android-test-runner-current-api/Android.bp b/tests/signature/api-check/android-test-runner-current-api/Android.bp
index 84ba5e9..80d2803 100644
--- a/tests/signature/api-check/android-test-runner-current-api/Android.bp
+++ b/tests/signature/api-check/android-test-runner-current-api/Android.bp
@@ -18,9 +18,9 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-android-test-base-current-txt",
-        ":cts-android-test-mock-current-txt",
-        ":cts-android-test-runner-current-txt",
+        ":cts-android-test-base-current-api-gz",
+        ":cts-android-test-mock-current-api-gz",
+        ":cts-android-test-runner-current-api-gz",
     ],
 
     use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
index 1c6ed19..5c18209 100644
--- a/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/android-test-runner-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.android_test_runner_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.current.runner.SignatureTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.txt,android-test-mock-current.txt,android-test-runner-current.txt" />
+        <option name="instrumentation-arg" key="expected-api-files" value="android-test-base-current.api.gz,android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/Android.bp b/tests/signature/api-check/apache-http-legacy-27-api/Android.bp
index 13e99d0..d649145 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/Android.bp
+++ b/tests/signature/api-check/apache-http-legacy-27-api/Android.bp
@@ -18,8 +18,8 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-current-txt",
-        ":cts-apache-http-legacy-current-txt",
+        ":cts-current-api-gz",
+        ":cts-apache-http-legacy-current-api-gz",
     ],
     min_sdk_version: "27",
 
diff --git a/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
index f308253..ff5cff8 100644
--- a/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-27-api/AndroidTest.xml
@@ -27,8 +27,8 @@
         <option name="package" value="android.signature.cts.api.apache_http_legacy_27" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.api27.http.SignatureTest" />
-        <option name="instrumentation-arg" key="base-api-files" value="current.txt" />
-        <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.txt" />
+        <option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
+        <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/Android.bp b/tests/signature/api-check/apache-http-legacy-current-api/Android.bp
index bf778fc..ffda5cc 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/Android.bp
+++ b/tests/signature/api-check/apache-http-legacy-current-api/Android.bp
@@ -18,7 +18,7 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-apache-http-legacy-current-txt",
+        ":cts-apache-http-legacy-current-api-gz",
     ],
 
     use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
index 3fa2220..5b15e41 100644
--- a/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-current-api/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.apache_http_legacy_current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.current.http.SignatureTest" />
-        <option name="instrumentation-arg" key="unexpected-api-files" value="apache-http-legacy-current.txt" />
+        <option name="instrumentation-arg" key="unexpected-api-files" value="apache-http-legacy-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp b/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp
index 5d7a473..f811f85 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/Android.bp
@@ -18,8 +18,8 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-current-txt",
-        ":cts-apache-http-legacy-current-txt",
+        ":cts-current-api-gz",
+        ":cts-apache-http-legacy-current-api-gz",
     ],
 
     use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
index 0c75fa6..7216d25 100644
--- a/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
+++ b/tests/signature/api-check/apache-http-legacy-uses-library-api/AndroidTest.xml
@@ -27,8 +27,8 @@
         <option name="package" value="android.signature.cts.api.apache_http_legacy_uses_library" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.http_uses_library.SignatureTest" />
-        <option name="instrumentation-arg" key="base-api-files" value="current.txt" />
-        <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.txt" />
+        <option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
+        <option name="instrumentation-arg" key="expected-api-files" value="apache-http-legacy-current.api.gz" />
         <option name="runtime-hint" value="5s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/current-api/Android.bp b/tests/signature/api-check/current-api/Android.bp
index 1e867d9..61656c3 100644
--- a/tests/signature/api-check/current-api/Android.bp
+++ b/tests/signature/api-check/current-api/Android.bp
@@ -18,10 +18,10 @@
         "signature-api-check-defaults",
     ],
     java_resources: [
-        ":cts-current-txt",
-        ":cts-android-test-base-current-txt",
-        ":cts-android-test-mock-current-txt",
-        ":cts-android-test-runner-current-txt",
+        ":cts-current-api-gz",
+        ":cts-android-test-base-current-api-gz",
+        ":cts-android-test-mock-current-api-gz",
+        ":cts-android-test-runner-current-api-gz",
     ],
 
     use_embedded_native_libs: false,
diff --git a/tests/signature/api-check/current-api/AndroidTest.xml b/tests/signature/api-check/current-api/AndroidTest.xml
index 421306f..f14a503 100644
--- a/tests/signature/api-check/current-api/AndroidTest.xml
+++ b/tests/signature/api-check/current-api/AndroidTest.xml
@@ -28,8 +28,8 @@
         <option name="package" value="android.signature.cts.api.current" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.current.SignatureTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="current.txt" />
-        <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-base-current.txt,android-test-mock-current.txt,android-test-runner-current.txt" />
+        <option name="instrumentation-arg" key="expected-api-files" value="current.api.gz" />
+        <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-base-current.api.gz,android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/shared-libs-api/Android.mk b/tests/signature/api-check/shared-libs-api/Android.mk
index d921e6b..92c66d1 100644
--- a/tests/signature/api-check/shared-libs-api/Android.mk
+++ b/tests/signature/api-check/shared-libs-api/Android.mk
@@ -22,13 +22,13 @@
   $(foreach api_level,public system,\
     $(foreach lib,$(filter-out android,$(filter-out %removed,$(filter-out incompatibilities,\
       $(basename $(notdir $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(ver)/$(api_level)/api/*.txt)))))),\
-        $(eval all_shared_libs_modules += $(lib)-$(ver)-$(api_level).txt))))
+        $(eval all_shared_libs_modules += $(lib)-$(ver)-$(api_level).api))))
 
 all_shared_libs_files := $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(all_shared_libs_modules))
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := cts-shared-libs-all.txt
-LOCAL_MODULE_STEM := shared-libs-all.txt.zip
+LOCAL_MODULE := cts-shared-libs-all.api
+LOCAL_MODULE_STEM := shared-libs-all.api.zip
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
 include $(BUILD_SYSTEM)/base_rules.mk
diff --git a/tests/signature/api-check/shared-libs-api/AndroidTest.xml b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
index d6cc7fc..a679079 100644
--- a/tests/signature/api-check/shared-libs-api/AndroidTest.xml
+++ b/tests/signature/api-check/shared-libs-api/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.shared_libs" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.SignatureMultiLibsTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="shared-libs-all.txt.zip" />
+        <option name="instrumentation-arg" key="expected-api-files" value="shared-libs-all.api.zip" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api-check/system-annotation/Android.bp b/tests/signature/api-check/system-annotation/Android.bp
index d328107..6b63792 100644
--- a/tests/signature/api-check/system-annotation/Android.bp
+++ b/tests/signature/api-check/system-annotation/Android.bp
@@ -21,10 +21,10 @@
         "compatibility-device-util-axt",
     ],
     java_resources: [
-        ":cts-system-current-txt",
-        ":cts-system-removed-txt",
-        ":cts-car-system-current-txt",
-        ":cts-car-system-removed-txt",
+        ":cts-system-current-api-gz",
+        ":cts-system-removed-api-gz",
+        ":cts-car-system-current-api-gz",
+        ":cts-car-system-removed-api-gz",
     ],
     min_sdk_version: "27",
 
diff --git a/tests/signature/api-check/system-annotation/AndroidTest.xml b/tests/signature/api-check/system-annotation/AndroidTest.xml
index 816ff81..4a61a40 100644
--- a/tests/signature/api-check/system-annotation/AndroidTest.xml
+++ b/tests/signature/api-check/system-annotation/AndroidTest.xml
@@ -27,7 +27,7 @@
         <option name="package" value="android.signature.cts.api.system_annotation" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.AnnotationTest" />
-        <option name="instrumentation-arg" key="expected-api-files" value="system-current.txt,system-removed.txt,car-system-current.txt,car-system-removed.txt" />
+        <option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz,car-system-current.api.gz,car-system-removed.api.gz" />
         <option name="instrumentation-arg" key="annotation-for-exact-match" value="@android.annotation.SystemApi\(client=PRIVILEGED_APPS\)" />
         <option name="runtime-hint" value="30s" />
     </test>
diff --git a/tests/signature/api-check/system-api/Android.mk b/tests/signature/api-check/system-api/Android.mk
index d6afb39..29636af 100644
--- a/tests/signature/api-check/system-api/Android.mk
+++ b/tests/signature/api-check/system-api/Android.mk
@@ -17,14 +17,14 @@
 all_system_api_modules :=
 $(foreach ver,$(PLATFORM_SYSTEMSDK_VERSIONS),\
   $(if $(call math_is_number,$(ver)),\
-    $(eval all_system_api_modules += system-$(ver).txt)\
+    $(eval all_system_api_modules += system-$(ver).api)\
   )\
 )
 all_system_api_files := $(addprefix $(COMPATIBILITY_TESTCASES_OUT_cts)/,$(all_system_api_modules))
 
 include $(CLEAR_VARS)
-LOCAL_MODULE := cts-system-all.txt
-LOCAL_MODULE_STEM := system-all.txt.zip
+LOCAL_MODULE := cts-system-all.api
+LOCAL_MODULE_STEM := system-all.api.zip
 LOCAL_MODULE_CLASS := ETC
 LOCAL_MODULE_PATH = $(TARGET_OUT_DATA_ETC)
 LOCAL_COMPATIBILITY_SUITE := arcts cts vts10 general-tests
@@ -46,11 +46,11 @@
 LOCAL_JAVA_RESOURCE_FILES := $(all_system_api_zip_file)
 
 LOCAL_SIGNATURE_API_FILES := \
-    current.txt \
-    android-test-mock-current.txt \
-    android-test-runner-current.txt \
-    system-current.txt \
-    system-removed.txt \
+    current.api.gz \
+    android-test-mock-current.api.gz \
+    android-test-runner-current.api.gz \
+    system-current.api.gz \
+    system-removed.api.gz \
 
 include $(LOCAL_PATH)/../build_signature_apk.mk
 
diff --git a/tests/signature/api-check/system-api/AndroidTest.xml b/tests/signature/api-check/system-api/AndroidTest.xml
index 646338e..904dce1 100644
--- a/tests/signature/api-check/system-api/AndroidTest.xml
+++ b/tests/signature/api-check/system-api/AndroidTest.xml
@@ -27,9 +27,9 @@
         <option name="package" value="android.signature.cts.api.system" />
         <option name="runner" value="repackaged.android.test.InstrumentationTestRunner" />
         <option name="class" value="android.signature.cts.api.system.SignatureTest" />
-        <option name="instrumentation-arg" key="base-api-files" value="current.txt" />
-        <option name="instrumentation-arg" key="expected-api-files" value="system-current.txt,system-removed.txt,system-all.txt.zip" />
-        <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.txt,android-test-runner-current.txt" />
+        <option name="instrumentation-arg" key="base-api-files" value="current.api.gz" />
+        <option name="instrumentation-arg" key="expected-api-files" value="system-current.api.gz,system-removed.api.gz,system-all.api.zip" />
+        <option name="instrumentation-arg" key="unexpected-api-files" value="android-test-mock-current.api.gz,android-test-runner-current.api.gz" />
         <option name="runtime-hint" value="30s" />
     </test>
 </configuration>
diff --git a/tests/signature/api/Android.bp b/tests/signature/api/Android.bp
index 8c3e12a..424c881 100644
--- a/tests/signature/api/Android.bp
+++ b/tests/signature/api/Android.bp
@@ -12,115 +12,111 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-default_visibility = [
-    "//cts/tests/signature/api-check:__subpackages__",
-    "//cts/tests/signature/intent-check",
-]
+genrule_defaults {
+    name: "signature-cts-api-api-gz",
+    cmd: "$(location metalava) --no-banner -convert2xmlnostrip $(in) $(genDir)/api.xml && gzip -c $(genDir)/api.xml > $(out)",
+    tools: ["metalava"],
+    visibility: [
+        "//cts/tests/signature/api-check:__subpackages__",
+        "//cts/tests/signature/intent-check",
+    ],
+}
 
 genrule {
-    name: "cts-current-txt",
-    visibility: default_visibility,
+    name: "cts-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":frameworks-base-api-current.txt",
     ],
     out: [
-        "current.txt",
+        "current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-system-current-txt",
-    visibility: default_visibility,
+    name: "cts-system-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":frameworks-base-api-system-current.txt",
     ],
     out: [
-        "system-current.txt",
+        "system-current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-system-removed-txt",
-    visibility: default_visibility,
+    name: "cts-system-removed-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":frameworks-base-api-system-removed.txt",
     ],
     out: [
-        "system-removed.txt",
+        "system-removed.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-android-test-base-current-txt",
-    visibility: default_visibility,
+    name: "cts-android-test-base-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":android-test-base-current.txt",
     ],
     out: [
-        "android-test-base-current.txt",
+        "android-test-base-current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-android-test-mock-current-txt",
-    visibility: default_visibility,
+    name: "cts-android-test-mock-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":android-test-mock-current.txt",
     ],
     out: [
-        "android-test-mock-current.txt",
+        "android-test-mock-current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-android-test-runner-current-txt",
-    visibility: default_visibility,
+    name: "cts-android-test-runner-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":android-test-runner-current.txt",
     ],
     out: [
-        "android-test-runner-current.txt",
+        "android-test-runner-current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-apache-http-legacy-current-txt",
-    visibility: default_visibility,
+    name: "cts-apache-http-legacy-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":apache-http-legacy-current.txt",
     ],
     out: [
-        "apache-http-legacy-current.txt",
+        "apache-http-legacy-current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-car-system-current-txt",
-    visibility: default_visibility,
+    name: "cts-car-system-current-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":car-api-system-current.txt",
     ],
     out: [
-        "car-system-current.txt",
+        "car-system-current.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
 
 genrule {
-    name: "cts-car-system-removed-txt",
-    visibility: default_visibility,
+    name: "cts-car-system-removed-api-gz",
+    defaults: ["signature-cts-api-api-gz"],
     srcs: [
         ":car-api-system-removed.txt",
     ],
     out: [
-        "car-system-removed.txt",
+        "car-system-removed.api.gz",
     ],
-    cmd: "cp $(in) $(out)",
 }
diff --git a/tests/signature/api/Android.mk b/tests/signature/api/Android.mk
index dd3bfde..11ab071 100644
--- a/tests/signature/api/Android.mk
+++ b/tests/signature/api/Android.mk
@@ -16,23 +16,24 @@
 
 LOCAL_PATH := $(call my-dir)
 
-# $(1) name of the txt file to be created
+# $(1) name of the xml file to be created
 # $(2) path to the api text file
-define copy_api_txt_file
+define build_xml_api_file
 include $(CLEAR_VARS)
 LOCAL_MODULE := cts-$(subst .,-,$(1))
 LOCAL_MODULE_STEM := $(1)
 LOCAL_MODULE_CLASS := ETC
-LOCAL_COMPATIBILITY_SUITE := arcts cts vts10 general-tests
+LOCAL_COMPATIBILITY_SUITE := arcts cts vts general-tests
 include $(BUILD_SYSTEM)/base_rules.mk
 $$(LOCAL_BUILT_MODULE): $(2) | $(APICHECK)
-	@echo "Copying API file $$< -> $$@"
-	$$(copy-file-to-target)
+	@echo "Convert API file $$< -> $$@"
+	@mkdir -p $$(dir $$@)
+	$(hide) $(APICHECK_COMMAND) -convert2xmlnostrip $$< $$@
 endef
 
 $(foreach ver,$(PLATFORM_SYSTEMSDK_VERSIONS),\
   $(if $(call math_is_number,$(ver)),\
-    $(eval $(call copy_api_txt_file,system-$(ver).txt,prebuilts/sdk/$(ver)/system/api/android.txt))\
+    $(eval $(call build_xml_api_file,system-$(ver).api,prebuilts/sdk/$(ver)/system/api/android.txt))\
   )\
 )
 
@@ -40,4 +41,7 @@
   $(foreach api_level,public system,\
     $(foreach lib,$(filter-out android,$(filter-out %removed,$(filter-out incompatibilities,\
       $(basename $(notdir $(wildcard $(HISTORICAL_SDK_VERSIONS_ROOT)/$(ver)/$(api_level)/api/*.txt)))))),\
-        $(eval $(call copy_api_txt_file,$(lib)-$(ver)-$(api_level).txt,prebuilts/sdk/$(ver)/$(api_level)/api/$(lib).txt)))))
+        $(eval $(call build_xml_api_file,$(lib)-$(ver)-$(api_level).api,prebuilts/sdk/$(ver)/$(api_level)/api/$(lib).txt)) \
+    )\
+  )\
+)
diff --git a/tests/signature/intent-check/Android.bp b/tests/signature/intent-check/Android.bp
index f6ec58c..82fb79e 100644
--- a/tests/signature/intent-check/Android.bp
+++ b/tests/signature/intent-check/Android.bp
@@ -18,9 +18,9 @@
 
     srcs: ["src/**/*.java"],
     java_resources: [
-        ":cts-current-txt",
-        ":cts-system-current-txt",
-        ":cts-system-removed-txt",
+        ":cts-current-api-gz",
+        ":cts-system-current-api-gz",
+        ":cts-system-removed-api-gz",
     ],
 
     // Tag this module as a cts test artifact
diff --git a/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java b/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java
index 0195dc4..efd574e 100644
--- a/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java
+++ b/tests/signature/intent-check/src/android/signature/cts/intent/IntentTest.java
@@ -48,11 +48,11 @@
 @RunWith(AndroidJUnit4.class)
 public class IntentTest {
 
-    private static final String CURRENT_API_RESOURCE = "current.txt";
+    private static final String CURRENT_API_RESOURCE = "current.api.gz";
 
-    private static final String SYSTEM_CURRENT_API_RESOURCE = "system-current.txt";
+    private static final String SYSTEM_CURRENT_API_RESOURCE = "system-current.api.gz";
 
-    private static final String SYSTEM_REMOVED_API_RESOURCE = "system-removed.txt";
+    private static final String SYSTEM_REMOVED_API_RESOURCE = "system-removed.api.gz";
 
     private static final String TAG = IntentTest.class.getSimpleName();
 
diff --git a/tests/signature/lib/android/Android.bp b/tests/signature/lib/android/Android.bp
index 7b0e679..546190a 100644
--- a/tests/signature/lib/android/Android.bp
+++ b/tests/signature/lib/android/Android.bp
@@ -24,7 +24,6 @@
     ],
     static_libs: [
         "signature-common-javalib",
-        "metalava",
     ],
     sdk_version: "current",
 }
diff --git a/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java b/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java
index 78027d4..70e3665 100644
--- a/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java
+++ b/tests/signature/lib/android/src/android/signature/cts/ApiDocumentParser.java
@@ -34,9 +34,14 @@
 
     private ApiParser getApiParser(VirtualPath path) {
         if (path.toString().endsWith(".txt")) {
-            return new TextApiParser();
+            // At one point we used the "text" signature format in this test, but we stopped doing
+            // it because we don't want metalava to be used as a library, especially
+            // on the device side.
+            throw new RuntimeException("Signature format not supported");
         } else if (path.toString().endsWith(".api")) {
-            return new XmlApiParser(tag);
+            return new XmlApiParser(tag, /*gzipped=*/ false);
+        } else if (path.toString().endsWith(".api.gz")) {
+            return new XmlApiParser(tag, /*gzipped=*/ true);
         } else {
             throw new IllegalStateException("Unrecognized file type: " + path);
         }
diff --git a/tests/signature/lib/android/src/android/signature/cts/KtHelper.kt b/tests/signature/lib/android/src/android/signature/cts/KtHelper.kt
deleted file mode 100644
index 4d2fade..0000000
--- a/tests/signature/lib/android/src/android/signature/cts/KtHelper.kt
+++ /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.
- */
-
-@file:JvmName("KtHelper")
-package android.signature.cts
-
-import com.android.tools.metalava.model.TypeItem
-
-/**
- * Allows Java to call the TypeItem.toTypeString() without having to explicitly specify each named
- * parameter to its default. This allows additional parameters to be added to the method without
- * breaking the Java code.
- */
-fun toDefaultTypeString(item: TypeItem): String {
-    // Normalize the strings to contain , without a following space. This is needed because
-    // different versions of the txt specification used different separators in generic types, some
-    // used "," and some used ", " and metalava does not normalize them. e.g. some files will format
-    // a Map from String to Integer as "java.util.Map<java.lang.String,java.lang.Integer>" and some
-    // will format it as "java.util.Map<java.lang.String, java.lang.Integer>".
-    //
-    // Must match separator used in android.signature.cts.ReflectionHelper.typeToString.
-    return item.toTypeString().replace(", ", ",")
-}
diff --git a/tests/signature/lib/android/src/android/signature/cts/TextApiParser.java b/tests/signature/lib/android/src/android/signature/cts/TextApiParser.java
deleted file mode 100644
index 26ac862..0000000
--- a/tests/signature/lib/android/src/android/signature/cts/TextApiParser.java
+++ /dev/null
@@ -1,191 +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.signature.cts;
-
-import android.signature.cts.JDiffClassDescription.JDiffConstructor;
-import android.signature.cts.JDiffClassDescription.JDiffField;
-import android.signature.cts.JDiffClassDescription.JDiffMethod;
-import com.android.tools.metalava.doclava1.ApiFile;
-import com.android.tools.metalava.doclava1.ApiParseException;
-import com.android.tools.metalava.doclava1.TextCodebase;
-import com.android.tools.metalava.model.ClassItem;
-import com.android.tools.metalava.model.ConstructorItem;
-import com.android.tools.metalava.model.FieldItem;
-import com.android.tools.metalava.model.Item;
-import com.android.tools.metalava.model.MethodItem;
-import com.android.tools.metalava.model.ModifierList;
-import com.android.tools.metalava.model.PackageItem;
-import com.android.tools.metalava.model.ParameterItem;
-import com.android.tools.metalava.model.TypeItem;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.lang.reflect.Modifier;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import kotlin.streams.jdk8.StreamsKt;
-
-/**
- * Parser for the text representation of an API specification.
- */
-public class TextApiParser extends ApiParser {
-
-    @Override
-    public Stream<JDiffClassDescription> parseAsStream(VirtualPath path) {
-        try {
-            String content = new BufferedReader(new InputStreamReader(path.newInputStream()))
-                    .lines()
-                    .parallel()
-                    .collect(Collectors.joining("\n"));
-            TextCodebase codebase = ApiFile.parseApi(path.toString(), content, false);
-            List<PackageItem> packages = codebase.getPackages().getPackages();
-            return packages.stream()
-                    // Map each package to the Sequence of ClassItems that it contains
-                    .map(PackageItem::allClasses)
-                    // Flatten the Sequences of ClassItems into one stream.
-                    .flatMap(StreamsKt::asStream)
-                    // Filter out TextClassItems that are used from but not defined in the source.
-                    .filter(ClassItem::isDefined)
-                    .map(TextApiParser::convertClass);
-        } catch (IOException | ApiParseException e) {
-            throw new RuntimeException("Could not parse " + path, e);
-        }
-    }
-
-    private static JDiffClassDescription convertClass(ClassItem item) {
-        String pkg = item.containingPackage().qualifiedName();
-
-        JDiffClassDescription currentClass = new JDiffClassDescription(pkg, item.fullName());
-
-        int modifiers = getModifiers(item);
-
-        currentClass.setModifier(modifiers);
-        currentClass.setType(item.isInterface() ? JDiffClassDescription.JDiffType.INTERFACE :
-                JDiffClassDescription.JDiffType.CLASS);
-
-        // Map the super class.
-        ClassItem superClass = item.superClass();
-        if (superClass != null) {
-            String extendsClass = superClass.qualifiedName();
-            if (item.isInterface()) {
-                // TextCodebase treats an interface as if it extends java.lang.Object.
-                if (!superClass.isJavaLangObject()) {
-                    currentClass.addImplInterface(extendsClass);
-                }
-            } else {
-                currentClass.setExtendsClass(extendsClass);
-            }
-        }
-
-        // Map the interfaces.
-        item.interfaceTypes().stream()
-                .map(TypeItem::asClass)
-                .filter(Objects::nonNull)
-                .map(ClassItem::qualifiedName)
-                .forEach(currentClass::addImplInterface);
-
-        item.fields().stream().map(TextApiParser::convertField).forEach(currentClass::addField);
-
-        item.constructors().stream()
-                .map(TextApiParser::convertConstructor)
-                .forEach(currentClass::addConstructor);
-
-        item.methods().stream()
-                .map(TextApiParser::convertMethod)
-                .forEach(currentClass::addMethod);
-
-        return currentClass;
-    }
-
-    private static int getModifiers(Item item) {
-        ModifierList modifierList = item.getModifiers();
-        int modifiers = 0;
-        if (modifierList.isAbstract()) {
-            modifiers |= Modifier.ABSTRACT;
-        }
-        if (modifierList.isFinal()) {
-            modifiers |= Modifier.FINAL;
-        }
-        if (modifierList.isNative()) {
-            modifiers |= Modifier.NATIVE;
-        }
-        if (modifierList.isStatic()) {
-            modifiers |= Modifier.STATIC;
-        }
-        if (modifierList.isSynchronized()) {
-            modifiers |= Modifier.SYNCHRONIZED;
-        }
-        if (modifierList.isTransient()) {
-            modifiers |= Modifier.TRANSIENT;
-        }
-        if (modifierList.isVolatile()) {
-            modifiers |= Modifier.VOLATILE;
-        }
-        if (modifierList.isPrivate()) {
-            modifiers |= Modifier.PRIVATE;
-        } else if (modifierList.isProtected()) {
-            modifiers |= Modifier.PROTECTED;
-        } else if (modifierList.isPublic()) {
-            modifiers |= Modifier.PUBLIC;
-        }
-        return modifiers;
-    }
-
-    private static JDiffField convertField(FieldItem item) {
-        int modifiers = getModifiers(item);
-        Object value = item.initialValue(true);
-
-        if (item.isEnumConstant()) {
-            // Set the enum bit on the enum constant to match the modifiers returned by reflection.
-            modifiers |= 0x00004000;
-        }
-
-        return new JDiffField(item.name(),
-                KtHelper.toDefaultTypeString(item.type()), modifiers,
-                value == null ? null : value.toString());
-    }
-
-    private static JDiffConstructor convertConstructor(ConstructorItem item) {
-        JDiffConstructor constructor = new JDiffConstructor(item.name(), getModifiers(item));
-
-        convertParameters(item, constructor);
-
-        return constructor;
-    }
-
-    private static void convertParameters(MethodItem item, JDiffMethod method) {
-        item.parameters().stream()
-                .map(TextApiParser::convertParameter)
-                .forEach(method::addParam);
-    }
-
-    private static JDiffMethod convertMethod(MethodItem item) {
-        TypeItem returnType = item.returnType();
-        String returnTypeAsString = returnType == null ? null
-                : KtHelper.toDefaultTypeString(returnType);
-        JDiffMethod method = new JDiffMethod(item.name(), getModifiers(item), returnTypeAsString);
-
-        convertParameters(item, method);
-
-        return method;
-    }
-
-    private static String convertParameter(ParameterItem item) {
-        return KtHelper.toDefaultTypeString(item.type());
-    }
-}
diff --git a/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java b/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java
index 8e5d0bb..e77d7e0 100644
--- a/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java
+++ b/tests/signature/lib/android/src/android/signature/cts/XmlApiParser.java
@@ -20,6 +20,7 @@
 import android.signature.cts.JDiffClassDescription.JDiffMethod;
 import android.util.Log;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.reflect.Modifier;
 import java.util.Collections;
 import java.util.HashSet;
@@ -28,6 +29,8 @@
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
+import java.util.zip.GZIPInputStream;
+
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 import org.xmlpull.v1.XmlPullParserFactory;
@@ -106,11 +109,13 @@
     }
 
     private final String tag;
+    private final boolean gzipped;
 
     private final XmlPullParserFactory factory;
 
-    XmlApiParser(String tag) {
+    XmlApiParser(String tag, boolean gzipped) {
         this.tag = tag;
+        this.gzipped = gzipped;
         try {
             factory = XmlPullParserFactory.newInstance();
         } catch (XmlPullParserException e) {
@@ -121,18 +126,25 @@
     /**
      * Load field information from xml to memory.
      *
-     * @param className
+     * @param currentClass
      *         of the class being examined which will be shown in error messages
      * @param parser
      *         The XmlPullParser which carries the xml information.
      * @return the new field
      */
-    private static JDiffField loadFieldInfo(String className, XmlPullParser parser) {
+    private static JDiffField loadFieldInfo(
+            JDiffClassDescription currentClass, XmlPullParser parser) {
         String fieldName = parser.getAttributeValue(null, ATTRIBUTE_NAME);
         String fieldType = canonicalizeType(parser.getAttributeValue(null, ATTRIBUTE_TYPE));
-        int modifier = jdiffModifierToReflectionFormat(className, parser);
+        int modifier = jdiffModifierToReflectionFormat(currentClass.getClassName(), parser);
         String value = parser.getAttributeValue(null, ATTRIBUTE_VALUE);
 
+        if (currentClass.isEnumType() && fieldType.equals(currentClass.getAbsoluteClassName())
+                && (value != null && value.startsWith("PsiEnumConstant:"))) {
+            // We don't need to check the value.
+            value = null;
+        }
+
         // Canonicalize the expected value to ensure that it is consistent with the values obtained
         // using reflection by ApiComplianceChecker.getFieldValueAsString(...).
         if (value != null) {
@@ -148,10 +160,24 @@
                         break;
 
                     case "char":
-                        // A character is encoded in XML as its numeric value. Convert it to a
+                        // A character may be encoded in XML as its numeric value. Convert it to a
                         // string containing the single character.
-                        char c = (char) Integer.parseInt(value);
-                        value = String.valueOf(c);
+                        try {
+                            char c = (char) Integer.parseInt(value);
+                            value = String.valueOf(c);
+                        } catch (NumberFormatException e) {
+                            // If not, it must be a string "'?'". Extract the second character,
+                            // but we need to unescape it.
+                            int len = value.length();
+                            if (value.charAt(0) == '\'' && value.charAt(len - 1) == '\'') {
+                                String sub = value.substring(1, len - 1);
+                                value = unescapeFieldStringValue(sub);
+                            } else {
+                                throw new NumberFormatException(String.format(
+                                        "Cannot parse the value of field '%s': invalid number '%s'",
+                                        fieldName, value));
+                            }
+                        }
                         break;
 
                     case "double":
@@ -248,10 +274,25 @@
         String className = parser.getAttributeValue(null, ATTRIBUTE_NAME);
         JDiffClassDescription currentClass = new JDiffClassDescription(pkg, className);
 
-        currentClass.setModifier(jdiffModifierToReflectionFormat(className, parser));
         currentClass.setType(isInterface ? JDiffClassDescription.JDiffType.INTERFACE :
                 JDiffClassDescription.JDiffType.CLASS);
-        currentClass.setExtendsClass(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS));
+
+        String superClass = stripGenericsArgs(parser.getAttributeValue(null, ATTRIBUTE_EXTENDS));
+        int modifiers = jdiffModifierToReflectionFormat(className, parser);
+        if (isInterface) {
+            if (superClass != null) {
+                currentClass.addImplInterface(superClass);
+            }
+        } else {
+            if ("java.lang.annotation.Annotation".equals(superClass)) {
+                // ApiComplianceChecker expects "java.lang.annotation.Annotation" to be in
+                // the "impl interfaces".
+                currentClass.addImplInterface(superClass);
+            } else {
+                currentClass.setExtendsClass(superClass);
+            }
+        }
+        currentClass.setModifier(modifiers);
         return currentClass;
     }
 
@@ -324,7 +365,11 @@
         XmlPullParser parser;
         try {
             parser = factory.newPullParser();
-            parser.setInput(path.newInputStream(), null);
+            InputStream input = path.newInputStream();
+            if (gzipped) {
+                input = new GZIPInputStream(input);
+            }
+            parser.setInput(input, null);
             return StreamSupport
                     .stream(new ClassDescriptionSpliterator(parser), false);
         } catch (XmlPullParserException | IOException e) {
@@ -332,6 +377,10 @@
         }
     }
 
+    private static String stripGenericsArgs(String typeName) {
+        return typeName == null ? null : typeName.replaceFirst("<.*", "");
+    }
+
     private class ClassDescriptionSpliterator implements Spliterator<JDiffClassDescription> {
 
         private final XmlPullParser parser;
@@ -444,8 +493,8 @@
                         break;
 
                     case TAG_IMPLEMENTS:
-                        currentClass
-                                .addImplInterface(parser.getAttributeValue(null, ATTRIBUTE_NAME));
+                        currentClass.addImplInterface(stripGenericsArgs(
+                                parser.getAttributeValue(null, ATTRIBUTE_NAME)));
                         break;
 
                     case TAG_CONSTRUCTOR:
@@ -470,7 +519,7 @@
                         break;
 
                     case TAG_FIELD:
-                        JDiffField field = loadFieldInfo(currentClass.getClassName(), parser);
+                        JDiffField field = loadFieldInfo(currentClass, parser);
                         currentClass.addField(field);
                         break;
 
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp b/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
index 036853e..e4ec9b4 100644
--- a/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/Android.bp
@@ -12,8 +12,8 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-aidl_interface {
-    name: "libbinder_ndk_test_interface",
+filegroup {
+    name: "libbinder_ndk_test_interface_srcs",
     srcs: [
         "test_package/Bar.aidl",
         "test_package/ByteEnum.aidl",
@@ -24,6 +24,12 @@
         "test_package/LongEnum.aidl",
         "test_package/RegularPolygon.aidl",
     ],
+    visibility: ["//visibility:private"]
+}
+
+aidl_interface {
+    name: "libbinder_ndk_test_interface",
+    srcs: [":libbinder_ndk_test_interface_srcs"],
     versions: [
         "1",
         "2",
@@ -38,6 +44,29 @@
     },
 }
 
+aidl_interface {
+    name: "libbinder_ndk_test_interface_dup",
+    srcs: [":libbinder_ndk_test_interface_srcs"],
+    versions: [
+        "1",
+    ],
+    backend: {
+        java: {
+            enabled: false,
+        },
+        cpp: {
+            enabled: false,
+        },
+        ndk: {
+            enabled: true,
+        },
+    },
+    visibility: [
+        ":__subpackages__",
+        "//system/tools/aidl/build:__pkg__",
+    ]
+}
+
 cc_defaults {
     name: "libbinder_ndk_test_defaults",
     cflags: [
@@ -82,7 +111,8 @@
     cflags: ["-DUSING_VERSION_1"],
     // Using the frozen version 1 of the interface
     static_libs: [
-        "libbinder_ndk_test_interface-V1-ndk",
+        // this refers to the latest stable version which is 1
+        "libbinder_ndk_test_interface_dup-ndk",
     ],
     shared_libs: [
         "libbinder_ndk_test_utilities",
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/.hash b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/.hash
new file mode 100644
index 0000000..44d6213
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/.hash
@@ -0,0 +1 @@
+8e163a1b4a6f366aa0c00b6da7fc13a970ee55d8
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Bar.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Bar.aidl
new file mode 100644
index 0000000..6a5d253
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Bar.aidl
@@ -0,0 +1,7 @@
+package test_package;
+parcelable Bar {
+  String a = "BAR";
+  String b = "BAR2";
+  float c = 4.200000f;
+  int d = 100;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ByteEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ByteEnum.aidl
new file mode 100644
index 0000000..6884107
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ByteEnum.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 test_package;
+
+@Backing(type="byte")
+enum ByteEnum {
+    FOO = 1,
+    BAR = 2,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Foo.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Foo.aidl
new file mode 100644
index 0000000..86af9b6
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/Foo.aidl
@@ -0,0 +1,15 @@
+package test_package;
+parcelable Foo {
+  String a = "FOO";
+  int b = 42;
+  float c = 3.140000f;
+  test_package.Bar d;
+  test_package.Bar e;
+  int f = 3;
+  test_package.ByteEnum shouldBeByteBar;
+  test_package.IntEnum shouldBeIntBar;
+  test_package.LongEnum shouldBeLongBar;
+  test_package.ByteEnum[] shouldContainTwoByteFoos;
+  test_package.IntEnum[] shouldContainTwoIntFoos;
+  test_package.LongEnum[] shouldContainTwoLongFoos;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IEmpty.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IEmpty.aidl
new file mode 100644
index 0000000..2baa52c
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IEmpty.aidl
@@ -0,0 +1,3 @@
+package test_package;
+interface IEmpty {
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ITest.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ITest.aidl
new file mode 100644
index 0000000..75e7a41
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/ITest.aidl
@@ -0,0 +1,69 @@
+package test_package;
+interface ITest {
+  String GetName();
+  void TestVoidReturn();
+  oneway void TestOneway();
+  int GiveMeMyCallingPid();
+  int GiveMeMyCallingUid();
+  oneway void CacheCallingInfoFromOneway();
+  int GiveMeMyCallingPidFromOneway();
+  int GiveMeMyCallingUidFromOneway();
+  int RepeatInt(int value);
+  long RepeatLong(long value);
+  float RepeatFloat(float value);
+  double RepeatDouble(double value);
+  boolean RepeatBoolean(boolean value);
+  char RepeatChar(char value);
+  byte RepeatByte(byte value);
+  test_package.ByteEnum RepeatByteEnum(test_package.ByteEnum value);
+  test_package.IntEnum RepeatIntEnum(test_package.IntEnum value);
+  test_package.LongEnum RepeatLongEnum(test_package.LongEnum value);
+  IBinder RepeatBinder(IBinder value);
+  @nullable IBinder RepeatNullableBinder(@nullable IBinder value);
+  test_package.IEmpty RepeatInterface(test_package.IEmpty value);
+  @nullable test_package.IEmpty RepeatNullableInterface(@nullable test_package.IEmpty value);
+  ParcelFileDescriptor RepeatFd(in ParcelFileDescriptor fd);
+  @nullable ParcelFileDescriptor RepeatNullableFd(in @nullable ParcelFileDescriptor fd);
+  String RepeatString(String value);
+  @nullable String RepeatNullableString(@nullable String value);
+  test_package.RegularPolygon RepeatPolygon(in test_package.RegularPolygon value);
+  @nullable test_package.RegularPolygon RepeatNullablePolygon(in @nullable test_package.RegularPolygon value);
+  void RenamePolygon(inout test_package.RegularPolygon value, String newName);
+  boolean[] RepeatBooleanArray(in boolean[] input, out boolean[] repeated);
+  byte[] RepeatByteArray(in byte[] input, out byte[] repeated);
+  char[] RepeatCharArray(in char[] input, out char[] repeated);
+  int[] RepeatIntArray(in int[] input, out int[] repeated);
+  long[] RepeatLongArray(in long[] input, out long[] repeated);
+  float[] RepeatFloatArray(in float[] input, out float[] repeated);
+  double[] RepeatDoubleArray(in double[] input, out double[] repeated);
+  test_package.ByteEnum[] RepeatByteEnumArray(in test_package.ByteEnum[] input, out test_package.ByteEnum[] repeated);
+  test_package.IntEnum[] RepeatIntEnumArray(in test_package.IntEnum[] input, out test_package.IntEnum[] repeated);
+  test_package.LongEnum[] RepeatLongEnumArray(in test_package.LongEnum[] input, out test_package.LongEnum[] repeated);
+  String[] RepeatStringArray(in String[] input, out String[] repeated);
+  test_package.RegularPolygon[] RepeatRegularPolygonArray(in test_package.RegularPolygon[] input, out test_package.RegularPolygon[] repeated);
+  ParcelFileDescriptor[] RepeatFdArray(in ParcelFileDescriptor[] input, out ParcelFileDescriptor[] repeated);
+  List<String> Repeat2StringList(in List<String> input, out List<String> repeated);
+  List<test_package.RegularPolygon> Repeat2RegularPolygonList(in List<test_package.RegularPolygon> input, out List<test_package.RegularPolygon> repeated);
+  @nullable boolean[] RepeatNullableBooleanArray(in @nullable boolean[] input);
+  @nullable byte[] RepeatNullableByteArray(in @nullable byte[] input);
+  @nullable char[] RepeatNullableCharArray(in @nullable char[] input);
+  @nullable int[] RepeatNullableIntArray(in @nullable int[] input);
+  @nullable long[] RepeatNullableLongArray(in @nullable long[] input);
+  @nullable float[] RepeatNullableFloatArray(in @nullable float[] input);
+  @nullable double[] RepeatNullableDoubleArray(in @nullable double[] input);
+  @nullable test_package.ByteEnum[] RepeatNullableByteEnumArray(in @nullable test_package.ByteEnum[] input);
+  @nullable test_package.IntEnum[] RepeatNullableIntEnumArray(in @nullable test_package.IntEnum[] input);
+  @nullable test_package.LongEnum[] RepeatNullableLongEnumArray(in @nullable test_package.LongEnum[] input);
+  @nullable String[] RepeatNullableStringArray(in @nullable String[] input);
+  @nullable String[] DoubleRepeatNullableStringArray(in @nullable String[] input, out @nullable String[] repeated);
+  test_package.Foo repeatFoo(in test_package.Foo inFoo);
+  void renameFoo(inout test_package.Foo foo, String name);
+  void renameBar(inout test_package.Foo foo, String name);
+  int getF(in test_package.Foo foo);
+  String RepeatStringNullableLater(String repeated);
+  const int kZero = 0;
+  const int kOne = 1;
+  const int kOnes = -1;
+  const String kEmpty = "";
+  const String kFoo = "foo";
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IntEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IntEnum.aidl
new file mode 100644
index 0000000..15b9891
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/IntEnum.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 test_package;
+
+@Backing(type="int")
+enum IntEnum {
+    FOO = 1000,
+    BAR = 2000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/LongEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/LongEnum.aidl
new file mode 100644
index 0000000..f21ea63
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/LongEnum.aidl
@@ -0,0 +1,23 @@
+/*
+ * 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 test_package;
+
+@Backing(type="long")
+enum LongEnum {
+    FOO = 100000000000,
+    BAR = 200000000000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/RegularPolygon.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/RegularPolygon.aidl
new file mode 100644
index 0000000..14c6c2e
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/1/test_package/RegularPolygon.aidl
@@ -0,0 +1,6 @@
+package test_package;
+parcelable RegularPolygon {
+  String name = "square";
+  int numSides = 4;
+  float sideLength = 1.000000f;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Bar.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Bar.aidl
new file mode 100644
index 0000000..99ba6b5
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Bar.aidl
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+parcelable Bar {
+  String a = "BAR";
+  String b = "BAR2";
+  float c = 4.200000f;
+  int d = 100;
+  String e = "HELLO";
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ByteEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ByteEnum.aidl
new file mode 100644
index 0000000..16c6e1b
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ByteEnum.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+@Backing(type="byte")
+enum ByteEnum {
+  FOO = 1,
+  BAR = 2,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Foo.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Foo.aidl
new file mode 100644
index 0000000..8b71fee
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/Foo.aidl
@@ -0,0 +1,33 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+parcelable Foo {
+  String a = "FOO";
+  int b = 42;
+  float c = 3.140000f;
+  test_package.Bar d;
+  test_package.Bar e;
+  int f = 3;
+  test_package.ByteEnum shouldBeByteBar;
+  test_package.IntEnum shouldBeIntBar;
+  test_package.LongEnum shouldBeLongBar;
+  test_package.ByteEnum[] shouldContainTwoByteFoos;
+  test_package.IntEnum[] shouldContainTwoIntFoos;
+  test_package.LongEnum[] shouldContainTwoLongFoos;
+  @nullable String[] g;
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IEmpty.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IEmpty.aidl
new file mode 100644
index 0000000..5a27b19
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IEmpty.aidl
@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+interface IEmpty {
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ITest.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ITest.aidl
new file mode 100644
index 0000000..effb098
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/ITest.aidl
@@ -0,0 +1,87 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+interface ITest {
+  String GetName();
+  void TestVoidReturn();
+  oneway void TestOneway();
+  int GiveMeMyCallingPid();
+  int GiveMeMyCallingUid();
+  oneway void CacheCallingInfoFromOneway();
+  int GiveMeMyCallingPidFromOneway();
+  int GiveMeMyCallingUidFromOneway();
+  int RepeatInt(int value);
+  long RepeatLong(long value);
+  float RepeatFloat(float value);
+  double RepeatDouble(double value);
+  boolean RepeatBoolean(boolean value);
+  char RepeatChar(char value);
+  byte RepeatByte(byte value);
+  test_package.ByteEnum RepeatByteEnum(test_package.ByteEnum value);
+  test_package.IntEnum RepeatIntEnum(test_package.IntEnum value);
+  test_package.LongEnum RepeatLongEnum(test_package.LongEnum value);
+  IBinder RepeatBinder(IBinder value);
+  @nullable IBinder RepeatNullableBinder(@nullable IBinder value);
+  test_package.IEmpty RepeatInterface(test_package.IEmpty value);
+  @nullable test_package.IEmpty RepeatNullableInterface(@nullable test_package.IEmpty value);
+  ParcelFileDescriptor RepeatFd(in ParcelFileDescriptor fd);
+  @nullable ParcelFileDescriptor RepeatNullableFd(in @nullable ParcelFileDescriptor fd);
+  String RepeatString(String value);
+  @nullable String RepeatNullableString(@nullable String value);
+  test_package.RegularPolygon RepeatPolygon(in test_package.RegularPolygon value);
+  @nullable test_package.RegularPolygon RepeatNullablePolygon(in @nullable test_package.RegularPolygon value);
+  void RenamePolygon(inout test_package.RegularPolygon value, String newName);
+  boolean[] RepeatBooleanArray(in boolean[] input, out boolean[] repeated);
+  byte[] RepeatByteArray(in byte[] input, out byte[] repeated);
+  char[] RepeatCharArray(in char[] input, out char[] repeated);
+  int[] RepeatIntArray(in int[] input, out int[] repeated);
+  long[] RepeatLongArray(in long[] input, out long[] repeated);
+  float[] RepeatFloatArray(in float[] input, out float[] repeated);
+  double[] RepeatDoubleArray(in double[] input, out double[] repeated);
+  test_package.ByteEnum[] RepeatByteEnumArray(in test_package.ByteEnum[] input, out test_package.ByteEnum[] repeated);
+  test_package.IntEnum[] RepeatIntEnumArray(in test_package.IntEnum[] input, out test_package.IntEnum[] repeated);
+  test_package.LongEnum[] RepeatLongEnumArray(in test_package.LongEnum[] input, out test_package.LongEnum[] repeated);
+  String[] RepeatStringArray(in String[] input, out String[] repeated);
+  test_package.RegularPolygon[] RepeatRegularPolygonArray(in test_package.RegularPolygon[] input, out test_package.RegularPolygon[] repeated);
+  ParcelFileDescriptor[] RepeatFdArray(in ParcelFileDescriptor[] input, out ParcelFileDescriptor[] repeated);
+  List<String> Repeat2StringList(in List<String> input, out List<String> repeated);
+  List<test_package.RegularPolygon> Repeat2RegularPolygonList(in List<test_package.RegularPolygon> input, out List<test_package.RegularPolygon> repeated);
+  @nullable boolean[] RepeatNullableBooleanArray(in @nullable boolean[] input);
+  @nullable byte[] RepeatNullableByteArray(in @nullable byte[] input);
+  @nullable char[] RepeatNullableCharArray(in @nullable char[] input);
+  @nullable int[] RepeatNullableIntArray(in @nullable int[] input);
+  @nullable long[] RepeatNullableLongArray(in @nullable long[] input);
+  @nullable float[] RepeatNullableFloatArray(in @nullable float[] input);
+  @nullable double[] RepeatNullableDoubleArray(in @nullable double[] input);
+  @nullable test_package.ByteEnum[] RepeatNullableByteEnumArray(in @nullable test_package.ByteEnum[] input);
+  @nullable test_package.IntEnum[] RepeatNullableIntEnumArray(in @nullable test_package.IntEnum[] input);
+  @nullable test_package.LongEnum[] RepeatNullableLongEnumArray(in @nullable test_package.LongEnum[] input);
+  @nullable String[] RepeatNullableStringArray(in @nullable String[] input);
+  @nullable String[] DoubleRepeatNullableStringArray(in @nullable String[] input, out @nullable String[] repeated);
+  test_package.Foo repeatFoo(in test_package.Foo inFoo);
+  void renameFoo(inout test_package.Foo foo, String name);
+  void renameBar(inout test_package.Foo foo, String name);
+  int getF(in test_package.Foo foo);
+  @nullable String RepeatStringNullableLater(@nullable String repeated);
+  int NewMethodThatReturns10();
+  const int kZero = 0;
+  const int kOne = 1;
+  const int kOnes = -1;
+  const String kEmpty = "";
+  const String kFoo = "foo";
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IntEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IntEnum.aidl
new file mode 100644
index 0000000..f889ec4
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/IntEnum.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+@Backing(type="int")
+enum IntEnum {
+  FOO = 1000,
+  BAR = 2000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/LongEnum.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/LongEnum.aidl
new file mode 100644
index 0000000..b03c85c
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/LongEnum.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+@Backing(type="long")
+enum LongEnum {
+  FOO = 100000000000,
+  BAR = 200000000000,
+}
diff --git a/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/RegularPolygon.aidl b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/RegularPolygon.aidl
new file mode 100644
index 0000000..8fdd8c84b
--- /dev/null
+++ b/tests/tests/binder_ndk/libbinder_ndk_test/aidl_api/libbinder_ndk_test_interface_dup/current/test_package/RegularPolygon.aidl
@@ -0,0 +1,23 @@
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE.                          //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
+// edit this file. It looks like you are doing that because you have modified
+// an AIDL interface in a backward-incompatible way, e.g., deleting a function
+// from an interface or a field from a parcelable and it broke the build. That
+// breakage is intended.
+//
+// You must not make a backward incompatible changes to the AIDL files built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package test_package;
+parcelable RegularPolygon {
+  String name = "square";
+  int numSides = 4;
+  float sideLength = 1.000000f;
+}
diff --git a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
index f39a5cc..29a9a04 100644
--- a/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
+++ b/tests/tests/carrierapi/src/android/carrierapi/cts/CarrierApiTest.java
@@ -257,6 +257,11 @@
         assertEquals(TelephonyManager.UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS, value);
     }
 
+    private static void assertUpdateAvailableNetworkNoOpportunisticSubAvailable(int value) {
+        assertEquals(
+                TelephonyManager.UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE, value);
+    }
+
     private static void assertSetOpportunisticSubSuccess(int value) {
         assertEquals(TelephonyManager.SET_OPPORTUNISTIC_SUB_SUCCESS, value);
     }
@@ -310,6 +315,8 @@
                 CarrierApiTest::assertUpdateAvailableNetworkSuccess;
         Consumer<Integer> callbackFailure =
                 CarrierApiTest::assertUpdateAvailableNetworkInvalidArguments;
+        Consumer<Integer> callbackNoOpportunisticSubAvailable =
+                CarrierApiTest::assertUpdateAvailableNetworkNoOpportunisticSubAvailable;
         Consumer<Integer> setOpCallbackSuccess = CarrierApiTest::assertSetOpportunisticSubSuccess;
         if (subscriptionInfoList == null || subscriptionInfoList.size() == 0
                 || !mSubscriptionManager.isActiveSubscriptionId(
@@ -320,10 +327,11 @@
                         bands);
                 availableNetworkInfos.add(availableNetworkInfo);
                 // Call updateAvailableNetworks without opportunistic subscription.
-                // callbackFailure is expected to be triggered and the return value will be checked
-                // against UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS
+                // callbackNoOpportunisticSubAvailable is expected to be triggered
+                // and the return value will be checked against
+                // UPDATE_AVAILABLE_NETWORKS_NO_OPPORTUNISTIC_SUB_AVAILABLE
                 mTelephonyManager.updateAvailableNetworks(availableNetworkInfos,
-                        AsyncTask.SERIAL_EXECUTOR, callbackFailure);
+                        AsyncTask.SERIAL_EXECUTOR, callbackNoOpportunisticSubAvailable);
             } finally {
                 // clear all the operations at the end of test.
                 availableNetworkInfos.clear();
@@ -617,6 +625,8 @@
     }
 
     public void testIccOpenLogicalChannelWithValidP2() {
+        if (!hasCellular) return;
+
         // {@link TelephonyManager#iccOpenLogicalChannel} sends a Manage Channel (open) APDU
         // followed by a Select APDU with the given AID and p2 values. See Open Mobile API
         // Specification v3.2 Section 6.2.7.h and TS 102 221 for details.
@@ -631,6 +641,8 @@
     }
 
     public void testIccOpenLogicalChannelWithInvalidP2() {
+        if (!hasCellular) return;
+
         // Valid p2 values are defined in TS 102 221 Table 11.2. Per Table 11.2, 0xF0 should be
         // invalid. Any p2 values that produce non '9000'/'62xx'/'63xx' status words are treated as
         // an error and the channel is not opened. Due to compatibility issues with older devices,
diff --git a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
index 3f9f758..640cb95 100644
--- a/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
+++ b/tests/tests/keystore/src/android/keystore/cts/CipherTest.java
@@ -289,6 +289,12 @@
             mLockCredential.gotoKeyguard();
             mLockCredential.enterAndConfirmLockCredential();
             launchHomeActivity();
+            KeyguardManager keyguardManager = (KeyguardManager)getContext().getSystemService(
+                    Context.KEYGUARD_SERVICE);
+            for (int i = 0; i < 25 && keyguardManager.isDeviceLocked(); i++) {
+                SystemClock.sleep(200);
+            }
+            assertFalse(keyguardManager.isDeviceLocked());
         }
 
         @Override
@@ -430,6 +436,59 @@
         }
     }
 
+    /*
+     * This test performs a round trip en/decryption. It does so while the current thread
+     * is in interrupted state which cannot be signaled to the user of the Java Crypto
+     * API.
+     */
+    public void testEncryptsAndDecryptsInterrupted()
+            throws Exception {
+        Provider provider = Security.getProvider(EXPECTED_PROVIDER_NAME);
+        assertNotNull(provider);
+        final byte[] originalPlaintext = EmptyArray.BYTE;
+        for (String algorithm : EXPECTED_ALGORITHMS) {
+            for (ImportedKey key : importKatKeys(
+                    algorithm,
+                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT,
+                    false)) {
+                try {
+                    Key encryptionKey = key.getKeystoreBackedEncryptionKey();
+                    byte[] plaintext = truncatePlaintextIfNecessary(
+                            algorithm, encryptionKey, originalPlaintext);
+                    if (plaintext == null) {
+                        // Key is too short to encrypt anything using this transformation
+                        continue;
+                    }
+                    Cipher cipher = Cipher.getInstance(algorithm, provider);
+                    Thread.currentThread().interrupt();
+                    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);
+                    AlgorithmParameters params = cipher.getParameters();
+                    byte[] ciphertext = cipher.doFinal(plaintext);
+                    byte[] expectedPlaintext = plaintext;
+                    if ("RSA/ECB/NoPadding".equalsIgnoreCase(algorithm)) {
+                        // RSA decryption without padding left-pads resulting plaintext with NUL
+                        // bytes to the length of RSA modulus.
+                        int modulusLengthBytes = (TestUtils.getKeySizeBits(encryptionKey) + 7) / 8;
+                        expectedPlaintext = TestUtils.leftPadWithZeroBytes(
+                                expectedPlaintext, modulusLengthBytes);
+                    }
+
+                    cipher = Cipher.getInstance(algorithm, provider);
+                    Key decryptionKey = key.getKeystoreBackedDecryptionKey();
+                    cipher.init(Cipher.DECRYPT_MODE, decryptionKey, params);
+                    byte[] actualPlaintext = cipher.doFinal(ciphertext);
+                    assertTrue(Thread.currentThread().interrupted());
+                    MoreAsserts.assertEquals(expectedPlaintext, actualPlaintext);
+                } catch (Throwable e) {
+                    throw new RuntimeException(
+                            "Failed for " + algorithm + " with key " + key.getAlias(),
+                            e);
+                }
+            }
+        }
+    }
+
+
     private boolean isDecryptValid(byte[] expectedPlaintext, byte[] ciphertext, Cipher cipher,
             AlgorithmParameters params, ImportedKey key) {
         try {
diff --git a/tests/tests/media/res/raw/MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps.trp b/tests/tests/media/res/raw/MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps.trp
deleted file mode 100644
index e39e5c4..0000000
--- a/tests/tests/media/res/raw/MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps.trp
+++ /dev/null
Binary files differ
diff --git a/tests/tests/media/res/raw/MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps_Audio_Only.ts b/tests/tests/media/res/raw/MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps_Audio_Only.ts
new file mode 100644
index 0000000..4b4da9f
--- /dev/null
+++ b/tests/tests/media/res/raw/MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps_Audio_Only.ts
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/AudioManagerTest.java b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
index 2618c3d..639f738 100644
--- a/tests/tests/media/src/android/media/cts/AudioManagerTest.java
+++ b/tests/tests/media/src/android/media/cts/AudioManagerTest.java
@@ -640,6 +640,11 @@
         int maxMusicVolume = mAudioManager.getStreamMaxVolume(STREAM_MUSIC);
 
         for (int stream : streams) {
+
+            if (mIsSingleVolume && stream != AudioManager.STREAM_MUSIC) {
+                continue;
+            }
+
             // set ringer mode to back normal to not interfere with volume tests
             mAudioManager.setRingerMode(RINGER_MODE_NORMAL);
 
diff --git a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
index 78e22d5..6cbc957 100644
--- a/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
+++ b/tests/tests/media/src/android/media/cts/MediaExtractorTest.java
@@ -349,7 +349,7 @@
     }
 
     public void testGetAudioPresentations() throws Exception {
-        final int resid = R.raw.MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps;
+        final int resid = R.raw.MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps_Audio_Only;
         TestMediaDataSource dataSource = setDataSource(resid);
         int ac4TrackIndex = -1;
         for (int i = 0; i < mExtractor.getTrackCount(); i++) {
@@ -360,9 +360,15 @@
                 break;
             }
         }
-        assertNotEquals(
-                "AC4 track was not found in MultiLangPerso_1PID_PC0_Select_AC4_H265_DVB_50fps",
-                -1, ac4TrackIndex);
+
+        // Not all devices support AC4
+        if (ac4TrackIndex == -1) {
+            List<AudioPresentation> presentations =
+                    mExtractor.getAudioPresentations(0 /*trackIndex*/);
+            assertNotNull(presentations);
+            assertTrue(presentations.isEmpty());
+            return;
+        }
 
         // The test file has two sets of audio presentations. The presentation set
         // changes for every 100 audio presentation descriptors between two presentations.
diff --git a/tests/tests/net/Android.bp b/tests/tests/net/Android.bp
index 82b7413..052ab26 100644
--- a/tests/tests/net/Android.bp
+++ b/tests/tests/net/Android.bp
@@ -82,6 +82,7 @@
     min_sdk_version: "29",
     target_sdk_version: "29",
     test_suites: [
+        "device-tests",
         "mts",
     ],
     test_config_template: "AndroidTestTemplate.xml",
diff --git a/tests/tests/net/TEST_MAPPING b/tests/tests/net/TEST_MAPPING
new file mode 100644
index 0000000..e2a9c75
--- /dev/null
+++ b/tests/tests/net/TEST_MAPPING
@@ -0,0 +1,13 @@
+{
+  // TODO: move to mainline-presubmit once supported
+  "postsubmit": [
+    {
+      "name": "CtsNetTestCasesLatestSdk",
+      "options": [
+        {
+          "exclude-annotation": "com.android.testutils.SkipPresubmit"
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/tests/net/api23Test/AndroidManifest.xml b/tests/tests/net/api23Test/AndroidManifest.xml
index 8af87f6..4889660 100644
--- a/tests/tests/net/api23Test/AndroidManifest.xml
+++ b/tests/tests/net/api23Test/AndroidManifest.xml
@@ -18,8 +18,11 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="android.net.cts.api23test">
 
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
     <uses-permission android:name="android.permission.INTERNET" />
 
     <application android:usesCleartextTraffic="true">
diff --git a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
index 0509fc0..13f953a 100644
--- a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
+++ b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionPskTest.java
@@ -18,13 +18,14 @@
 
 import static android.app.AppOpsManager.OP_MANAGE_IPSEC_TUNNELS;
 import static android.net.ipsec.ike.exceptions.IkeProtocolException.ERROR_TYPE_AUTHENTICATION_FAILED;
-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_TS_UNACCEPTABLE;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
 import android.net.LinkAddress;
+import android.net.ipsec.ike.ChildSessionParams;
 import android.net.ipsec.ike.IkeFqdnIdentification;
 import android.net.ipsec.ike.IkeSession;
 import android.net.ipsec.ike.IkeSessionParams;
@@ -84,7 +85,15 @@
                     + "9352D71100777B00ABCC6BD7DBEA697827FFAAA48DF9A54D1D68161939F5DC8"
                     + "6743A7CEB2BE34AC00095A5B8";
 
-    private IkeSession openIkeSessionWithRemoteAddress(InetAddress remoteAddress) {
+    private IkeSession openIkeSessionWithTunnelModeChild(InetAddress remoteAddress) {
+        return openIkeSession(remoteAddress, buildTunnelModeChildSessionParams());
+    }
+
+    private IkeSession openIkeSessionWithTransportModeChild(InetAddress remoteAddress) {
+        return openIkeSession(remoteAddress, buildTransportModeChildParamsWithDefaultTs());
+    }
+
+    private IkeSession openIkeSession(InetAddress remoteAddress, ChildSessionParams childParams) {
         IkeSessionParams ikeParams =
                 new IkeSessionParams.Builder(sContext)
                         .setNetwork(mTunNetwork)
@@ -98,7 +107,7 @@
         return new IkeSession(
                 sContext,
                 ikeParams,
-                buildTunnelModeChildSessionParams(),
+                childParams,
                 mUserCbExecutor,
                 mIkeSessionCallback,
                 mFirstChildSessionCallback);
@@ -124,7 +133,7 @@
         if (!hasTunnelsFeature()) return;
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
 
         // IKE INIT and IKE AUTH takes two exchanges. Message ID starts from 2
@@ -222,7 +231,7 @@
         setUpTestNetwork(mLocalAddress);
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(
                 ikeInitResp,
                 1 /* expectedAuthReqPktCnt */,
@@ -258,7 +267,7 @@
         if (!hasTunnelsFeature()) return;
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTunnelModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(SUCCESS_IKE_INIT_RESP, SUCCESS_IKE_AUTH_RESP);
 
         ikeSession.kill();
@@ -272,7 +281,7 @@
                 "46B8ECA1E0D72A180000000000000000292022200000000000000024000000080000000E";
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
         int expectedMsgId = 0;
         mTunUtils.awaitReqAndInjectResp(
                 IKE_DETERMINISTIC_INITIATOR_SPI,
@@ -309,7 +318,7 @@
                         + "AB6E4808BAC0CA1DAD6ADD0A126A41BD";
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthFailRespHex);
 
         mFirstChildSessionCallback.awaitOnClosed();
@@ -322,27 +331,28 @@
     @Test
     public void testIkeAuthHandlesFirstChildCreationFail() throws Exception {
         final String ikeInitRespHex =
-                "46B8ECA1E0D72A182B300285DA19E6452120222000000000000001502200"
-                        + "00300000002C010100040300000C0100000C800E01000300000803000005"
-                        + "0300000802000004000000080400000228000088000200005C9DE629981F"
-                        + "DB1FC45DB6CCF15D076C1F51BD9F63C771DC089F05CCDE6247965D15C616"
-                        + "C7B5A62342491715E4D1FEA19326477D24143E8E56AB6AD93F54B19BC32A"
-                        + "44BC0A5B5632E57D0A3C43E466E1547D8E4EF65EA4B864A348161666E229"
-                        + "84975A486251A17C4F096A6D5CF3DB83874B70324A31AA7ADDE2D73BADD8"
-                        + "238029000024CF06260F7C4923295E7C91F2B8479212892DA7A519A0322F"
-                        + "F5B2BF570B92972B2900001C00004004C7ACC2C7D58CF8C9F5E953993AF4"
-                        + "6CAC976635B42900001C00004005B64B190DFE7BDE8B9B1475EDE67B63D6"
-                        + "F1DBBF44290000080000402E290000100000402F00020003000400050000"
+                "46B8ECA1E0D72A18F5ABBF896A1240BE2120222000000000000001502200"
+                        + "00300000002C010100040300000C0100000C800E0100030000080300000C"
+                        + "03000008020000050000000804000002280000880002000074950F016B85"
+                        + "605E57E24651843AB70E41B552EDEE227DFE51E6CBEC00E75FFEFC7D5453"
+                        + "109B15F721FCD811FC9F113BE06050882F2FC5F5FF25857E555CCFB5AB64"
+                        + "8B0D1D7A819A3B05DE1FE89A4A627C60D5AA06CD0F66ACD3748722F9CD4F"
+                        + "F30AE7477CBC12049821F07AD6C9F0ED732321A6A36FA817722E025AC34B"
+                        + "ABE62900002432E3807F595070E95EDA341A787599B24B1151B535B0222B"
+                        + "65C003401B9B38F82900001C000040043BB760DB3037B51768DFFAB4B21D"
+                        + "B1716EA1C1382900001C0000400531098EB04DF1BE3F304606BD59B454A8"
+                        + "CC7E7311290000080000402E290000100000402F00020003000400050000"
                         + "000800004014";
         final String ikeAuthCreateChildFailHex =
-                "46B8ECA1E0D72A182B300285DA19E6452E202320000000010000008C2400"
-                        + "0070386FC9CCC67495A17915D0544390A2963A769F4A42C6FA668CEEC07F"
-                        + "EC0C87D681DE34267023DD394F1401B5A563E71002C0CE0928D0ABC0C4570"
-                        + "E39C2EDEF820F870AB71BD70A3F3EB5C96CA294B6D3F01677690DCF9F8CFC"
-                        + "9584650957573502BA83E32F18207A9ADEB1FA";
+                "46B8ECA1E0D72A18F5ABBF896A1240BE2E20232000000001000000B02400"
+                        + "009400B0861242E0C88ECB3848D772B560CAD65B6AC9DFFDC8622A394B8E"
+                        + "64E550BDD69FCD7E768129787ED9062992C1D6DB0F0631C2E05765B403CF"
+                        + "EF1D0A055B32F6698FF7DB5B8FB1B6A83A81634D00E22C86E35B3BFBEC73"
+                        + "EAC6806678926945BC7A57003DC1A3528A1EC423EE56C1075B36C0B57A6B"
+                        + "C6DD990182F6FABFFA167D199C7D629E5B830AAD2AFBD31CEBA6";
 
         // Open IKE Session
-        IkeSession ikeSession = openIkeSessionWithRemoteAddress(mRemoteAddress);
+        IkeSession ikeSession = openIkeSessionWithTransportModeChild(mRemoteAddress);
         performSetupIkeAndFirstChildBlocking(ikeInitRespHex, ikeAuthCreateChildFailHex);
 
         // Even though the child creation failed, the authentication succeeded, so the IKE Session's
@@ -352,7 +362,7 @@
         // Verify Child Creation failed
         IkeProtocolException protocolException =
                 (IkeProtocolException) mFirstChildSessionCallback.awaitOnClosedException();
-        assertEquals(ERROR_TYPE_INTERNAL_ADDRESS_FAILURE, protocolException.getErrorType());
+        assertEquals(ERROR_TYPE_TS_UNACCEPTABLE, protocolException.getErrorType());
         assertArrayEquals(EXPECTED_PROTOCOL_ERROR_DATA_NONE, protocolException.getErrorData());
 
         ikeSession.kill();
diff --git a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
index 2458b25..a81063b 100644
--- a/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
+++ b/tests/tests/net/ipsec/src/android/net/ipsec/ike/cts/IkeSessionTestBase.java
@@ -276,6 +276,13 @@
                 .build();
     }
 
+    TransportModeChildSessionParams buildTransportModeChildParamsWithDefaultTs() {
+        return new TransportModeChildSessionParams.Builder()
+                .addSaProposal(SaProposalTest.buildChildSaProposalWithCombinedModeCipher())
+                .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
+                .build();
+    }
+
     TunnelModeChildSessionParams buildTunnelModeChildSessionParams() {
         return new TunnelModeChildSessionParams.Builder()
                 .addSaProposal(SaProposalTest.buildChildSaProposalWithNormalModeCipher())
diff --git a/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt b/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
index 40d0ca6..68d5281 100644
--- a/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
+++ b/tests/tests/net/src/android/net/cts/CaptivePortalApiTest.kt
@@ -61,7 +61,6 @@
 import java.net.Inet4Address
 import java.util.concurrent.ArrayBlockingQueue
 import java.util.concurrent.TimeUnit
-import kotlin.reflect.KClass
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
@@ -90,7 +89,7 @@
     private val eth by lazy { context.assertHasService(EthernetManager::class.java) }
     private val cm by lazy { context.assertHasService(ConnectivityManager::class.java) }
 
-    private val handlerThread = HandlerThread(CaptivePortalApiTest::class.simpleName)
+    private val handlerThread = HandlerThread(CaptivePortalApiTest::class.java.simpleName)
     private val serverIpAddr = InetAddresses.parseNumericAddress("192.0.2.222") as Inet4Address
     private val clientIpAddr = InetAddresses.parseNumericAddress("192.0.2.111") as Inet4Address
     private val httpServer = HttpServer()
@@ -155,11 +154,11 @@
     fun testApiCallbacks() {
         // Handle the DHCP handshake that includes the capport API URL
         val discover = reader.assertDhcpPacketReceived(
-                DhcpDiscoverPacket::class, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
+                DhcpDiscoverPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_DISCOVER)
         reader.sendResponse(makeOfferPacket(discover.clientMac, discover.transactionId))
 
         val request = reader.assertDhcpPacketReceived(
-                DhcpRequestPacket::class, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
+                DhcpRequestPacket::class.java, TEST_TIMEOUT_MS, DHCP_MESSAGE_TYPE_REQUEST)
         assertEquals(discover.transactionId, request.transactionId)
         assertEquals(clientIpAddr, request.mRequestedIp)
         reader.sendResponse(makeAckPacket(request.clientMac, request.transactionId))
@@ -244,7 +243,7 @@
 }
 
 private fun <T : DhcpPacket> TapPacketReader.assertDhcpPacketReceived(
-    packetType: KClass<T>,
+    packetType: Class<T>,
     timeoutMs: Long,
     type: Byte
 ): T {
@@ -254,7 +253,7 @@
     val packet = DhcpPacket.decodeFullPacket(packetBytes, packetBytes.size, DhcpPacket.ENCAP_L2)
     assertTrue(packetType.isInstance(packet),
             "Expected ${packetType.simpleName} but got ${packet.javaClass.simpleName}")
-    return packetType.java.cast(packet)
+    return packetType.cast(packet)
 }
 
 private fun <T> Context.assertHasService(manager: Class<T>): T {
diff --git a/tests/tests/net/src/android/net/cts/CaptivePortalTest.kt b/tests/tests/net/src/android/net/cts/CaptivePortalTest.kt
index 0816aba..4a7d38a1 100644
--- a/tests/tests/net/src/android/net/cts/CaptivePortalTest.kt
+++ b/tests/tests/net/src/android/net/cts/CaptivePortalTest.kt
@@ -41,6 +41,7 @@
 import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
 import androidx.test.runner.AndroidJUnit4
 import com.android.compatibility.common.util.SystemUtil
+import com.android.testutils.isDevSdkInRange
 import fi.iki.elonen.NanoHTTPD
 import fi.iki.elonen.NanoHTTPD.Response.IStatus
 import fi.iki.elonen.NanoHTTPD.Response.Status
@@ -105,6 +106,9 @@
     @After
     fun tearDown() {
         clearTestUrls()
+        if (pm.hasSystemFeature(FEATURE_WIFI)) {
+            reconnectWifi()
+        }
         server.stop()
     }
 
@@ -167,7 +171,7 @@
             assertNotEquals(network, cm.activeNetwork, wifiDefaultMessage)
 
             val startPortalAppPermission =
-                    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) CONNECTIVITY_INTERNAL
+                    if (isDevSdkInRange(0, Build.VERSION_CODES.Q)) CONNECTIVITY_INTERNAL
                     else NETWORK_SETTINGS
             doAsShell(startPortalAppPermission) { cm.startCaptivePortalApp(network) }
             assertTrue(portalContentRequestCv.block(TEST_TIMEOUT_MS), "The captive portal login " +
@@ -180,9 +184,6 @@
             // disconnectFromCell should be called after connectToCell
             utils.disconnectFromCell()
         }
-
-        clearTestUrls()
-        reconnectWifi()
     }
 
     private fun setHttpsUrl(url: String?) = setConfig(TEST_CAPTIVE_PORTAL_HTTPS_URL_SETTING, url)
@@ -203,10 +204,8 @@
     }
 
     private fun reconnectWifi() {
-        doAsShell(NETWORK_SETTINGS) {
-            assertTrue(wm.disconnect())
-            assertTrue(wm.reconnect())
-        }
+        utils.ensureWifiDisconnected(null /* wifiNetworkToCheck */)
+        utils.ensureWifiConnected()
     }
 
     /**
diff --git a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
index d498ed9..3880664 100644
--- a/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/tests/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -96,6 +96,7 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.ArrayUtils;
+import com.android.testutils.SkipPresubmit;
 
 import libcore.io.Streams;
 
@@ -325,6 +326,7 @@
      */
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     @Test
+    @SkipPresubmit(reason = "Virtual devices use a single internet connection for all networks")
     public void testOpenConnection() throws Exception {
         boolean canRunTest = mPackageManager.hasSystemFeature(FEATURE_WIFI)
                 && mPackageManager.hasSystemFeature(FEATURE_TELEPHONY);
@@ -990,6 +992,7 @@
 
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     @Test
+    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
     public void testCreateTcpKeepalive() throws Exception {
         if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testCreateTcpKeepalive cannot execute unless device supports WiFi");
@@ -1199,6 +1202,7 @@
      */
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     @Test
+    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
     public void testSocketKeepaliveLimitWifi() throws Exception {
         if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testSocketKeepaliveLimitWifi cannot execute unless device"
@@ -1252,6 +1256,7 @@
      */
     @AppModeFull(reason = "Cannot request network in instant app mode")
     @Test
+    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
     public void testSocketKeepaliveLimitTelephony() throws Exception {
         if (!mPackageManager.hasSystemFeature(FEATURE_TELEPHONY)) {
             Log.i(TAG, "testSocketKeepaliveLimitTelephony cannot execute unless device"
@@ -1294,6 +1299,7 @@
      */
     @AppModeFull(reason = "Cannot get WifiManager in instant app mode")
     @Test
+    @SkipPresubmit(reason = "Keepalive is not supported on virtual hardware")
     public void testSocketKeepaliveUnprivileged() throws Exception {
         if (!mPackageManager.hasSystemFeature(FEATURE_WIFI)) {
             Log.i(TAG, "testSocketKeepaliveUnprivileged cannot execute unless device"
diff --git a/tests/tests/net/src/android/net/cts/DnsTest.java b/tests/tests/net/src/android/net/cts/DnsTest.java
index 746dcb0..fde27e9 100644
--- a/tests/tests/net/src/android/net/cts/DnsTest.java
+++ b/tests/tests/net/src/android/net/cts/DnsTest.java
@@ -27,6 +27,8 @@
 import android.test.AndroidTestCase;
 import android.util.Log;
 
+import com.android.testutils.SkipPresubmit;
+
 import java.net.Inet4Address;
 import java.net.Inet6Address;
 import java.net.InetAddress;
@@ -68,6 +70,7 @@
      * Perf - measure size of first and second tier caches and their effect
      * Assert requires network permission
      */
+    @SkipPresubmit(reason = "IPv6 support may be missing on presubmit virtual hardware")
     public void testDnsWorks() throws Exception {
         ensureIpv6Connectivity();
 
diff --git a/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java b/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
index 5cc0cb4..9eab024 100644
--- a/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
+++ b/tests/tests/net/src/android/net/cts/Ikev2VpnTest.java
@@ -16,6 +16,7 @@
 
 package android.net.cts;
 
+import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 import static android.net.cts.util.CtsNetUtils.TestNetworkCallback;
 
@@ -40,20 +41,25 @@
 import android.net.IpSecAlgorithm;
 import android.net.LinkAddress;
 import android.net.Network;
+import android.net.NetworkCapabilities;
 import android.net.NetworkRequest;
 import android.net.ProxyInfo;
 import android.net.TestNetworkInterface;
 import android.net.TestNetworkManager;
 import android.net.VpnManager;
 import android.net.cts.util.CtsNetUtils;
+import android.os.Build;
+import android.os.Process;
 import android.platform.test.annotations.AppModeFull;
 
 import androidx.test.InstrumentationRegistry;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.util.HexDump;
 import com.android.org.bouncycastle.x509.X509V1CertificateGenerator;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+import com.android.testutils.DevSdkIgnoreRunner;
 
+import org.junit.After;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -70,7 +76,8 @@
 
 import javax.security.auth.x500.X500Principal;
 
-@RunWith(AndroidJUnit4.class)
+@RunWith(DevSdkIgnoreRunner.class)
+@IgnoreUpTo(Build.VERSION_CODES.Q)
 @AppModeFull(reason = "Appops state changes disallowed for instant apps (OP_ACTIVATE_PLATFORM_VPN)")
 public class Ikev2VpnTest {
     private static final String TAG = Ikev2VpnTest.class.getSimpleName();
@@ -172,6 +179,12 @@
         mUserCertKey = generateRandomCertAndKeyPair();
     }
 
+    @After
+    public void tearDown() {
+        setAppop(AppOpsManager.OP_ACTIVATE_VPN, false);
+        setAppop(AppOpsManager.OP_ACTIVATE_PLATFORM_VPN, false);
+    }
+
     /**
      * Sets the given appop using shell commands
      *
@@ -416,6 +429,11 @@
         final Network vpnNetwork = cb.currentNetwork;
         assertNotNull(vpnNetwork);
 
+        final NetworkCapabilities caps = sCM.getNetworkCapabilities(vpnNetwork);
+        assertTrue(caps.hasTransport(TRANSPORT_VPN));
+        assertTrue(caps.hasCapability(NET_CAPABILITY_INTERNET));
+        assertEquals(Process.myUid(), caps.getOwnerUid());
+
         sVpnMgr.stopProvisionedVpnProfile();
         cb.waitForLost();
         assertEquals(vpnNetwork, cb.lastLostNetwork);
diff --git a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
index 985e313..6d3db89 100644
--- a/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
+++ b/tests/tests/net/src/android/net/cts/MultinetworkApiTest.java
@@ -68,7 +68,6 @@
         mCM = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
         mCR = getContext().getContentResolver();
         mCtsNetUtils = new CtsNetUtils(getContext());
-        mCtsNetUtils.storePrivateDnsSetting();
     }
 
     @Override
@@ -223,6 +222,7 @@
 
     @AppModeFull(reason = "WRITE_SECURE_SETTINGS permission can't be granted to instant apps")
     public void testResNApiNXDomainPrivateDns() throws InterruptedException {
+        mCtsNetUtils.storePrivateDnsSetting();
         // Enable private DNS strict mode and set server to dns.google before doing NxDomain test.
         // b/144521720
         try {
diff --git a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
index 32cdf92..85d2113 100644
--- a/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
+++ b/tests/tests/net/util/java/android/net/cts/util/CtsNetUtils.java
@@ -30,8 +30,8 @@
 import android.annotation.NonNull;
 import android.app.AppOpsManager;
 import android.content.BroadcastReceiver;
-import android.content.Context;
 import android.content.ContentResolver;
+import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.PackageManager;
@@ -44,6 +44,8 @@
 import android.net.NetworkInfo.State;
 import android.net.NetworkRequest;
 import android.net.TestNetworkManager;
+import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Binder;
 import android.os.Build;
@@ -155,8 +157,36 @@
         }
     }
 
-    /** Enable WiFi and wait for it to become connected to a network. */
+    /**
+     * Enable WiFi and wait for it to become connected to a network.
+     *
+     * This method expects to receive a legacy broadcast on connect, which may not be sent if the
+     * network does not become default or if it is not the first network.
+     */
     public Network connectToWifi() {
+        return connectToWifi(true /* expectLegacyBroadcast */);
+    }
+
+    /**
+     * Enable WiFi and wait for it to become connected to a network.
+     *
+     * A network is considered connected when a {@link NetworkCallback#onAvailable(Network)}
+     * callback is received.
+     */
+    public Network ensureWifiConnected() {
+        return connectToWifi(false /* expectLegacyBroadcast */);
+    }
+
+    /**
+     * Enable WiFi and wait for it to become connected to a network.
+     *
+     * @param expectLegacyBroadcast Whether to check for a legacy CONNECTIVITY_ACTION connected
+     *                              broadcast. The broadcast is typically not sent if the network
+     *                              does not become the default network, and is not the first
+     *                              network to appear.
+     * @return The network that was newly connected.
+     */
+    private Network connectToWifi(boolean expectLegacyBroadcast) {
         final TestNetworkCallback callback = new TestNetworkCallback();
         mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
         Network wifiNetwork = null;
@@ -168,14 +198,16 @@
         mContext.registerReceiver(receiver, filter);
 
         boolean connected = false;
+        final String err = "Wifi must be configured to connect to an access point for this test.";
         try {
+            clearWifiBlacklist();
             SystemUtil.runShellCommand("svc wifi enable");
             SystemUtil.runWithShellPermissionIdentity(() -> mWifiManager.reconnect(),
                     NETWORK_SETTINGS);
-            // Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION.
+            // Ensure we get an onAvailable callback and possibly a CONNECTIVITY_ACTION.
             wifiNetwork = callback.waitForAvailable();
-            assertNotNull(wifiNetwork);
-            connected = receiver.waitForState();
+            assertNotNull(err, wifiNetwork);
+            connected = !expectLegacyBroadcast || receiver.waitForState();
         } catch (InterruptedException ex) {
             fail("connectToWifi was interrupted");
         } finally {
@@ -183,16 +215,66 @@
             mContext.unregisterReceiver(receiver);
         }
 
-        assertTrue("Wifi must be configured to connect to an access point for this test.",
-                connected);
+        assertTrue(err, connected);
         return wifiNetwork;
     }
 
-    /** Disable WiFi and wait for it to become disconnected from the network. */
+    /**
+     * Re-enable wifi networks that were blacklisted, typically because no internet connection was
+     * detected the last time they were connected. This is necessary to make sure wifi can reconnect
+     * to them.
+     */
+    private void clearWifiBlacklist() {
+        SystemUtil.runWithShellPermissionIdentity(() -> {
+            for (WifiConfiguration config : mWifiManager.getConfiguredNetworks()) {
+                mWifiManager.enableNetwork(config.networkId, false /* attemptConnect */);
+            }
+        });
+    }
+
+    /**
+     * Disable WiFi and wait for it to become disconnected from the network.
+     *
+     * This method expects to receive a legacy broadcast on disconnect, which may not be sent if the
+     * network was not default, or was not the first network.
+     *
+     * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network
+     *                           is expected to be able to establish a TCP connection to a remote
+     *                           server before disconnecting, and to have that connection closed in
+     *                           the process.
+     */
     public void disconnectFromWifi(Network wifiNetworkToCheck) {
+        disconnectFromWifi(wifiNetworkToCheck, true /* expectLegacyBroadcast */);
+    }
+
+    /**
+     * Disable WiFi and wait for it to become disconnected from the network.
+     *
+     * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network
+     *                           is expected to be able to establish a TCP connection to a remote
+     *                           server before disconnecting, and to have that connection closed in
+     *                           the process.
+     */
+    public void ensureWifiDisconnected(Network wifiNetworkToCheck) {
+        disconnectFromWifi(wifiNetworkToCheck, false /* expectLegacyBroadcast */);
+    }
+
+    /**
+     * Disable WiFi and wait for it to become disconnected from the network.
+     *
+     * @param wifiNetworkToCheck If non-null, a network that should be disconnected. This network
+     *                           is expected to be able to establish a TCP connection to a remote
+     *                           server before disconnecting, and to have that connection closed in
+     *                           the process.
+     * @param expectLegacyBroadcast Whether to check for a legacy CONNECTIVITY_ACTION disconnected
+     *                              broadcast. The broadcast is typically not sent if the network
+     *                              was not the default network and not the first network to appear.
+     *                              The check will always be skipped if the device was not connected
+     *                              to wifi in the first place.
+     */
+    private void disconnectFromWifi(Network wifiNetworkToCheck, boolean expectLegacyBroadcast) {
         final TestNetworkCallback callback = new TestNetworkCallback();
         mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
-        Network lostWifiNetwork = null;
 
         ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
                 mCm, ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
@@ -200,9 +282,15 @@
         filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         mContext.registerReceiver(receiver, filter);
 
+        final WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
+        final boolean wasWifiConnected = wifiInfo != null && wifiInfo.getNetworkId() != -1;
         // Assert that we can establish a TCP connection on wifi.
         Socket wifiBoundSocket = null;
         if (wifiNetworkToCheck != null) {
+            assertTrue("Cannot check network " + wifiNetworkToCheck + ": wifi is not connected",
+                    wasWifiConnected);
+            final NetworkCapabilities nc = mCm.getNetworkCapabilities(wifiNetworkToCheck);
+            assertNotNull("Network " + wifiNetworkToCheck + " is not connected", nc);
             try {
                 wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT);
                 testHttpRequest(wifiBoundSocket);
@@ -211,13 +299,16 @@
             }
         }
 
-        boolean disconnected = false;
         try {
             SystemUtil.runShellCommand("svc wifi disable");
-            // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
-            lostWifiNetwork = callback.waitForLost();
-            assertNotNull(lostWifiNetwork);
-            disconnected = receiver.waitForState();
+            if (wasWifiConnected) {
+                // Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
+                assertNotNull("Did not receive onLost callback after disabling wifi",
+                        callback.waitForLost());
+            }
+            if (wasWifiConnected && expectLegacyBroadcast) {
+                assertTrue("Wifi failed to reach DISCONNECTED state.", receiver.waitForState());
+            }
         } catch (InterruptedException ex) {
             fail("disconnectFromWifi was interrupted");
         } finally {
@@ -225,8 +316,6 @@
             mContext.unregisterReceiver(receiver);
         }
 
-        assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
-
         // Check that the socket is closed when wifi disconnects.
         if (wifiBoundSocket != null) {
             try {
diff --git a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
index a62248e..67c4443 100644
--- a/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
+++ b/tests/tests/permission/src/android/permission/cts/LocationAccessCheckTest.java
@@ -58,6 +58,7 @@
 import android.os.Looper;
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.AppModeFull;
+import android.platform.test.annotations.SecurityTest;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
@@ -540,6 +541,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void notificationIsShownOnlyOnce() throws Throwable {
         accessLocation();
         getNotification(true);
@@ -548,6 +550,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void notificationIsShownAgainAfterClear() throws Throwable {
         accessLocation();
         getNotification(true);
@@ -584,6 +587,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void removeNotificationOnUninstall() throws Throwable {
         accessLocation();
         getNotification(false);
@@ -623,6 +627,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void noNotificationIfFeatureDisabled() throws Throwable {
         disableLocationAccessCheck();
         accessLocation();
@@ -630,6 +635,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void notificationOnlyForAccessesSinceFeatureWasEnabled() throws Throwable {
         // Disable the feature and access location in disabled state
         disableLocationAccessCheck();
@@ -646,6 +652,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void noNotificationIfBlamerNotSystemOrLocationProvider() throws Throwable {
         // Blame the app for access from an untrusted for notification purposes package.
         runWithShellPermissionIdentity(() -> {
@@ -657,6 +664,7 @@
     }
 
     @Test
+    @SecurityTest(minPatchLevel="2019-12-01")
     public void testOpeningLocationSettingsDoesNotTriggerAccess() throws Throwable {
         Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
diff --git a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
index 8609e33..84c2dd6 100644
--- a/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
+++ b/tests/tests/permission/src/android/permission/cts/ServicesInstantAppsCannotAccessTests.java
@@ -25,11 +25,15 @@
 import static android.content.Context.WIFI_P2P_SERVICE;
 import static android.content.Context.WIFI_SERVICE;
 
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 
+import android.app.WallpaperManager;
 import android.content.Context;
 import android.platform.test.annotations.AppModeInstant;
 
+import com.android.compatibility.common.util.RequiredServiceRule;
+
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
@@ -68,8 +72,14 @@
 
     @Test
     public void cannotGetWallpaperManager() {
-        assertNull(InstrumentationRegistry.getTargetContext().getSystemService(
-                WALLPAPER_SERVICE));
+        WallpaperManager mgr  = (WallpaperManager) InstrumentationRegistry.getTargetContext()
+                .getSystemService(WALLPAPER_SERVICE);
+        boolean supported = RequiredServiceRule.hasService("wallpaper");
+        if (supported) {
+            assertNull(mgr);
+        } else {
+            assertFalse(mgr.isWallpaperSupported());
+        }
     }
 
     @Test
diff --git a/tests/tests/permission2/res/raw/android_manifest.xml b/tests/tests/permission2/res/raw/android_manifest.xml
index a52ae96..59375ab 100644
--- a/tests/tests/permission2/res/raw/android_manifest.xml
+++ b/tests/tests/permission2/res/raw/android_manifest.xml
@@ -1215,6 +1215,15 @@
         android:protectionLevel="dangerous|instant" />
 
 
+    <!-- Allows receiving the camera service notifications when a camera is opened
+        (by a certain application package) or closed.
+        @hide -->
+    <permission android:name="android.permission.CAMERA_OPEN_CLOSE_LISTENER"
+        android:permissionGroup="android.permission-group.UNDEFINED"
+        android:label="@string/permlab_cameraOpenCloseListener"
+        android:description="@string/permdesc_cameraOpenCloseListener"
+        android:protectionLevel="signature" />
+
     <!-- ====================================================================== -->
     <!-- Permissions for accessing the device sensors                           -->
     <!-- ====================================================================== -->
@@ -4507,12 +4516,12 @@
     <!-- @SystemApi Allows to access all app shortcuts.
          @hide -->
     <permission android:name="android.permission.ACCESS_SHORTCUTS"
-        android:protectionLevel="signature|textClassifier" />
+        android:protectionLevel="signature|appPredictor" />
 
     <!-- @SystemApi Allows unlimited calls to shortcut mutation APIs.
          @hide -->
     <permission android:name="android.permission.UNLIMITED_SHORTCUTS_API_CALLS"
-        android:protectionLevel="signature|textClassifier" />
+        android:protectionLevel="signature|appPredictor" />
 
     <!-- @SystemApi Allows an application to read the runtime profiles of other apps.
          @hide <p>Not for use by third-party applications. -->
diff --git a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
index 9e09a7b..c2becc7 100644
--- a/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
+++ b/tests/tests/permission2/src/android/permission2/cts/PermissionPolicyTest.java
@@ -28,6 +28,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PermissionGroupInfo;
 import android.content.pm.PermissionInfo;
+import android.os.Build;
 import android.os.storage.StorageManager;
 import android.platform.test.annotations.AppModeFull;
 import android.util.ArrayMap;
@@ -82,6 +83,9 @@
     private static final String ATTR_PROTECTION_LEVEL = "protectionLevel";
     private static final String ATTR_BACKGROUND_PERMISSION = "backgroundPermission";
 
+    private static final String CAMERA_OPEN_CLOSE_LISTENER_PERMISSION =
+            "android.permission.CAMERA_OPEN_CLOSE_LISTENER";
+
     private static final Context sContext =
             InstrumentationRegistry.getInstrumentation().getTargetContext();
 
@@ -116,6 +120,13 @@
                 continue;
             }
 
+            // Skip CAMERA OPEN_CLOSE_LISTENER_PERMISSION check for Android Q
+            if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.Q
+                    && expectedPermissionName.equals(CAMERA_OPEN_CLOSE_LISTENER_PERMISSION)) {
+                declaredPermissionsMap.remove(expectedPermissionName);
+                continue;
+            }
+
             // OEMs cannot remove permissions
             PermissionInfo declaredPermission = declaredPermissionsMap.get(expectedPermissionName);
             if (declaredPermission == null) {
diff --git a/tests/tests/role/CtsRoleTestApp/Android.bp b/tests/tests/role/CtsRoleTestApp/Android.bp
index 4ccb35d..e89468a 100644
--- a/tests/tests/role/CtsRoleTestApp/Android.bp
+++ b/tests/tests/role/CtsRoleTestApp/Android.bp
@@ -24,5 +24,6 @@
         "cts",
         "vts10",
         "general-tests",
+        "mts",
     ]
 }
diff --git a/tests/tests/role/CtsRoleTestApp28/Android.bp b/tests/tests/role/CtsRoleTestApp28/Android.bp
index 2a99ebb..114a8a4 100644
--- a/tests/tests/role/CtsRoleTestApp28/Android.bp
+++ b/tests/tests/role/CtsRoleTestApp28/Android.bp
@@ -24,5 +24,6 @@
         "cts",
         "vts10",
         "general-tests",
+        "mts",
     ]
 }
diff --git a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
index da99ff0..5d56ded 100644
--- a/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
+++ b/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java
@@ -24,6 +24,7 @@
 
 import android.content.pm.PackageManager;
 import android.os.Build;
+import android.os.SystemProperties;
 import android.se.omapi.Channel;
 import android.se.omapi.Reader;
 import android.se.omapi.SEService;
@@ -154,7 +155,7 @@
 
     private boolean supportsHardware() {
         final PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
-        boolean lowRamDevice = PropertyUtil.propertyEquals("ro.config.low_ram", "true");
+        boolean lowRamDevice = SystemProperties.getBoolean("ro.config.low_ram", false);
         return !lowRamDevice || pm.hasSystemFeature("android.hardware.type.watch")
                 || hasSecureElementPackage(pm);
     }
diff --git a/tests/tests/security/res/raw/bug_110435401.mid b/tests/tests/security/res/raw/bug_110435401.mid
deleted file mode 100644
index 184ab1f..0000000
--- a/tests/tests/security/res/raw/bug_110435401.mid
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_123700383.mid b/tests/tests/security/res/raw/bug_123700383.mid
new file mode 100644
index 0000000..1e1ae6b
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_123700383.mid
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_127310810.mid b/tests/tests/security/res/raw/bug_127310810.mid
new file mode 100644
index 0000000..8a64142
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_127310810.mid
@@ -0,0 +1,3 @@
+BEGIN:IMELODY
+BEAT:900
+MELODY:((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((ledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonledonr5;@32767)
\ No newline at end of file
diff --git a/tests/tests/security/res/raw/bug_127312550.mid b/tests/tests/security/res/raw/bug_127312550.mid
new file mode 100644
index 0000000..ea66e75
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_127312550.mid
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_127313223.mid b/tests/tests/security/res/raw/bug_127313223.mid
new file mode 100644
index 0000000..6558be7
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_127313223.mid
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_127313537.mid b/tests/tests/security/res/raw/bug_127313537.mid
new file mode 100644
index 0000000..658ab923
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_127313537.mid
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_127313764.mid b/tests/tests/security/res/raw/bug_127313764.mid
new file mode 100644
index 0000000..bda2dfb
--- /dev/null
+++ b/tests/tests/security/res/raw/bug_127313764.mid
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_26366256.midi b/tests/tests/security/res/raw/bug_26366256.midi
deleted file mode 100644
index 5114d92..0000000
--- a/tests/tests/security/res/raw/bug_26366256.midi
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/bug_68664359.mid b/tests/tests/security/res/raw/bug_68664359.mid
deleted file mode 100644
index f816d82..0000000
--- a/tests/tests/security/res/raw/bug_68664359.mid
+++ /dev/null
@@ -1 +0,0 @@
-DK:@~kkkkk
\ No newline at end of file
diff --git a/tests/tests/security/res/raw/bug_68953854.mid b/tests/tests/security/res/raw/bug_68953854.mid
deleted file mode 100644
index ce9432d6..0000000
--- a/tests/tests/security/res/raw/bug_68953854.mid
+++ /dev/null
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10533.mp4 b/tests/tests/security/res/raw/cve_2019_10533.mp4
new file mode 100644
index 0000000..619a0f3
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10533.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10534.mp4 b/tests/tests/security/res/raw/cve_2019_10534.mp4
new file mode 100644
index 0000000..bdcc52d
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10534.mp4
Binary files differ
diff --git a/tests/tests/security/res/raw/cve_2019_10541.mp4 b/tests/tests/security/res/raw/cve_2019_10541.mp4
new file mode 100644
index 0000000..6b1d167
--- /dev/null
+++ b/tests/tests/security/res/raw/cve_2019_10541.mp4
Binary files differ
diff --git a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
index 5a035dd..47730e1 100644
--- a/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
+++ b/tests/tests/security/src/android/security/cts/ActivityManagerTest.java
@@ -15,11 +15,15 @@
  */
 package android.security.cts;
 
+import android.app.ActivityManager;
 import android.os.IBinder;
 import android.platform.test.annotations.SecurityTest;
+import android.util.Log;
 
 import junit.framework.TestCase;
 
+import java.lang.reflect.InvocationTargetException;
+
 @SecurityTest
 public class ActivityManagerTest extends TestCase {
 
@@ -44,4 +48,32 @@
             // Patched devices should throw this exception
         }
     }
+
+    // b/144285917
+    @SecurityTest(minPatchLevel = "2020-05")
+    public void testActivityManager_attachNullApplication() {
+        SecurityException securityException = null;
+        Exception unexpectedException = null;
+        try {
+            final Object iam = ActivityManager.class.getDeclaredMethod("getService").invoke(null);
+            Class.forName("android.app.IActivityManager").getDeclaredMethod("attachApplication",
+                    Class.forName("android.app.IApplicationThread"), long.class)
+                    .invoke(iam, null /* thread */, 0 /* startSeq */);
+        } catch (SecurityException e) {
+            securityException = e;
+        } catch (InvocationTargetException e) {
+            if (e.getCause() instanceof SecurityException) {
+                securityException = (SecurityException) e.getCause();
+            } else {
+                unexpectedException = e;
+            }
+        } catch (Exception e) {
+            unexpectedException = e;
+        }
+        if (unexpectedException != null) {
+            Log.w("ActivityManagerTest", "Unexpected exception", unexpectedException);
+        }
+
+        assertNotNull("Expect SecurityException by attaching null application", securityException);
+    }
 }
diff --git a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
index b621491..a324fd7 100644
--- a/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
+++ b/tests/tests/security/src/android/security/cts/NanoAppBundleTest.java
@@ -48,9 +48,11 @@
 
 import android.util.Log;
 import android.annotation.Nullable;
+import android.platform.test.annotations.AppModeFull;
 import static java.lang.Thread.sleep;
 import static org.junit.Assert.assertTrue;
 
+@AppModeFull
 @SecurityTest
 public class NanoAppBundleTest extends AndroidTestCase {
 
@@ -130,7 +132,7 @@
             ActivityInfo info = intent.resolveActivityInfo(
                     mContext.getPackageManager(), intent.getFlags());
             // Will throw NullPointerException if activity not found.
-            if (info.exported) {
+            if (info != null && info.exported) {
                 mContext.startActivity(intent);
             } else {
                 Log.i(TAG, "Activity is not exported");
diff --git a/tests/tests/security/src/android/security/cts/StagefrightTest.java b/tests/tests/security/src/android/security/cts/StagefrightTest.java
index 236f798..ea858f5 100644
--- a/tests/tests/security/src/android/security/cts/StagefrightTest.java
+++ b/tests/tests/security/src/android/security/cts/StagefrightTest.java
@@ -22,8 +22,7 @@
  */
 package android.security.cts;
 
-import android.test.AndroidTestCase;
-import android.util.Log;
+import android.app.Instrumentation;
 import android.content.Context;
 import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
@@ -42,7 +41,6 @@
 import android.os.Looper;
 import android.os.SystemClock;
 import android.platform.test.annotations.SecurityTest;
-import android.test.InstrumentationTestCase;
 import android.util.Log;
 import android.view.Surface;
 import android.webkit.cts.CtsTestServer;
@@ -80,18 +78,35 @@
 import android.security.NetworkSecurityPolicy;
 import android.media.TimedText;
 
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Rule;
+import org.junit.rules.TestName;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assume.*;
+import static org.junit.Assert.*;
+
 /**
  * Verify that the device is not vulnerable to any known Stagefright
  * vulnerabilities.
  */
-@SecurityTest
-public class StagefrightTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class StagefrightTest {
     static final String TAG = "StagefrightTest";
+    private Instrumentation mInstrumentation;
 
     private final long TIMEOUT_NS = 10000000000L;  // 10 seconds.
     private final static long CHECK_INTERVAL = 50;
 
-    public StagefrightTest() {
+    @Rule public TestName name = new TestName();
+
+    @Before
+    public void setup() {
+        mInstrumentation = InstrumentationRegistry.getInstrumentation();
     }
 
     /***********************************************************
@@ -99,177 +114,206 @@
      before any existing test methods
      ***********************************************************/
 
+    @Test
     @SecurityTest(minPatchLevel = "2019-04")
     public void testStagefright_cve_2019_2244() throws Exception {
         doStagefrightTestRawBlob(R.raw.cve_2019_2244, "video/mpeg2", 320, 420);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_36725407() throws Exception {
         doStagefrightTest(R.raw.bug_36725407);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3829() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3829, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_cve_2017_0643() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0643, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_cve_2017_0728() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0728, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-10")
     public void testStagefright_bug_62187433() throws Exception {
         doStagefrightTest(R.raw.bug_62187433);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefrightANR_bug_62673844() throws Exception {
         doStagefrightTestANR(R.raw.bug_62673844);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_37079296() throws Exception {
         doStagefrightTest(R.raw.bug_37079296);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_38342499() throws Exception {
         doStagefrightTest(R.raw.bug_38342499);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_bug_22771132() throws Exception {
         doStagefrightTest(R.raw.bug_22771132);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_bug_21443020() throws Exception {
         doStagefrightTest(R.raw.bug_21443020_webm);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-03")
     public void testStagefright_bug_34360591() throws Exception {
         doStagefrightTest(R.raw.bug_34360591);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35763994() throws Exception {
         doStagefrightTest(R.raw.bug_35763994, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testStagefright_bug_33137046() throws Exception {
         doStagefrightTest(R.raw.bug_33137046);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2016_2507() throws Exception {
         doStagefrightTest(R.raw.cve_2016_2507, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testStagefright_bug_31647370() throws Exception {
         doStagefrightTest(R.raw.bug_31647370);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-01")
     public void testStagefright_bug_32577290() throws Exception {
         doStagefrightTest(R.raw.bug_32577290);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2015_1538_1() throws Exception {
         doStagefrightTest(R.raw.cve_2015_1538_1);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2015_1538_2() throws Exception {
         doStagefrightTest(R.raw.cve_2015_1538_2);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2015_1538_3() throws Exception {
         doStagefrightTest(R.raw.cve_2015_1538_3);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2015_1538_4() throws Exception {
         doStagefrightTest(R.raw.cve_2015_1538_4);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_cve_2015_1539() throws Exception {
         doStagefrightTest(R.raw.cve_2015_1539);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3824() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3824);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3826() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3826);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3827() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3827);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3828() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3828);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3829() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3829);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3836() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3836);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3864() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3864);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-01")
     public void testStagefright_cve_2015_3864_b23034759() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3864_b23034759);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_6598() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6598);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6766() throws Exception {
         doStagefrightTest(R.raw.cve_2016_6766);
     }
 
-    @SecurityTest(minPatchLevel = "2016-04")
-    public void testStagefright_bug_26366256() throws Exception {
-        doStagefrightTest(R.raw.bug_26366256);
-    }
-
+    @Test
     @SecurityTest(minPatchLevel = "2017-02")
     public void testStagefright_cve_2016_2429_b_27211885() throws Exception {
         doStagefrightTest(R.raw.cve_2016_2429_b_27211885,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_34031018() throws Exception {
         doStagefrightTest(R.raw.bug_34031018_32bit, new CrashUtils.Config().checkMinAddress(false));
@@ -281,32 +325,38 @@
      before any existing test methods
      ***********************************************************/
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_bug_65123471() throws Exception {
         doStagefrightTest(R.raw.bug_65123471);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testStagefright_bug_72165027() throws Exception {
         doStagefrightTest(R.raw.bug_72165027);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-06")
     public void testStagefright_bug_65483665() throws Exception {
         doStagefrightTest(R.raw.bug_65483665);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_cve_2017_0852_b_62815506() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0852_b_62815506,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testStagefright_cve_2017_13229() throws Exception {
         doStagefrightTest(R.raw.cve_2017_13229);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_cve_2017_0763() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0763);
@@ -317,82 +367,92 @@
      before any existing test methods
      ***********************************************************/
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-06")
     public void testBug_73965890() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_73965890_framelen);
         doStagefrightTestRawBlob(R.raw.bug_73965890_hevc, "video/hevc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-10")
     public void testStagefright_cve_2016_3920() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3920, new CrashUtils.Config().checkMinAddress(false));
     }
 
-    @SecurityTest(minPatchLevel = "2018-06")
-    public void testStagefright_bug_68953854() throws Exception {
-        doStagefrightTest(R.raw.bug_68953854, 1 * 60 * 1000);
-    }
-
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_38448381() throws Exception {
         doStagefrightTest(R.raw.bug_38448381);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3821() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3821, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testStagefright_bug_70897454() throws Exception {
         doStagefrightTestRawBlob(R.raw.b70897454_avc, "video/avc", 320, 420);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_3742_b_28165659() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3742_b_28165659);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_bug_35039946() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_35039946_hevc, "video/hevc", 320, 420);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_38115076() throws Exception {
         doStagefrightTest(R.raw.bug_38115076, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_bug_34618607() throws Exception {
         doStagefrightTest(R.raw.bug_34618607, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testStagefright_bug_69478425() throws Exception {
         doStagefrightTest(R.raw.bug_69478425);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_bug_65735716() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_65735716_avc, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-12")
     public void testStagefright_bug_65717533() throws Exception {
         doStagefrightTest(R.raw.bug_65717533_header_corrupt);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_38239864() throws Exception {
         doStagefrightTest(R.raw.bug_38239864, (4 * 60 * 1000));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_cve_2017_0600() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0600, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug_38014992() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_38014992_framelen);
@@ -400,30 +460,35 @@
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testBug_35584425() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_35584425_framelen);
         doStagefrightTestRawBlob(R.raw.bug_35584425_avc, "video/avc", 352, 288, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testBug_31092462() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_31092462_framelen);
         doStagefrightTestRawBlob(R.raw.bug_31092462_avc, "video/avc", 1280, 1024, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testBug_34097866() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_34097866_frame_len);
         doStagefrightTestRawBlob(R.raw.bug_34097866_avc, "video/avc", 352, 288, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33862021() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_33862021_frame_len);
         doStagefrightTestRawBlob(R.raw.bug_33862021_hevc, "video/hevc", 160, 96, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33387820() throws Exception {
         int[] frameSizes = {45, 3202, 430, 2526};
@@ -431,43 +496,51 @@
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testBug_37008096() throws Exception {
         int[] frameSizes = {245, 12, 33, 140, 164};
         doStagefrightTestRawBlob(R.raw.bug_37008096_avc, "video/avc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_34231163() throws Exception {
         int[] frameSizes = {22, 357, 217, 293, 175};
         doStagefrightTestRawBlob(R.raw.bug_34231163_mpeg2, "video/mpeg2", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testStagefright_bug_33933140() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_33933140_framelen);
         doStagefrightTestRawBlob(R.raw.bug_33933140_avc, "video/avc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testStagefright_bug_34097915() throws Exception {
         int[] frameSizes = {4140, 593, 0, 15495};
         doStagefrightTestRawBlob(R.raw.bug_34097915_avc, "video/avc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testStagefright_bug_34097213() throws Exception {
         int[] frameSizes = {2571, 210, 33858};
         doStagefrightTestRawBlob(R.raw.bug_34097213_avc, "video/avc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-08")
     public void testBug_28816956() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_28816956_framelen);
-        doStagefrightTestRawBlob(R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes,
-                new CrashUtils.Config().checkMinAddress(false));
+        doStagefrightTestRawBlob(
+                R.raw.bug_28816956_hevc, "video/hevc", 352, 288, frameSizes,
+                    new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33818500() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_33818500_framelen);
@@ -475,96 +548,114 @@
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testBug_64784973() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_64784973_framelen);
         doStagefrightTestRawBlob(R.raw.bug_64784973_hevc, "video/hevc", 1280, 720, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testBug_34231231() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_34231231_framelen);
         doStagefrightTestRawBlob(R.raw.bug_34231231_mpeg2, "video/mpeg2", 352, 288, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-10")
     public void testBug_63045918() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_63045918_framelen);
         doStagefrightTestRawBlob(R.raw.bug_63045918_hevc, "video/hevc", 352, 288, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33298089() throws Exception {
         int[] frameSizes = {3247, 430, 221, 2305};
         doStagefrightTestRawBlob(R.raw.bug_33298089_avc, "video/avc", 32, 64, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_cve_2017_0599() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0599, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_36492741() throws Exception {
         doStagefrightTest(R.raw.bug_36492741);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_38487564() throws Exception {
         doStagefrightTest(R.raw.bug_38487564, (4 * 60 * 1000));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_37237396() throws Exception {
         doStagefrightTest(R.raw.bug_37237396);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_cve_2016_0842() throws Exception {
         doStagefrightTest(R.raw.cve_2016_0842);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-11")
     public void testStagefright_bug_63121644() throws Exception {
         doStagefrightTest(R.raw.bug_63121644);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_cve_2016_6712() throws Exception {
         doStagefrightTest(R.raw.cve_2016_6712, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testStagefright_bug_34097231() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_34097231_avc, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testStagefright_bug_34097672() throws Exception {
         doStagefrightTest(R.raw.bug_34097672);
     }
 
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testStagefright_bug_33751193() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_33751193_avc, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testBug_36993291() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_36993291_avc, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_33818508() throws Exception {
         doStagefrightTest(R.raw.bug_33818508, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_32873375() throws Exception {
         doStagefrightTest(R.raw.bug_32873375, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testStagefright_bug_63522067() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_63522067_1_hevc, "video/hevc", 320, 420);
@@ -573,66 +664,79 @@
         doStagefrightTestRawBlob(R.raw.bug_63522067_4_hevc, "video/hevc", 320, 420);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-03")
     public void testStagefright_bug_25765591() throws Exception {
         doStagefrightTest(R.raw.bug_25765591);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_62673179() throws Exception {
         doStagefrightTest(R.raw.bug_62673179_ts, (4 * 60 * 1000));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-03")
     public void testStagefright_bug_69269702() throws Exception {
         doStagefrightTest(R.raw.bug_69269702);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3867() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3867);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_bug_65398821() throws Exception {
         doStagefrightTest(R.raw.bug_65398821, ( 4 * 60 * 1000 ) );
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3869() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3869);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-03")
     public void testStagefright_bug_23452792() throws Exception {
         doStagefrightTest(R.raw.bug_23452792);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-08")
     public void testStagefright_cve_2016_3820() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3820);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_3741() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3741);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_2506() throws Exception {
         doStagefrightTest(R.raw.cve_2016_2506);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-06")
     public void testStagefright_cve_2016_2428() throws Exception {
         doStagefrightTest(R.raw.cve_2016_2428, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_3756() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3756);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_36592202() throws Exception {
         Resources resources = getInstrumentation().getContext().getResources();
@@ -682,138 +786,165 @@
         }
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testStagefright_bug_30822755() throws Exception {
         doStagefrightTest(R.raw.bug_30822755);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_32322258() throws Exception {
         doStagefrightTest(R.raw.bug_32322258, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3873_b_23248776() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3873_b_23248776);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35472997() throws Exception {
         doStagefrightTest(R.raw.bug_35472997);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3873_b_20718524() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3873_b_20718524);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_34896431() throws Exception {
         doStagefrightTest(R.raw.bug_34896431);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-04")
     public void testBug_33641588() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_33641588_avc, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3862_b_22954006() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3862_b_22954006,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3867_b_23213430() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3867_b_23213430);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3873_b_21814993() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3873_b_21814993);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testStagefright_bug_25812590() throws Exception {
         doStagefrightTest(R.raw.bug_25812590);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_6600() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6600);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_6603() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6603);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_6604() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6604);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-12")
     public void testStagefright_bug_24157524() throws Exception {
         doStagefrightTestMediaCodec(R.raw.bug_24157524);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-10")
     public void testStagefright_cve_2015_3871() throws Exception {
         doStagefrightTest(R.raw.cve_2015_3871);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testStagefright_bug_26070014() throws Exception {
         doStagefrightTest(R.raw.bug_26070014);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testStagefright_bug_32915871() throws Exception {
         doStagefrightTest(R.raw.bug_32915871);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_bug_28333006() throws Exception {
         doStagefrightTest(R.raw.bug_28333006);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-11")
     public void testStagefright_bug_14388161() throws Exception {
         doStagefrightTestMediaPlayer(R.raw.bug_14388161);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_3755() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3755, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-09")
     public void testStagefright_cve_2016_3878_b_29493002() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3878_b_29493002,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug_36819262() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_36819262_mpeg2, "video/mpeg2", 640, 480);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-11")
     public void testStagefright_cve_2015_6608_b_23680780() throws Exception {
         doStagefrightTest(R.raw.cve_2015_6608_b_23680780);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_bug_36715268() throws Exception {
         doStagefrightTest(R.raw.bug_36715268);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-06")
     public void testStagefright_bug_27855419_CVE_2016_2463() throws Exception {
         doStagefrightTest(R.raw.bug_27855419, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-11")
     public void testStagefright_bug_19779574() throws Exception {
         doStagefrightTest(R.raw.bug_19779574, new CrashUtils.Config().checkMinAddress(false));
@@ -823,17 +954,21 @@
      to prevent merge conflicts, add N tests below this comment,
      before any existing test methods
      ***********************************************************/
+
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33090864() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_33090864_framelen);
         doStagefrightTestRawBlob(R.raw.bug_33090864_avc, "video/avc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_36279112() throws Exception {
         doStagefrightTest(R.raw.bug_36279112, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_cve_2017_0640() throws Exception {
         int[] frameSizes = {21, 4};
@@ -841,28 +976,33 @@
                 frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug_37203196() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_37203196_framelen);
         doStagefrightTestRawBlob(R.raw.bug_37203196_mpeg2, "video/mpeg2", 48, 48, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-06")
     public void testBug_73552574() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_73552574_framelen);
         doStagefrightTestRawBlob(R.raw.bug_73552574_avc, "video/avc", 320, 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2015-09")
     public void testStagefright_bug_23285192() throws Exception {
         doStagefrightTest(R.raw.bug_23285192);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-03")
     public void testStagefright_bug_25928803() throws Exception {
         doStagefrightTest(R.raw.bug_25928803);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-04")
     public void testBug_26399350() throws Exception {
         int[] frameSizes = {657, 54930};
@@ -870,11 +1010,13 @@
                 frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-12")
     public void testBug_113260892() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_113260892_hevc, "video/hevc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testStagefright_bug_68342866() throws Exception {
         NetworkSecurityPolicy policy = NetworkSecurityPolicy.getInstance();
@@ -913,8 +1055,8 @@
         };
         server.start();
         String uri = "http://127.0.0.1:8080/bug_68342866.m3u8";
-        final MediaPlayerCrashListener mpcl = new MediaPlayerCrashListener(
-                new CrashUtils.Config().checkMinAddress(false));
+        final MediaPlayerCrashListener mpcl =
+                new MediaPlayerCrashListener(new CrashUtils.Config().checkMinAddress(false));
         LooperThread t = new LooperThread(new Runnable() {
             @Override
             public void run() {
@@ -948,54 +1090,54 @@
         server.join();
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-05")
     public void testStagefright_bug_74114680() throws Exception {
         doStagefrightTest(R.raw.bug_74114680_ts, (10 * 60 * 1000));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-03")
     public void testStagefright_bug_70239507() throws Exception {
         doStagefrightTestExtractorSeek(R.raw.bug_70239507,1311768465173141112L);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testBug_33250932() throws Exception {
     int[] frameSizes = {65, 11, 102, 414};
     doStagefrightTestRawBlob(R.raw.bug_33250932_avc, "video/avc", 640, 480, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testStagefright_bug_37430213() throws Exception {
     doStagefrightTest(R.raw.bug_37430213);
     }
 
-    @SecurityTest(minPatchLevel = "2018-11")
-    public void testStagefright_bug_68664359() throws Exception {
-        doStagefrightTest(R.raw.bug_68664359, 60000);
-    }
-
-    @SecurityTest(minPatchLevel = "2018-11")
-    public void testStagefright_bug_110435401() throws Exception {
-        doStagefrightTest(R.raw.bug_110435401, 60000);
-    }
-
+    @Test
     @SecurityTest(minPatchLevel = "2017-03")
     public void testStagefright_cve_2017_0474() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0474, 120000);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-09")
     public void testStagefright_cve_2017_0765() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0765);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testStagefright_cve_2017_13279() throws Exception {
       Thread server = new Thread() {
         @Override
         public void run(){
-          try (ServerSocket serverSocket = new ServerSocket(8080);
-            Socket conn = serverSocket.accept()){
+          try (ServerSocket serverSocket = new ServerSocket(8080) {
+                  {setSoTimeout(10_000);} // time out after 10 seconds
+              };
+              Socket conn = serverSocket.accept()
+          ) {
               OutputStream stream = conn.getOutputStream();
               byte http[] = ("HTTP/1.0 200 OK\r\nContent-Type: application/x-mpegURL\r\n\r\n"
                            + "#EXTM3U\n#EXT-X-STREAM-INF:\n").getBytes();
@@ -1070,21 +1212,25 @@
       server.join();
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testStagefright_cve_2017_13276() throws Exception {
         doStagefrightTest(R.raw.cve_2017_13276);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6764() throws Exception {
         doStagefrightTest(R.raw.cve_2016_6764, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_cve_2017_13214() throws Exception {
         doStagefrightTest(R.raw.cve_2017_13214);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_bug_35467107() throws Exception {
         doStagefrightTest(R.raw.bug_35467107, new CrashUtils.Config().checkMinAddress(false));
@@ -1095,12 +1241,32 @@
      before any existing test methods
      ***********************************************************/
 
+    @Test
+    @SecurityTest(minPatchLevel = "2019-09")
+    public void testStagefright_cve_2019_10534() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10534);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2019-09")
+    public void testStagefright_cve_2019_10533() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10533);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "2019-09")
+    public void testStagefright_cve_2019_10541() throws Exception {
+        doStagefrightTest(R.raw.cve_2019_10541);
+    }
+
+    @Test
     @SecurityTest(minPatchLevel = "2018-02")
     public void testStagefright_cve_2017_13233() throws Exception {
         doStagefrightTestRawBlob(R.raw.cve_2017_13233_hevc, "video/hevc", 640,
                 480);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2019-07")
     public void testStagefright_cve_2019_2106() throws Exception {
         int[] frameSizes = {943, 3153};
@@ -1108,87 +1274,105 @@
                 240, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-06")
     public void testStagefright_cve_2017_0637() throws Exception {
         doStagefrightTest(R.raw.cve_2017_0637, 2 * 72000);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-09")
     public void testStagefright_cve_2018_11287() throws Exception {
         doStagefrightTest(R.raw.cve_2018_11287, 180000);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2019-07")
     public void testStagefright_cve_2019_2327() throws Exception {
         doStagefrightTest(R.raw.cve_2019_2327);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2019-07")
     public void testStagefright_cve_2019_2322() throws Exception {
         doStagefrightTest(R.raw.cve_2019_2322);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2019-07")
     public void testStagefright_cve_2019_2334() throws Exception {
         doStagefrightTest(R.raw.cve_2019_2334);
     }
 
+    @Test
+    @SecurityTest(minPatchLevel = "2018-01")
     public void testStagefright_cve_2017_13204() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.cve_2017_13204_framelen);
         doStagefrightTestRawBlob(R.raw.cve_2017_13204_avc, "video/avc", 16, 16, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-03")
     public void testStagefright_cve_2017_17773() throws Exception {
         doStagefrightTest(R.raw.cve_2017_17773);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testStagefright_cve_2017_18074() throws Exception {
         doStagefrightTest(R.raw.cve_2017_18074);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-06")
     public void testStagefright_cve_2018_5894() throws Exception {
         doStagefrightTest(R.raw.cve_2018_5894);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testStagefright_cve_2018_5874() throws Exception {
         doStagefrightTest(R.raw.cve_2018_5874);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testStagefright_cve_2018_5875() throws Exception {
         doStagefrightTest(R.raw.cve_2018_5875);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testStagefright_cve_2018_5876() throws Exception {
         doStagefrightTest(R.raw.cve_2018_5876);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testStagefright_cve_2018_5882() throws Exception {
         doStagefrightTest(R.raw.cve_2018_5882);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-12")
     public void testBug_65186291() throws Exception {
         int[] frameSizes = getFrameSizes(R.raw.bug_65186291_framelen);
         doStagefrightTestRawBlob(R.raw.bug_65186291_hevc, "video/hevc", 1920, 1080, frameSizes);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testBug_67737022() throws Exception {
         doStagefrightTest(R.raw.bug_67737022);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testStagefright_bug_37093318() throws Exception {
         doStagefrightTest(R.raw.bug_37093318, (4 * 60 * 1000));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-05")
     public void testStagefright_bug_73172046() throws Exception {
         doStagefrightTest(R.raw.bug_73172046);
@@ -1201,46 +1385,55 @@
         }
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-03")
     public void testStagefright_cve_2016_0824() throws Exception {
         doStagefrightTest(R.raw.cve_2016_0824);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-03")
     public void testStagefright_cve_2016_0815() throws Exception {
         doStagefrightTest(R.raw.cve_2016_0815);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-05")
     public void testStagefright_cve_2016_2454() throws Exception {
         doStagefrightTest(R.raw.cve_2016_2454);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-12")
     public void testStagefright_cve_2016_6765() throws Exception {
         doStagefrightTest(R.raw.cve_2016_6765, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-07")
     public void testStagefright_cve_2016_2508() throws Exception {
         doStagefrightTest(R.raw.cve_2016_2508, new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-11")
     public void testStagefright_cve_2016_6699() throws Exception {
         doStagefrightTest(R.raw.cve_2016_6699);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-06")
     public void testStagefright_cve_2017_18155() throws Exception {
         doStagefrightTest(R.raw.cve_2017_18155);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-07")
     public void testStagefright_cve_2018_9423() throws Exception {
         doStagefrightTest(R.raw.cve_2018_9423);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2016-09")
     public void testStagefright_cve_2016_3879() throws Exception {
         doStagefrightTest(R.raw.cve_2016_3879, new CrashUtils.Config().checkMinAddress(false));
@@ -1271,10 +1464,10 @@
         String rname = resources.getResourceEntryName(rid);
         String url = server.getAssetUrl("raw/" + rname);
         verifyServer(rid, url);
+        policy.setCleartextTrafficPermitted(false);
         doStagefrightTestMediaPlayer(url, config);
         doStagefrightTestMediaCodec(url, config);
         doStagefrightTestMediaMetadataRetriever(url, config);
-        policy.setCleartextTrafficPermitted(false);
         server.shutdown();
     }
 
@@ -1438,15 +1631,15 @@
                 SystemClock.sleep(1000);
             }
             if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
-                JSONArray crashes = getCrashReport(getName(), 5000);
+                JSONArray crashes = getCrashReport(name.getMethodName(), 5000);
                 if (crashes == null) {
-                    Log.e(TAG, "Crash results not found for test " + getName());
+                    Log.e(TAG, "Crash results not found for test " + name.getMethodName());
                     return what;
                 } else if (CrashUtils.securityCrashDetected(crashes, config)) {
                     return what;
                 } else {
                     Log.i(TAG, "Crash ignored due to no security crash found for test " +
-                        getName());
+                        name.getMethodName());
                     // 0 is the code for no error.
                     return 0;
                 }
@@ -1578,6 +1771,7 @@
     /*
      * b/135207745
      */
+    @Test
     @SecurityTest(minPatchLevel = "2019-08")
     public void testStagefright_cve_2019_2129() throws Exception {
         final int rid = R.raw.cve_2019_2129;
@@ -1924,54 +2118,99 @@
         thr.join();
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testBug36215950() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_36215950, "video/hevc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug36816007() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_36816007, "video/avc", 320, 240,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-05")
     public void testBug36895511() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_36895511, "video/hevc", 320, 240,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-11")
     public void testBug64836894() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_64836894, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testCve_2017_0687() throws Exception {
         doStagefrightTestRawBlob(R.raw.cve_2017_0687, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-07")
     public void testCve_2017_0696() throws Exception {
         doStagefrightTestRawBlob(R.raw.cve_2017_0696, "video/avc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-01")
     public void testBug_37930177() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_37930177_hevc, "video/hevc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2017-08")
     public void testBug_37712181() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_37712181_hevc, "video/hevc", 320, 240);
     }
 
+    @Test
     @SecurityTest(minPatchLevel = "2018-04")
     public void testBug_70897394() throws Exception {
         doStagefrightTestRawBlob(R.raw.bug_70897394_avc, "video/avc", 320, 240,
                 new CrashUtils.Config().checkMinAddress(false));
     }
 
+    @Test
+    @SecurityTest(minPatchLevel = "Unknown")
+    public void testBug_123700383() throws Exception {
+        assertExtractorDoesNotHang(R.raw.bug_123700383);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "Unknown")
+    public void testBug_127310810() throws Exception {
+        assertExtractorDoesNotHang(R.raw.bug_127310810);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "Unknown")
+    public void testBug_127312550() throws Exception {
+        assertExtractorDoesNotHang(R.raw.bug_127312550);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "Unknown")
+    public void testBug_127313223() throws Exception {
+        assertExtractorDoesNotHang(R.raw.bug_127313223);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "Unknown")
+    public void testBug_127313537() throws Exception {
+        assertExtractorDoesNotHang(R.raw.bug_127313537);
+    }
+
+    @Test
+    @SecurityTest(minPatchLevel = "Unknown")
+    public void testBug_127313764() throws Exception {
+        assertExtractorDoesNotHang(R.raw.bug_127313764);
+    }
+
     private int[] getFrameSizes(int rid) throws IOException {
         final Context context = getInstrumentation().getContext();
         final Resources resources =  context.getResources();
@@ -2131,7 +2370,8 @@
 
     private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
             int frameSizes[]) throws Exception {
-        doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, frameSizes, null);
+        // check crash address by default
+        doStagefrightTestRawBlob(rid, mime, initWidth, initHeight, frameSizes, new CrashUtils.Config());
     }
 
     private void doStagefrightTestRawBlob(int rid, String mime, int initWidth, int initHeight,
@@ -2324,7 +2564,7 @@
     }
 
     private void doStagefrightTestExtractorSeek(final int rid, final long offset) throws Exception {
-        doStagefrightTestExtractorSeek(rid, offset, null);
+        doStagefrightTestExtractorSeek(rid, offset, new CrashUtils.Config()); // check crash address by default
     }
 
     private void doStagefrightTestExtractorSeek(final int rid, final long offset,
@@ -2391,4 +2631,39 @@
         thr.stopLooper();
         thr.join();
     }
+
+    protected void assertExtractorDoesNotHang(int rid) throws Exception {
+        // The media extractor has a watchdog, currently set to 10 seconds.
+        final long timeoutMs = 12 * 1000;
+
+        Thread thread = new Thread(() -> {
+            MediaExtractor ex = new MediaExtractor();
+            AssetFileDescriptor fd =
+                    getInstrumentation().getContext().getResources().openRawResourceFd(rid);
+            try {
+                ex.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+            } catch (IOException e) {
+                // It is OK for the call to fail, we're only making sure it doesn't hang.
+            } finally {
+                closeQuietly(fd);
+                ex.release();
+            }
+        });
+        thread.start();
+
+        thread.join(timeoutMs);
+        boolean hung = thread.isAlive();
+        if (hung) {
+            // We don't have much to do at this point. Attempt to un-hang the thread, the media
+            // extractor process is likely still spinning. At least we found a bug...
+            // TODO: reboot the media extractor process.
+            thread.interrupt();
+        }
+
+        assertFalse(hung);
+    }
+
+    private Instrumentation getInstrumentation() {
+        return mInstrumentation;
+    }
 }
diff --git a/tests/tests/telecom/AndroidTest.xml b/tests/tests/telecom/AndroidTest.xml
index 07778a3..741a897 100644
--- a/tests/tests/telecom/AndroidTest.xml
+++ b/tests/tests/telecom/AndroidTest.xml
@@ -19,6 +19,7 @@
     <option name="config-descriptor:metadata" key="parameter" value="not_instant_app" />
     <option name="config-descriptor:metadata" key="parameter" value="not_multi_abi" />
     <option name="config-descriptor:metadata" key="parameter" value="secondary_user" />
+    <option name="hidden-api-checks" value="false" />
     <target_preparer class="com.android.compatibility.common.tradefed.targetprep.TokenRequirement">
         <option name="token" value="sim-card" />
     </target_preparer>
diff --git a/tests/tests/telecom/Api29InCallServiceTestApp/aidl/android/telecom/cts/api29incallservice/ICtsApi29InCallServiceControl.aidl b/tests/tests/telecom/Api29InCallServiceTestApp/aidl/android/telecom/cts/api29incallservice/ICtsApi29InCallServiceControl.aidl
index 1c96bdf..7dd22cd 100644
--- a/tests/tests/telecom/Api29InCallServiceTestApp/aidl/android/telecom/cts/api29incallservice/ICtsApi29InCallServiceControl.aidl
+++ b/tests/tests/telecom/Api29InCallServiceTestApp/aidl/android/telecom/cts/api29incallservice/ICtsApi29InCallServiceControl.aidl
@@ -22,4 +22,12 @@
     int getLocalCallCount();
 
     int getHistoricalCallCount();
+
+    boolean hasReceivedBindRequest();
+
+    void setShouldReturnNullBinding(boolean shouldReturnNullBinding);
+
+    boolean waitForBindRequest();
+
+    void kill();
 }
diff --git a/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallService.java b/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallService.java
index a1aaf35..a86ccc7 100644
--- a/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallService.java
+++ b/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallService.java
@@ -16,12 +16,19 @@
 
 package android.telecom.cts.api29incallservice;
 
+import android.content.Intent;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
 import android.telecom.Call;
 import android.telecom.cts.MockInCallService;
 import android.util.Log;
 
 import java.util.HashSet;
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
 
 public class CtsApi29InCallService extends MockInCallService {
 
@@ -31,22 +38,46 @@
 
     static Set<Call> sCalls = new HashSet<>();
     static int sHistoricalCallCount = 0;
+    static boolean sShouldReturnNullBinding = false;
+    static CompletableFuture<Boolean> sBindRequestFuture = new CompletableFuture<>();
 
     @Override
     public void onCallAdded(Call call) {
-        Log.i(TAG, "onCallAdded");
         super.onCallAdded(call);
         if (!sCalls.contains(call)) {
             sHistoricalCallCount++;
         }
         sCalls.add(call);
+        Log.i(TAG, "onCallAdded, size=" + sCalls.size());
     }
 
     @Override
     public void onCallRemoved(Call call) {
-        Log.i(TAG, "onCallRemoved");
         super.onCallRemoved(call);
         sCalls.remove(call);
+        Log.i(TAG, "onCallRemoved, size=" + sCalls.size());
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        Log.i(TAG, "onBind future=" + sBindRequestFuture);
+        sBindRequestFuture.complete(true);
+        if (!sShouldReturnNullBinding) {
+            return super.onBind(intent);
+        }
+        return null;
+    }
+
+    public static boolean waitForBindRequest() {
+        try {
+            if (isServiceBound()) return true;
+            return sBindRequestFuture.get(TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (TimeoutException te) {
+            Log.e(TAG, "Waited too long for bind request. future=" + sBindRequestFuture);
+            return false;
+        } catch (Exception e) {
+            return false;
+        }
     }
 
     public static int getLocalCallCount() {
@@ -58,5 +89,7 @@
     static void reset() {
         sCalls.clear();
         sHistoricalCallCount = 0;
+        sShouldReturnNullBinding = false;
+        sBindRequestFuture = new CompletableFuture<>();
     }
 }
diff --git a/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallServiceControl.java b/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallServiceControl.java
index 27876cd..4b8d1e0 100644
--- a/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallServiceControl.java
+++ b/tests/tests/telecom/Api29InCallServiceTestApp/src/android/telecom/cts/api29incallservice/CtsApi29InCallServiceControl.java
@@ -19,6 +19,7 @@
 import android.app.Service;
 import android.content.Intent;
 import android.os.IBinder;
+import android.os.Process;
 import android.telecom.Call;
 import android.util.Log;
 
@@ -46,6 +47,26 @@
         public int getHistoricalCallCount() {
             return CtsApi29InCallService.sHistoricalCallCount;
         }
+
+        @Override
+        public boolean hasReceivedBindRequest() {
+            return CtsApi29InCallService.sBindRequestFuture.getNow(false);
+        }
+
+        @Override
+        public void setShouldReturnNullBinding(boolean shouldReturnNullBinding) {
+            CtsApi29InCallService.sShouldReturnNullBinding = shouldReturnNullBinding;
+        }
+
+        @Override
+        public boolean waitForBindRequest() {
+            return CtsApi29InCallService.waitForBindRequest();
+        }
+
+        @Override
+        public void kill() {
+            Process.killProcess(Process.myPid());
+        }
     };
 
     @Override
diff --git a/tests/tests/telecom/src/android/telecom/cts/Api29InCallUtils.java b/tests/tests/telecom/src/android/telecom/cts/Api29InCallUtils.java
new file mode 100644
index 0000000..3ce7c33
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/Api29InCallUtils.java
@@ -0,0 +1,60 @@
+package android.telecom.cts;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.IBinder;
+import android.telecom.cts.api29incallservice.CtsApi29InCallServiceControl;
+import android.telecom.cts.api29incallservice.ICtsApi29InCallServiceControl;
+import android.util.Log;
+import android.util.Pair;
+
+import junit.framework.TestCase;
+
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public final class Api29InCallUtils {
+    private static final String LOG_TAG = Api29InCallUtils.class.getSimpleName();
+
+    public static Pair<ServiceConnection, ICtsApi29InCallServiceControl> setupControl(
+            Context context) throws Exception {
+
+        Intent bindIntent = new Intent(CtsApi29InCallServiceControl.CONTROL_INTERFACE_ACTION);
+        ComponentName controlComponentName =
+                ComponentName.createRelative(
+                        CtsApi29InCallServiceControl.class.getPackage().getName(),
+                        CtsApi29InCallServiceControl.class.getName());
+
+        bindIntent.setComponent(controlComponentName);
+        LinkedBlockingQueue<ICtsApi29InCallServiceControl> result = new LinkedBlockingQueue<>(1);
+
+        ServiceConnection serviceConnection = new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                Log.i(LOG_TAG, "Service Connected: " + name);
+                result.offer(ICtsApi29InCallServiceControl.Stub.asInterface(service));
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+            }
+        };
+
+        boolean success = context.bindService(bindIntent,
+                serviceConnection, Context.BIND_AUTO_CREATE);
+
+        if (!success) {
+            TestCase.fail("Failed to get control interface -- bind error");
+        }
+        return Pair.create(serviceConnection,
+                result.poll(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+    }
+
+    public static void tearDownControl(Context context, ServiceConnection serviceConnection) {
+        context.unbindService(serviceConnection);
+    }
+
+    private Api29InCallUtils() {}
+}
diff --git a/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java b/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java
index 313651e..c5be595 100644
--- a/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/BackgroundCallAudioTest.java
@@ -3,13 +3,9 @@
 import static android.telecom.cts.TestUtils.TEST_PHONE_ACCOUNT_HANDLE;
 import static android.telecom.cts.TestUtils.waitOnAllHandlers;
 
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
 import android.content.ServiceConnection;
 import android.media.AudioManager;
 import android.os.Bundle;
-import android.os.IBinder;
 import android.provider.CallLog;
 import android.telecom.Call;
 import android.telecom.Call.Details;
@@ -19,15 +15,12 @@
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
 import android.telecom.cts.MockCallScreeningService.CallScreeningServiceCallbacks;
-import android.telecom.cts.api29incallservice.CtsApi29InCallService;
-import android.telecom.cts.api29incallservice.CtsApi29InCallServiceControl;
 import android.telecom.cts.api29incallservice.ICtsApi29InCallServiceControl;
 import android.text.TextUtils;
-import android.util.Log;
+import android.util.Pair;
 
 import androidx.test.InstrumentationRegistry;
 
-import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 public class BackgroundCallAudioTest extends BaseTelecomTestWithMockServices {
@@ -92,7 +85,7 @@
 
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         verifySimulateRingAndUserPickup(call, connection);
@@ -118,7 +111,7 @@
 
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         call.disconnect();
@@ -146,7 +139,7 @@
 
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         verifySimulateRingAndUserMissed(call, connection);
@@ -172,14 +165,17 @@
 
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         call.exitBackgroundAudioProcessing(true);
         assertCallState(call, Call.STATE_SIMULATED_RINGING);
 
         waitOnAllHandlers(getInstrumentation());
-        assertEquals(AudioManager.MODE_RINGTONE, audioManager.getMode());
+        // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing.
+        if (doesAudioManagerSupportCallScreening) {
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
+        }
         assertConnectionState(connection, Connection.STATE_ACTIVE);
 
         connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
@@ -208,13 +204,16 @@
 
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         call.exitBackgroundAudioProcessing(true);
         assertCallState(call, Call.STATE_SIMULATED_RINGING);
         waitOnAllHandlers(getInstrumentation());
-        assertEquals(AudioManager.MODE_RINGTONE, audioManager.getMode());
+        // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing.
+        if (doesAudioManagerSupportCallScreening) {
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
+        }
         assertConnectionState(connection, Connection.STATE_ACTIVE);
 
         placeAndVerifyEmergencyCall(false /*supportsHold*/);
@@ -249,7 +248,7 @@
 
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         verifySimulateRingAndUserPickup(call, connection);
@@ -284,7 +283,7 @@
         waitOnAllHandlers(getInstrumentation());
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
         assertConnectionState(connection, Connection.STATE_ACTIVE);
 
@@ -306,7 +305,7 @@
         waitOnAllHandlers(getInstrumentation());
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         verifySimulateRingAndUserMissed(call, connection);
@@ -327,7 +326,7 @@
         waitOnAllHandlers(getInstrumentation());
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         connection.setDisconnected(new DisconnectCause(DisconnectCause.REMOTE));
@@ -352,7 +351,7 @@
         waitOnAllHandlers(getInstrumentation());
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         placeAndVerifyEmergencyCall(false /*supportsHold*/);
@@ -386,13 +385,13 @@
         waitOnAllHandlers(getInstrumentation());
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         call.exitBackgroundAudioProcessing(false);
         assertCallState(call, Call.STATE_ACTIVE);
         waitOnAllHandlers(getInstrumentation());
-        assertEquals(AudioManager.MODE_IN_CALL, audioManager.getMode());
+        assertAudioMode(audioManager, AudioManager.MODE_IN_CALL);
     }
 
     public void testManualAudioCallScreenReject() {
@@ -413,7 +412,7 @@
         waitOnAllHandlers(getInstrumentation());
         AudioManager audioManager = mContext.getSystemService(AudioManager.class);
         if (doesAudioManagerSupportCallScreening) {
-            assertEquals(MODE_CALL_SCREENING, audioManager.getMode());
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
         }
 
         call.disconnect();
@@ -552,13 +551,16 @@
         call.exitBackgroundAudioProcessing(true);
         assertCallState(call, Call.STATE_SIMULATED_RINGING);
         waitOnAllHandlers(getInstrumentation());
-        assertEquals(AudioManager.MODE_RINGTONE, audioManager.getMode());
+        // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing.
+        if (doesAudioManagerSupportCallScreening) {
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
+        }
         assertConnectionState(connection, Connection.STATE_ACTIVE);
 
         call.answer(VideoProfile.STATE_AUDIO_ONLY);
         assertCallState(call, Call.STATE_ACTIVE);
         waitOnAllHandlers(getInstrumentation());
-        assertEquals(AudioManager.MODE_IN_CALL, audioManager.getMode());
+        assertAudioMode(audioManager, AudioManager.MODE_IN_CALL);
         assertConnectionState(connection, Connection.STATE_ACTIVE);
     }
 
@@ -568,8 +570,12 @@
         call.exitBackgroundAudioProcessing(true);
         assertCallState(call, Call.STATE_SIMULATED_RINGING);
         waitOnAllHandlers(getInstrumentation());
-        assertEquals(AudioManager.MODE_RINGTONE, audioManager.getMode());
+        // We expect the audio mode to stay in CALL_SCREENING when going into simulated ringing.
+        if (doesAudioManagerSupportCallScreening) {
+            assertAudioMode(audioManager, MODE_CALL_SCREENING);
+        }
         assertConnectionState(connection, Connection.STATE_ACTIVE);
+        assertTrue(mTelecomManager.isRinging());
 
         call.disconnect();
         assertCallState(call, Call.STATE_DISCONNECTED);
@@ -602,45 +608,14 @@
     }
 
     private ICtsApi29InCallServiceControl setUpControl() throws Exception {
-        TestUtils.executeShellCommand(getInstrumentation(),
-                "telecom add-or-remove-call-companion-app " + CtsApi29InCallService.PACKAGE_NAME
-                        + " 1");
-
-        Intent bindIntent = new Intent(CtsApi29InCallServiceControl.CONTROL_INTERFACE_ACTION);
-        ComponentName controlComponentName =
-                ComponentName.createRelative(
-                        CtsApi29InCallServiceControl.class.getPackage().getName(),
-                        CtsApi29InCallServiceControl.class.getName());
-
-        bindIntent.setComponent(controlComponentName);
-        LinkedBlockingQueue<ICtsApi29InCallServiceControl> result = new LinkedBlockingQueue<>(1);
-
-        mApiCompatControlServiceConnection = new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                Log.i(LOG_TAG, "Service Connected: " + name);
-                result.offer(ICtsApi29InCallServiceControl.Stub.asInterface(service));
-            }
-
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-            }
-        };
-
-        boolean success = mContext.bindService(bindIntent,
-                mApiCompatControlServiceConnection, Context.BIND_AUTO_CREATE);
-
-        if (!success) {
-            fail("Failed to get control interface -- bind error");
-        }
-        return result.poll(TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        Pair<ServiceConnection, ICtsApi29InCallServiceControl> setupResult =
+                Api29InCallUtils.setupControl(mContext);
+        mApiCompatControlServiceConnection = setupResult.first;
+        return setupResult.second;
     }
 
     private void tearDownControl() throws Exception {
-        mContext.unbindService(mApiCompatControlServiceConnection);
-
-        TestUtils.executeShellCommand(getInstrumentation(),
-                "telecom add-or-remove-call-companion-app " + CtsApi29InCallService.PACKAGE_NAME
-                        + " 0");
+        Api29InCallUtils.tearDownControl(mContext,
+                mApiCompatControlServiceConnection);
     }
 }
\ No newline at end of file
diff --git a/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java b/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java
index 465782a..47b1462 100644
--- a/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java
+++ b/tests/tests/telecom/src/android/telecom/cts/EmergencyCallTests.java
@@ -17,6 +17,7 @@
 package android.telecom.cts;
 
 import android.net.Uri;
+import android.os.Bundle;
 import android.provider.CallLog;
 import android.telecom.Call;
 import android.telecom.Connection;
@@ -102,4 +103,42 @@
         // Notify as missed instead of rejected, since the user did not explicitly reject.
         verifyCallLogging(normalCallNumber, CallLog.Calls.MISSED_TYPE);
     }
+
+    /**
+     * While on an outgoing call, receive an incoming ringing call and then place an emergency call.
+     * The other two calls should stay active while the ringing call should be rejected and logged
+     * as a new missed call.
+     */
+    public void testActiveCallAndIncomingRingingCallAndPlaceEmergencyCall() throws Exception {
+        if (!mShouldTestTelecom) return;
+
+        Uri normalOutgoingCallNumber = createRandomTestNumber();
+        Bundle extras = new Bundle();
+        extras.putParcelable(TestUtils.EXTRA_PHONE_NUMBER, normalOutgoingCallNumber);
+        placeAndVerifyCall(extras);
+        Connection outgoingConnection = verifyConnectionForOutgoingCall();
+        Call outgoingCall = getInCallService().getLastCall();
+        outgoingConnection.setActive();
+        assertCallState(outgoingCall, Call.STATE_ACTIVE);
+
+        Uri normalIncomingCallNumber = createRandomTestNumber();
+        addAndVerifyNewIncomingCall(normalIncomingCallNumber, null);
+        Connection incomingConnection = verifyConnectionForIncomingCall();
+        Call incomingCall = getInCallService().getLastCall();
+        assertCallState(incomingCall, Call.STATE_RINGING);
+
+        // Do not support holding incoming call for emergency call.
+        Connection eConnection = placeAndVerifyEmergencyCall(false /*supportsHold*/);
+        Call eCall = getInCallService().getLastCall();
+        assertCallState(eCall, Call.STATE_DIALING);
+
+        assertConnectionState(incomingConnection, Connection.STATE_DISCONNECTED);
+        assertCallState(incomingCall, Call.STATE_DISCONNECTED);
+
+        eConnection.setActive();
+        assertCallState(eCall, Call.STATE_ACTIVE);
+
+        // Notify as missed instead of rejected, since the user did not explicitly reject.
+        verifyCallLogging(normalIncomingCallNumber, CallLog.Calls.MISSED_TYPE);
+    }
 }
diff --git a/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java b/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java
index 4c579ed..627ea62 100644
--- a/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java
+++ b/tests/tests/telecom/src/android/telecom/cts/IncomingCallTest.java
@@ -16,14 +16,19 @@
 
 package android.telecom.cts;
 
+import static android.media.AudioAttributes.USAGE_NOTIFICATION_RINGTONE;
 import static android.telecom.cts.TestUtils.COMPONENT;
 import static android.telecom.cts.TestUtils.PACKAGE;
+import static android.telecom.cts.TestUtils.WAIT_FOR_STATE_CHANGE_TIMEOUT_MS;
 import static android.telephony.TelephonyManager.CALL_STATE_RINGING;
 
 import android.content.ComponentName;
+import android.media.AudioManager;
+import android.media.AudioPlaybackConfiguration;
 import android.net.Uri;
 import android.os.Bundle;
-import android.provider.Telephony;
+import android.os.Handler;
+import android.os.Looper;
 import android.telecom.Call;
 import android.telecom.Connection;
 import android.telecom.ConnectionRequest;
@@ -31,9 +36,12 @@
 import android.telecom.TelecomManager;
 import android.telephony.PhoneStateListener;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -110,6 +118,45 @@
     }
 
     /**
+     * This test verifies that when a default dialer is incapable of playing a ringtone that the
+     * platform still plays a ringtone.
+     * <p>
+     * Given that the default {@link MockInCallService} defined in the CTS tests does not declare
+     * {@link TelecomManager#METADATA_IN_CALL_SERVICE_RINGING}, we expect the Telecom framework to
+     * play a ringtone for an incoming call.
+     * @throws Exception
+     */
+    public void testRingOnIncomingCall() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        LinkedBlockingQueue<Boolean> queue = new LinkedBlockingQueue(1);
+        setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        AudioManager audioManager = mContext.getSystemService(AudioManager.class);
+        AudioManager.AudioPlaybackCallback callback = new AudioManager.AudioPlaybackCallback() {
+            @Override
+            public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
+                super.onPlaybackConfigChanged(configs);
+                boolean isPlayingRingtone = configs.stream()
+                        .anyMatch(c -> c.getAudioAttributes().getUsage()
+                                == USAGE_NOTIFICATION_RINGTONE);
+                if (isPlayingRingtone && queue.isEmpty()) {
+                    queue.add(isPlayingRingtone);
+                }
+            }
+        };
+        audioManager.registerAudioPlaybackCallback(callback, new Handler(Looper.getMainLooper()));
+        Uri testNumber = createTestNumber();
+        addAndVerifyNewIncomingCall(testNumber, null);
+        verifyConnectionForIncomingCall();
+        verifyPhoneStateListenerCallbacksForCall(CALL_STATE_RINGING,
+                testNumber.getSchemeSpecificPart());
+        Boolean ringing = queue.poll(WAIT_FOR_STATE_CHANGE_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        assertTrue("Telecom should have played a ringtone.", ringing);
+        audioManager.unregisterAudioPlaybackCallback(callback);
+    }
+
+    /**
      * Tests to be sure that new incoming calls can only be added using a valid PhoneAccountHandle
      * (b/26864502). If a PhoneAccount has not been registered for the PhoneAccountHandle, then
      * a SecurityException will be thrown.
diff --git a/tests/tests/telecom/src/android/telecom/cts/NonUiInCallServiceTest.java b/tests/tests/telecom/src/android/telecom/cts/NonUiInCallServiceTest.java
new file mode 100644
index 0000000..3496fdb
--- /dev/null
+++ b/tests/tests/telecom/src/android/telecom/cts/NonUiInCallServiceTest.java
@@ -0,0 +1,129 @@
+package android.telecom.cts;
+
+import static android.telecom.cts.TestUtils.TEST_PHONE_ACCOUNT_HANDLE;
+import static android.telecom.cts.TestUtils.waitOnAllHandlers;
+
+import android.content.ComponentName;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.DeadObjectException;
+import android.telecom.cts.api29incallservice.CtsApi29InCallService;
+import android.telecom.cts.api29incallservice.ICtsApi29InCallServiceControl;
+import android.util.Pair;
+
+import androidx.test.InstrumentationRegistry;
+
+public class NonUiInCallServiceTest extends BaseTelecomTestWithMockServices {
+    private static final String LOG_TAG = NonUiInCallServiceTest.class.getSimpleName();
+
+    private ServiceConnection mServiceConnection;
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        if (mShouldTestTelecom) {
+            setupConnectionService(null, FLAG_REGISTER | FLAG_ENABLE);
+        }
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        if (mShouldTestTelecom) {
+            mTelecomManager.unregisterPhoneAccount(TEST_PHONE_ACCOUNT_HANDLE);
+            CtsConnectionService.tearDown();
+        }
+        super.tearDown();
+        waitOnAllHandlers(getInstrumentation());
+    }
+
+    public void testMidCallComponentEnablement() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity(
+                        "android.permission.CONTROL_INCALL_EXPERIENCE",
+                        "android.permission.CHANGE_COMPONENT_ENABLED_STATE");
+        try {
+            mContext.getPackageManager().setComponentEnabledSetting(
+                    ComponentName.createRelative(CtsApi29InCallService.PACKAGE_NAME,
+                            "." + CtsApi29InCallService.class.getSimpleName()),
+                    PackageManager.COMPONENT_ENABLED_STATE_DISABLED, 0);
+            ICtsApi29InCallServiceControl controlInterface = setUpControl();
+
+            addAndVerifyNewIncomingCall(createTestNumber(), new Bundle());
+            waitOnAllHandlers(getInstrumentation());
+            assertFalse("Non-UI incall incorrectly bound to despite being disabled",
+                    controlInterface.hasReceivedBindRequest());
+
+            mContext.getPackageManager().setComponentEnabledSetting(
+                    ComponentName.createRelative(CtsApi29InCallService.PACKAGE_NAME,
+                            "." + CtsApi29InCallService.class.getSimpleName()),
+                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                    PackageManager.DONT_KILL_APP);
+
+            boolean hasBound = controlInterface.waitForBindRequest();
+            assertTrue("InCall was not bound to", hasBound);
+            waitOnAllHandlers(getInstrumentation());
+
+            assertEquals("Call was not sent to incall", 1, controlInterface.getLocalCallCount());
+
+            try {
+                controlInterface.kill();
+            } catch (DeadObjectException e) {
+                //expected
+            }
+            tearDownControl();
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .dropShellPermissionIdentity();
+        }
+    }
+
+    public void testNullBinding() throws Exception {
+        if (!mShouldTestTelecom) {
+            return;
+        }
+        InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .adoptShellPermissionIdentity(
+                        "android.permission.CONTROL_INCALL_EXPERIENCE",
+                        "android.permission.CHANGE_COMPONENT_ENABLED_STATE");
+        try {
+            mContext.getPackageManager().setComponentEnabledSetting(
+                    ComponentName.createRelative(CtsApi29InCallService.PACKAGE_NAME,
+                            "." + CtsApi29InCallService.class.getSimpleName()),
+                    PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
+            ICtsApi29InCallServiceControl controlInterface = setUpControl();
+            controlInterface.setShouldReturnNullBinding(true);
+
+            addAndVerifyNewIncomingCall(createTestNumber(), new Bundle());
+            assertTrue("Non-UI incall incorrectly not bound to despite being enabled",
+                    controlInterface.waitForBindRequest());
+
+            assertEquals("Call was sent to incall despite null binding",
+                    0, controlInterface.getLocalCallCount());
+
+            try {
+                controlInterface.kill();
+            } catch (DeadObjectException e) {
+                //expected
+            }
+            tearDownControl();
+        } finally {
+            InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                    .dropShellPermissionIdentity();
+        }
+    }
+    private ICtsApi29InCallServiceControl setUpControl() throws Exception {
+        Pair<ServiceConnection, ICtsApi29InCallServiceControl> setupResult =
+                Api29InCallUtils.setupControl(mContext);
+        mServiceConnection = setupResult.first;
+        return setupResult.second;
+    }
+
+    private void tearDownControl() throws Exception {
+        Api29InCallUtils.tearDownControl(mContext,
+                mServiceConnection);
+    }
+}
\ No newline at end of file
diff --git a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
index 6af49f3..a360bd9 100644
--- a/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
+++ b/tests/tests/telecom/src/android/telecom/cts/TestUtils.java
@@ -119,7 +119,8 @@
             .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER |
                     PhoneAccount.CAPABILITY_VIDEO_CALLING |
                     PhoneAccount.CAPABILITY_RTT |
-                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER)
+                    PhoneAccount.CAPABILITY_CONNECTION_MANAGER |
+                    PhoneAccount.CAPABILITY_PLACE_EMERGENCY_CALLS)
             .setHighlightColor(Color.RED)
             .setShortDescription(ACCOUNT_LABEL)
             .addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
diff --git a/tests/tests/telephony/current/AndroidManifest.xml b/tests/tests/telephony/current/AndroidManifest.xml
index 74b9554..b29b897 100644
--- a/tests/tests/telephony/current/AndroidManifest.xml
+++ b/tests/tests/telephony/current/AndroidManifest.xml
@@ -34,6 +34,7 @@
     <uses-permission android:name="android.permission.BLUETOOTH" />
     <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
     <uses-permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"/>
+    <uses-permission android:name="android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS" />
 
     <permission android:name="android.telephony.embms.cts.permission.TEST_BROADCAST"
                 android:protectionLevel="signature"/>
diff --git a/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
index 8a186c9..e74c315 100644
--- a/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
+++ b/tests/tests/telephony/current/EmbmsMiddlewareTestApp/src/android/telephony/cts/embmstestapp/CtsDownloadService.java
@@ -258,7 +258,7 @@
         }
 
         @Override
-        public int addServiceAnnouncementFile(int subscriptionId, byte[] announcementFile) {
+        public int addServiceAnnouncement(int subscriptionId, byte[] announcementFile) {
             Bundle b = new Bundle();
             b.putString(METHOD_NAME, METHOD_ADD_SERVICE_ANNOUNCEMENT);
             b.putInt(ARGUMENT_SUBSCRIPTION_ID, subscriptionId);
diff --git a/tests/tests/telephony/current/LocationAccessingApp/AndroidManifest.xml b/tests/tests/telephony/current/LocationAccessingApp/AndroidManifest.xml
index e5c9aac..332d369 100644
--- a/tests/tests/telephony/current/LocationAccessingApp/AndroidManifest.xml
+++ b/tests/tests/telephony/current/LocationAccessingApp/AndroidManifest.xml
@@ -19,6 +19,7 @@
 
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
+  <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
   <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
 
   <application android:label="LocationAccessingApp">
diff --git a/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java b/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java
index 1d234d7..9fa1994 100644
--- a/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java
+++ b/tests/tests/telephony/current/permissions/src/android/telephony/cts/telephonypermission/TelephonyManagerReadPhoneStatePermissionTest.java
@@ -19,8 +19,10 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.fail;
 
+import android.app.UiAutomation;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.platform.test.annotations.AppModeFull;
 import android.telephony.TelephonyManager;
 
 import androidx.test.InstrumentationRegistry;
@@ -34,6 +36,7 @@
  * Test TelephonyManager APIs with READ_PHONE_STATE Permission.
  */
 @RunWith(AndroidJUnit4.class)
+@AppModeFull(reason = "Cannot grant the runtime permission in instant app mode")
 public class TelephonyManagerReadPhoneStatePermissionTest {
 
     private boolean mHasTelephony;
@@ -48,6 +51,12 @@
         assertNotNull(mTelephonyManager);
     }
 
+    public static void grantUserReadPhoneStatePermission() {
+        UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+        uiAutomation.grantRuntimePermission(getContext().getPackageName(),
+                android.Manifest.permission.READ_PHONE_STATE);
+    }
+
     /**
      * Verify that TelephonyManager APIs requiring READ_PHONE_STATE Permission must work.
      * <p>
@@ -64,6 +73,8 @@
             return;
         }
 
+        grantUserReadPhoneStatePermission();
+
         try {
             mTelephonyManager.getNetworkType();
         } catch (SecurityException e) {
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
index 2ed4a07..48a6573 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/CellInfoTest.java
@@ -82,8 +82,8 @@
     private static final int MAX_RSRQ = -3;
     private static final int MIN_RSRQ = -35;
     // Maximum and minimum possible RSSNR values.
-    private static final int MAX_RSSNR = 50;
-    private static final int MIN_RSSNR = 0;
+    private static final int MAX_RSSNR = 30;
+    private static final int MIN_RSSNR = -20;
     // Maximum and minimum possible CQI values.
     private static final int MAX_CQI = 30;
     private static final int MIN_CQI = 0;
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
new file mode 100644
index 0000000..1c8e0c5
--- /dev/null
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyLocationTests.java
@@ -0,0 +1,293 @@
+package android.telephony.cts;
+
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.Manifest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.telephony.CellLocation;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
+import android.telephony.cts.locationaccessingapp.CtsLocationAccessService;
+import android.telephony.cts.locationaccessingapp.ICtsLocationAccessControl;
+import android.text.TextUtils;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+public class TelephonyLocationTests {
+    private static final String LOCATION_ACCESS_APP_CURRENT_PACKAGE =
+            CtsLocationAccessService.class.getPackage().getName();
+
+    private static final String LOCATION_ACCESS_APP_SDK28_PACKAGE =
+            CtsLocationAccessService.class.getPackage().getName() + ".sdk28";
+
+    private static final long TEST_TIMEOUT = 5000;
+
+    private boolean mShouldTest = false;
+
+    @Before
+    public void setUp() {
+        PackageManager pm = InstrumentationRegistry.getContext().getPackageManager();
+        mShouldTest = pm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
+    }
+
+    @Test
+    public void testCellLocationFinePermission() {
+        if (!mShouldTest) return;
+        Runnable cellLocationAccess = () -> {
+            try {
+                Bundle cellLocationBundle = (Bundle) performLocationAccessCommand(
+                        CtsLocationAccessService.COMMAND_GET_CELL_LOCATION);
+                CellLocation cellLocation = cellLocationBundle == null ? null :
+                        CellLocation.newFromBundle(cellLocationBundle);
+                assertTrue(cellLocation == null || cellLocation.isEmpty());
+            } catch (SecurityException e) {
+                // expected
+            }
+
+            try {
+                List cis = (List) performLocationAccessCommand(
+                        CtsLocationAccessService.COMMAND_GET_CELL_INFO);
+                assertTrue(cis == null || cis.isEmpty());
+            } catch (SecurityException e) {
+                // expected
+            }
+        };
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE,
+                cellLocationAccess, Manifest.permission.ACCESS_FINE_LOCATION);
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, cellLocationAccess,
+                Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+    }
+
+    @Test
+    public void testServiceStateLocationSanitization() {
+        if (!mShouldTest) return;
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    ServiceState ss = (ServiceState) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_GET_SERVICE_STATE);
+                    assertServiceStateSanitization(ss, true);
+
+                    withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                                ServiceState ss1 = (ServiceState) performLocationAccessCommand(
+                                        CtsLocationAccessService.COMMAND_GET_SERVICE_STATE);
+                                assertServiceStateSanitization(ss1, false);
+                            },
+                            Manifest.permission.ACCESS_COARSE_LOCATION);
+                },
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    ServiceState ss1 = (ServiceState) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_GET_SERVICE_STATE);
+                    assertServiceStateSanitization(ss1, false);
+                },
+                Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+    }
+
+    @Test
+    public void testServiceStateListeningWithoutPermissions() {
+        if (!mShouldTest) return;
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    ServiceState ss = (ServiceState) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+                    assertServiceStateSanitization(ss, true);
+
+                    withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                                ServiceState ss1 = (ServiceState) performLocationAccessCommand(
+                                        CtsLocationAccessService
+                                                .COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+                                assertServiceStateSanitization(ss1, false);
+                            },
+                            Manifest.permission.ACCESS_COARSE_LOCATION);
+                },
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    ServiceState ss1 = (ServiceState) performLocationAccessCommand(
+                            CtsLocationAccessService
+                                    .COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
+                    assertServiceStateSanitization(ss1, false);
+                },
+                Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+    }
+
+    @Test
+    public void testRegistryPermissionsForCellLocation() {
+        if (!mShouldTest) return;
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_LISTEN_CELL_LOCATION);
+                    assertNull(cellLocation);
+                },
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_LISTEN_CELL_LOCATION);
+                    assertNull(cellLocation);
+                },
+                Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+    }
+
+    @Test
+    public void testRegistryPermissionsForCellInfo() {
+        if (!mShouldTest) return;
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_LISTEN_CELL_INFO);
+                    assertNull(cellLocation);
+                },
+                Manifest.permission.ACCESS_FINE_LOCATION);
+
+        withRevokedPermission(LOCATION_ACCESS_APP_CURRENT_PACKAGE, () -> {
+                    CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
+                            CtsLocationAccessService.COMMAND_LISTEN_CELL_INFO);
+                    assertNull(cellLocation);
+                },
+                Manifest.permission.ACCESS_BACKGROUND_LOCATION);
+    }
+
+    @Test
+    public void testSdk28CellLocation() {
+        if (!mShouldTest) return;
+
+        // Verify that a target-sdk 28 app can access cell location with ACCESS_COARSE_LOCATION, but
+        // not with no location permissions at all.
+        withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+            try {
+                performLocationAccessCommandSdk28(
+                        CtsLocationAccessService.COMMAND_GET_CELL_LOCATION);
+            } catch (SecurityException e) {
+                fail("SDK28 should have access to cell location with coarse permission");
+            }
+
+            withRevokedPermission(LOCATION_ACCESS_APP_SDK28_PACKAGE, () -> {
+                try {
+                    Bundle cellLocationBundle = (Bundle) performLocationAccessCommandSdk28(
+                            CtsLocationAccessService.COMMAND_GET_CELL_LOCATION);
+                    CellLocation cellLocation = cellLocationBundle == null ? null :
+                            CellLocation.newFromBundle(cellLocationBundle);
+                    assertTrue(cellLocation == null || cellLocation.isEmpty());
+                } catch (SecurityException e) {
+                    // expected
+                }
+            }, Manifest.permission.ACCESS_COARSE_LOCATION);
+        }, Manifest.permission.ACCESS_FINE_LOCATION);
+
+    }
+    private ICtsLocationAccessControl getLocationAccessAppControl() {
+        Intent bindIntent = new Intent(CtsLocationAccessService.CONTROL_ACTION);
+        bindIntent.setComponent(new ComponentName(
+                LOCATION_ACCESS_APP_CURRENT_PACKAGE,
+                CtsLocationAccessService.class.getName()));
+
+        return bindLocationAccessControl(bindIntent);
+    }
+
+    private ICtsLocationAccessControl getLocationAccessAppControlSdk28() {
+        Intent bindIntent = new Intent(CtsLocationAccessService.CONTROL_ACTION);
+        bindIntent.setComponent(new ComponentName(
+                LOCATION_ACCESS_APP_SDK28_PACKAGE,
+                CtsLocationAccessService.class.getName()));
+
+        return bindLocationAccessControl(bindIntent);
+    }
+
+    private ICtsLocationAccessControl bindLocationAccessControl(Intent bindIntent) {
+        LinkedBlockingQueue<ICtsLocationAccessControl> pipe =
+                new LinkedBlockingQueue<>();
+        InstrumentationRegistry.getContext().bindService(bindIntent, new ServiceConnection() {
+            @Override
+            public void onServiceConnected(ComponentName name, IBinder service) {
+                pipe.offer(ICtsLocationAccessControl.Stub.asInterface(service));
+            }
+
+            @Override
+            public void onServiceDisconnected(ComponentName name) {
+
+            }
+        }, Context.BIND_AUTO_CREATE);
+
+        try {
+            return pipe.poll(TEST_TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            fail("interrupted");
+        }
+        fail("Unable to connect to location access test app");
+        return null;
+    }
+
+    private Object performLocationAccessCommand(String command) {
+        int tries = 0;
+        while (tries < 5) {
+            ICtsLocationAccessControl control = getLocationAccessAppControl();
+            try {
+                List ret = control.performCommand(command);
+                if (!ret.isEmpty()) return ret.get(0);
+            } catch (RemoteException e) {
+                tries++;
+            }
+        }
+        fail("Too many remote exceptions");
+        return null;
+    }
+
+    private Object performLocationAccessCommandSdk28(String command) {
+        ICtsLocationAccessControl control = getLocationAccessAppControlSdk28();
+        try {
+            List ret = control.performCommand(command);
+            if (!ret.isEmpty()) return ret.get(0);
+        } catch (RemoteException e) {
+            fail("Remote exception");
+        }
+        return null;
+    }
+
+    private void withRevokedPermission(String packageName, Runnable r, String permission) {
+        InstrumentationRegistry.getInstrumentation()
+                .getUiAutomation().revokeRuntimePermission(packageName, permission);
+        try {
+            r.run();
+        } finally {
+            InstrumentationRegistry.getInstrumentation()
+                    .getUiAutomation().grantRuntimePermission(packageName, permission);
+        }
+    }
+
+    private void assertServiceStateSanitization(ServiceState state, boolean sanitizedForFineOnly) {
+        if (state == null) return;
+
+        if (state.getNetworkRegistrationInfoList() != null) {
+            for (NetworkRegistrationInfo nrs : state.getNetworkRegistrationInfoList()) {
+                assertNull(nrs.getCellIdentity());
+            }
+        }
+
+        if (sanitizedForFineOnly) return;
+
+        assertTrue(TextUtils.isEmpty(state.getOperatorAlphaLong()));
+        assertTrue(TextUtils.isEmpty(state.getOperatorAlphaShort()));
+        assertTrue(TextUtils.isEmpty(state.getOperatorNumeric()));
+    }
+
+}
diff --git a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
index acf5ec7..03b2e8d 100644
--- a/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/cts/TelephonyManagerTest.java
@@ -25,7 +25,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.Manifest;
 import android.Manifest.permission;
 import android.app.UiAutomation;
 import android.bluetooth.BluetoothAdapter;
@@ -34,7 +33,6 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
@@ -45,11 +43,9 @@
 import android.os.AsyncTask;
 import android.os.Build;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserManager;
 import android.provider.Settings;
 import android.telecom.PhoneAccount;
@@ -72,8 +68,6 @@
 import android.telephony.TelephonyManager;
 import android.telephony.UiccCardInfo;
 import android.telephony.UiccSlotInfo;
-import android.telephony.cts.locationaccessingapp.CtsLocationAccessService;
-import android.telephony.cts.locationaccessingapp.ICtsLocationAccessControl;
 import android.telephony.data.ApnSetting;
 import android.telephony.emergency.EmergencyNumber;
 import android.text.TextUtils;
@@ -678,152 +672,6 @@
      */
 
     @Test
-    public void testCellLocationFinePermission() {
-        withRevokedPermission(() -> {
-            try {
-                CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
-                        CtsLocationAccessService.COMMAND_GET_CELL_LOCATION);
-                assertTrue(cellLocation == null || cellLocation.isEmpty());
-            } catch (SecurityException e) {
-                // expected
-            }
-
-            try {
-                List cis = (List) performLocationAccessCommand(
-                        CtsLocationAccessService.COMMAND_GET_CELL_INFO);
-                assertTrue(cis == null || cis.isEmpty());
-            } catch (SecurityException e) {
-                // expected
-            }
-        }, Manifest.permission.ACCESS_FINE_LOCATION);
-    }
-
-    @Test
-    public void testServiceStateLocationSanitization() {
-        withRevokedPermission(() -> {
-                    ServiceState ss = (ServiceState) performLocationAccessCommand(
-                            CtsLocationAccessService.COMMAND_GET_SERVICE_STATE);
-                    assertServiceStateSanitization(ss, true);
-
-                    withRevokedPermission(() -> {
-                                ServiceState ss1 = (ServiceState) performLocationAccessCommand(
-                                        CtsLocationAccessService.COMMAND_GET_SERVICE_STATE);
-                                assertServiceStateSanitization(ss1, false);
-                            },
-                            Manifest.permission.ACCESS_COARSE_LOCATION);
-                },
-                Manifest.permission.ACCESS_FINE_LOCATION);
-    }
-
-    @Test
-    public void testServiceStateListeningWithoutPermissions() {
-        if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) return;
-
-        withRevokedPermission(() -> {
-                    ServiceState ss = (ServiceState) performLocationAccessCommand(
-                            CtsLocationAccessService.COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
-                    assertServiceStateSanitization(ss, true);
-
-                    withRevokedPermission(() -> {
-                                ServiceState ss1 = (ServiceState) performLocationAccessCommand(
-                                        CtsLocationAccessService
-                                                .COMMAND_GET_SERVICE_STATE_FROM_LISTENER);
-                                assertServiceStateSanitization(ss1, false);
-                            },
-                            Manifest.permission.ACCESS_COARSE_LOCATION);
-                },
-                Manifest.permission.ACCESS_FINE_LOCATION);
-    }
-
-    @Test
-    public void testRegistryPermissionsForCellLocation() {
-        withRevokedPermission(() -> {
-                    CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
-                            CtsLocationAccessService.COMMAND_LISTEN_CELL_LOCATION);
-                    assertNull(cellLocation);
-                },
-                Manifest.permission.ACCESS_FINE_LOCATION);
-    }
-
-    @Test
-    public void testRegistryPermissionsForCellInfo() {
-        withRevokedPermission(() -> {
-                    CellLocation cellLocation = (CellLocation) performLocationAccessCommand(
-                            CtsLocationAccessService.COMMAND_LISTEN_CELL_INFO);
-                    assertNull(cellLocation);
-                },
-                Manifest.permission.ACCESS_FINE_LOCATION);
-    }
-
-    private ICtsLocationAccessControl getLocationAccessAppControl() {
-        Intent bindIntent = new Intent(CtsLocationAccessService.CONTROL_ACTION);
-        bindIntent.setComponent(new ComponentName(CtsLocationAccessService.class.getPackageName$(),
-                CtsLocationAccessService.class.getName()));
-
-        LinkedBlockingQueue<ICtsLocationAccessControl> pipe =
-                new LinkedBlockingQueue<>();
-        getContext().bindService(bindIntent, new ServiceConnection() {
-            @Override
-            public void onServiceConnected(ComponentName name, IBinder service) {
-                pipe.offer(ICtsLocationAccessControl.Stub.asInterface(service));
-            }
-
-            @Override
-            public void onServiceDisconnected(ComponentName name) {
-
-            }
-        }, Context.BIND_AUTO_CREATE);
-
-        try {
-            return pipe.poll(TOLERANCE, TimeUnit.MILLISECONDS);
-        } catch (InterruptedException e) {
-            fail("interrupted");
-        }
-        fail("Unable to connect to location access test app");
-        return null;
-    }
-
-    private Object performLocationAccessCommand(String command) {
-        ICtsLocationAccessControl control = getLocationAccessAppControl();
-        try {
-            List ret = control.performCommand(command);
-            if (!ret.isEmpty()) return ret.get(0);
-        } catch (RemoteException e) {
-            fail("Remote exception");
-        }
-        return null;
-    }
-
-    private void withRevokedPermission(Runnable r, String permission) {
-        InstrumentationRegistry.getInstrumentation()
-                .getUiAutomation().revokeRuntimePermission(
-                CtsLocationAccessService.class.getPackageName$(), permission);
-        try {
-            r.run();
-        } finally {
-            InstrumentationRegistry.getInstrumentation()
-                    .getUiAutomation().grantRuntimePermission(
-                    CtsLocationAccessService.class.getPackageName$(), permission);
-        }
-    }
-
-    private void assertServiceStateSanitization(ServiceState state, boolean sanitizedForFineOnly) {
-        if (state == null) return;
-
-        if (state.getNetworkRegistrationInfoList() != null) {
-            for (NetworkRegistrationInfo nrs : state.getNetworkRegistrationInfoList()) {
-                assertNull(nrs.getCellIdentity());
-            }
-        }
-
-        if (sanitizedForFineOnly) return;
-
-        assertTrue(TextUtils.isEmpty(state.getOperatorAlphaLong()));
-        assertTrue(TextUtils.isEmpty(state.getOperatorAlphaShort()));
-        assertTrue(TextUtils.isEmpty(state.getOperatorNumeric()));
-    }
-
-    @Test
     public void testGetRadioHalVersion() {
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             Log.d(TAG,"skipping test on device without FEATURE_TELEPHONY present");
@@ -2262,20 +2110,21 @@
         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
             return;
         }
-
-        boolean rebootRequired = ShellIdentityUtils.invokeMethodWithShellPermissions(
-                mTelephonyManager, (tm) -> tm.doesSwitchMultiSimConfigTriggerReboot());
-
-        // It's hard to test if reboot is needed.
-        if (!rebootRequired) {
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                    (tm) -> tm.switchMultiSimConfig(1));
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                    (tm) -> tm.switchMultiSimConfig(2));
-        } else {
+        try {
+            mTelephonyManager.switchMultiSimConfig(mTelephonyManager.getActiveModemCount());
+            fail("TelephonyManager#switchMultiSimConfig should require the MODIFY_PHONE_STATE"
+                    + " permission to access.");
+        } catch (SecurityException e) {
+            // expected
+        }
+        try {
             // This should result in no-op.
-            ShellIdentityUtils.invokeMethodWithShellPermissionsNoReturn(mTelephonyManager,
-                    (tm) -> tm.switchMultiSimConfig(mTelephonyManager.getPhoneCount()));
+            ShellIdentityUtils.invokeThrowableMethodWithShellPermissionsNoReturn(mTelephonyManager,
+                    (tm) -> tm.switchMultiSimConfig(mTelephonyManager.getActiveModemCount()),
+                    SecurityException.class, "android.permission.MODIFY_PHONE_STATE");
+        } catch (SecurityException e) {
+            fail("TelephonyManager#switchMultiSimConfig should require MODIFY_PHONE_STATE"
+                    + "permission to access.");
         }
     }
 
diff --git a/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
index d6fd098..fe705aa 100644
--- a/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/embms/cts/MbmsDownloadSessionTest.java
@@ -93,7 +93,7 @@
     @Test
     public void testAddServiceAnnouncementFile() throws Exception {
         byte[] sampleAnnouncementFile = "<xml></xml>".getBytes();
-        mDownloadSession.addServiceAnnouncementFile(sampleAnnouncementFile);
+        mDownloadSession.addServiceAnnouncement(sampleAnnouncementFile);
         List<Bundle> addServiceAnnouncementCalls =
                 getMiddlewareCalls(CtsDownloadService.METHOD_ADD_SERVICE_ANNOUNCEMENT);
         assertEquals(1, addServiceAnnouncementCalls.size());
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
index c665116..8255cf4 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsServiceTest.java
@@ -196,6 +196,20 @@
         if (tm.getSimState(sTestSlot) != TelephonyManager.SIM_STATE_READY) {
             fail("This test requires that there is a SIM in the device!");
         }
+        // Sanity check: ensure that the subscription hasn't changed between tests.
+        int[] subs = SubscriptionManager.getSubId(sTestSlot);
+
+        if (subs == null) {
+            fail("This test requires there is an active subscription in slot " + sTestSlot);
+        }
+        boolean isFound = false;
+        for (int sub : subs) {
+            isFound |= (sTestSub == sub);
+        }
+        if (!isFound) {
+            fail("Invalid state found: the test subscription in slot " + sTestSlot + " changed "
+                    + "during this test.");
+        }
     }
 
     @After
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
index 8c904ee..50ae5b7 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/ImsUtils.java
@@ -54,22 +54,34 @@
 
     public static int getPreferredActiveSubId() {
         Context context = InstrumentationRegistry.getInstrumentation().getContext();
-        int defaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
-        if (defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return defaultSubId;
-        }
-        // Couldn't resolve a default. We can try to resolve a default using the active
-        // subscriptions.
         SubscriptionManager sm = (SubscriptionManager) context.getSystemService(
                 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
         List<SubscriptionInfo> infos = ShellIdentityUtils.invokeMethodWithShellPermissions(sm,
                 SubscriptionManager::getActiveSubscriptionInfoList);
+
+        int defaultSubId = SubscriptionManager.getDefaultVoiceSubscriptionId();
+        if (defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                && isSubIdInInfoList(infos, defaultSubId)) {
+            return defaultSubId;
+        }
+
+        defaultSubId = SubscriptionManager.getDefaultSubscriptionId();
+        if (defaultSubId != SubscriptionManager.INVALID_SUBSCRIPTION_ID
+                && isSubIdInInfoList(infos, defaultSubId)) {
+            return defaultSubId;
+        }
+
+        // Couldn't resolve a default. We can try to resolve a default using the active
+        // subscriptions.
         if (!infos.isEmpty()) {
             return infos.get(0).getSubscriptionId();
         }
-        // The best we can do is fall back to any default set. If it fails, notify the tester
-        // that there must be a default set.
-        return SubscriptionManager.getDefaultSubscriptionId();
+        // There must be at least one active subscription.
+        return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+    }
+
+    private static boolean isSubIdInInfoList(List<SubscriptionInfo> infos, int subId) {
+        return infos.stream().anyMatch(info -> info.getSubscriptionId() == subId);
     }
 
     /**
diff --git a/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java b/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
index f7160dd..5e2f627 100644
--- a/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
+++ b/tests/tests/tethering/src/android/tethering/cts/TetheringManagerTest.java
@@ -57,8 +57,11 @@
 import android.net.TetheringManager.TetheringRequest;
 import android.net.cts.util.CtsNetUtils;
 import android.net.cts.util.CtsNetUtils.TestNetworkCallback;
+import android.net.wifi.WifiClient;
 import android.net.wifi.WifiManager;
+import android.net.wifi.WifiManager.SoftApCallback;
 import android.os.Bundle;
+import android.os.ConditionVariable;
 import android.os.PersistableBundle;
 import android.os.ResultReceiver;
 import android.telephony.CarrierConfigManager;
@@ -135,6 +138,40 @@
         dropShellPermissionIdentity();
     }
 
+    private static class StopSoftApCallback implements SoftApCallback {
+        private final ConditionVariable mWaiting = new ConditionVariable();
+        @Override
+        public void onStateChanged(int state, int failureReason) {
+            if (state == WifiManager.WIFI_AP_STATE_DISABLED) mWaiting.open();
+        }
+
+        @Override
+        public void onConnectedClientsChanged(List<WifiClient> clients) { }
+
+        public void waitForSoftApStopped() {
+            if (!mWaiting.block(DEFAULT_TIMEOUT_MS)) {
+                fail("stopSoftAp Timeout");
+            }
+        }
+    }
+
+    // Wait for softAp to be disabled. This is necessary on devices where stopping softAp
+    // deletes the interface. On these devices, tethering immediately stops when the softAp
+    // interface is removed, but softAp is not yet fully disabled. Wait for softAp to be
+    // fully disabled, because otherwise the next test might fail because it attempts to
+    // start softAp before it's fully stopped.
+    private void expectSoftApDisabled() {
+        final StopSoftApCallback callback = new StopSoftApCallback();
+        try {
+            mWm.registerSoftApCallback(c -> c.run(), callback);
+            // registerSoftApCallback will immediately call the callback with the current state, so
+            // this callback will fire even if softAp is already disabled.
+            callback.waitForSoftApStopped();
+        } finally {
+            mWm.unregisterSoftApCallback(callback);
+        }
+    }
+
     private class TetherChangeReceiver extends BroadcastReceiver {
         private class TetherState {
             final ArrayList<String> mAvailable;
@@ -294,6 +331,7 @@
         mTetherChangeReceiver.expectTethering(true /* active */, wifiRegexs);
 
         mTM.stopTethering(TETHERING_WIFI);
+        expectSoftApDisabled();
         mTetherChangeReceiver.expectTethering(false /* active */, wifiRegexs);
     }
 
@@ -544,6 +582,7 @@
 
     private void stopWifiTethering(final TestTetheringEventCallback callback) {
         mTM.stopTethering(TETHERING_WIFI);
+        expectSoftApDisabled();
         callback.expectTetheredInterfacesChanged(null);
         callback.expectOneOfOffloadStatusChanged(TETHER_HARDWARE_OFFLOAD_STOPPED);
     }
diff --git a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
index e134bf5..5e29eea 100755
--- a/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
+++ b/tests/tests/webkit/src/android/webkit/cts/WebViewTest.java
@@ -1698,7 +1698,7 @@
         final int previousScrollX = mOnUiThread.getScrollX();
         final int previousScrollY = mOnUiThread.getScrollY();
 
-        mOnUiThread.flingScroll(100, 100);
+        mOnUiThread.flingScroll(10000, 10000);
 
         new PollingCheck() {
             @Override
diff --git a/tests/tests/widget/src/android/widget/cts/TextViewTest.java b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
index 01d5cd8..35db2c9 100644
--- a/tests/tests/widget/src/android/widget/cts/TextViewTest.java
+++ b/tests/tests/widget/src/android/widget/cts/TextViewTest.java
@@ -8485,6 +8485,8 @@
     private void initializeTextForSmartSelection(CharSequence text) throws Throwable {
         assertTrue(text.length() >= SMARTSELECT_END);
         mActivityRule.runOnUiThread(() -> {
+            // Support small devices. b/155842369
+            mTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 20);
             mTextView.setTextIsSelectable(true);
             mTextView.setText(text);
             mTextView.setTextClassifier(FAKE_TEXT_CLASSIFIER);